citadel

My dotfiles, scripts and nix configs
git clone git://jb55.com/citadel
Log | Files | Refs | README | LICENSE

default.nix (17123B)


      1 extra:
      2 { config, lib, pkgs, ... }:
      3 let
      4   chromecastIP = "192.168.87.190";
      5   iptables = "iptables -A nixos-fw";
      6   ipr = "${pkgs.iproute2}/bin/ip";
      7   hasVPN = false;
      8   writeBash = extra.util.writeBash;
      9   transmission-dir = "/zbig/torrents";
     10   download-dir = "${transmission-dir}/Downloads";
     11   openCloseTCP = op: dev: port: ''
     12     ip46tables -${op} nixos-fw -i ${dev} -p tcp --dport ${toString port} -j nixos-fw-accept ${if op == "D" then "|| true" else ""}
     13   '';
     14   openTCP = dev: port: openCloseTCP "A" dev port;
     15   closeTCP = dev: port: openCloseTCP "D" dev port;
     16   vpn = {
     17     name = "pia";
     18     table = "300";
     19     credfile = pkgs.writeText "vpncreds" ''
     20       ${extra.private.vpncred.user}
     21       ${extra.private.vpncred.pass}
     22     '';
     23     routeup = writeBash "openvpn-pia-routeup" ''
     24       ${ipr} route add default via $route_vpn_gateway dev $dev metric 1 table ${vpn.table}
     25       exit 0
     26     '';
     27 #    up = writeBash "openvpn-pia-preup" config.services.openvpn.servers.pia.up;
     28 #    down = writeBash "openvpn-pia-stop" config.services.openvpn.servers.pia.down;
     29   };
     30 
     31   ports = {
     32     lightning = 9735;
     33     lightningt = 9736;
     34     lightning_websocket = 8324;
     35     lntun = 7878;
     36     dns = 53;
     37     http = 80;
     38     ssh = 22;
     39     wireguard = 51820;
     40     weechat = 9000;
     41     webdev = 8080;
     42     testdamuspush = 8766;
     43     nncp = 5442;
     44     starbound = 21025;
     45     terraria = 7777;
     46     ollama = 11434;
     47     bg3 = 23253;
     48     inherit (extra.private) notify-port;
     49   };
     50 
     51   firewallRules = (with ports; [
     52     "nixos-fw -s 10.100.0.0/24,${extra.machine.subnet} -p tcp --dport ${toString webdev} -j nixos-fw-accept" # dev
     53     "nixos-fw -s 10.100.0.0/24,${extra.machine.subnet} -p tcp --dport ${toString testdamuspush} -j nixos-fw-accept" # damus push notification test server
     54     "nixos-fw -s 10.100.0.0/24,${extra.machine.subnet} -p tcp --dport ${toString nncp} -j nixos-fw-accept"
     55     "nixos-fw -s 10.100.0.0/24,${extra.machine.subnet} -p tcp --dport ${toString terraria} -j nixos-fw-accept"
     56     "nixos-fw -s 10.100.0.0/24,${extra.machine.subnet} -p tcp --dport ${toString ollama} -j nixos-fw-accept"
     57     "nixos-fw -s 192.168.86.1/24 -p udp --dport ${toString wireguard} -j nixos-fw-accept"
     58     "nixos-fw -s 192.168.86.1/24 -p tcp --dport ${toString bg3} -j nixos-fw-accept"
     59     "nixos-fw -s 192.168.86.1/24 -p udp --dport ${toString bg3} -j nixos-fw-accept"
     60     "nixos-fw -s 10.100.0.0/24 -p tcp --dport 80 -j nixos-fw-accept"
     61     "nixos-fw -s 10.100.0.0/24 -p tcp --dport 3000 -j nixos-fw-accept"
     62     "nixos-fw -s 10.100.0.0/24 -p tcp --dport 25565 -j nixos-fw-accept"
     63     "nixos-fw -s 10.100.0.0/24 -p tcp --dport 25575 -j nixos-fw-accept"
     64     "nixos-fw -s 10.100.0.2/32 -p tcp --dport ${toString lntun} -j nixos-fw-accept"
     65     "nixos-fw -s 10.100.0.0/24 -p tcp --dport ${toString weechat} -j nixos-fw-accept"
     66     "nixos-fw -s 10.100.0.0/24,${extra.machine.subnet} -p tcp --dport 8333 -j nixos-fw-accept" # bitcoin
     67     "nixos-fw -s 10.100.0.0/24,${extra.machine.subnet} -p tcp --dport 8332 -j nixos-fw-accept" # bitcoin-rpc
     68     "nixos-fw -s 192.168.122.218 -p udp --dport 137 -j nixos-fw-accept"
     69     "nixos-fw -s 192.168.122.218 -p udp --dport 138 -j nixos-fw-accept"
     70     "nixos-fw -s 192.168.122.218 -p tcp --dport 139 -j nixos-fw-accept"
     71     "nixos-fw -s 192.168.122.218 -p tcp --dport 445 -j nixos-fw-accept"
     72     "OUTPUT -t mangle   -m cgroup --cgroup 11 -j MARK --set-mark 11"
     73     "POSTROUTING -t nat -m cgroup --cgroup 11 -o tun0 -j MASQUERADE"
     74   ]);
     75 
     76   addRule = rule: "iptables -A ${rule}";
     77   rmRule = rule: "iptables -D ${rule} || true";
     78   extraCommands = lib.concatStringsSep "\n" (map addRule firewallRules);
     79   extraStopCommands = lib.concatStringsSep "\n" (map rmRule firewallRules);
     80 in
     81 {
     82   networking.hostId = extra.machine.hostId;
     83 
     84   #networking.firewall.trustedInterfaces = ["wg0"];
     85   networking.firewall.allowedTCPPorts = with ports; [ lightning lightning_websocket http ];
     86   networking.firewall.allowedUDPPorts = with ports; [ dns wireguard ];
     87 
     88   networking.nat.enable = true;
     89   networking.nat.externalInterface = "eth0";
     90   networking.nat.internalInterfaces = [ "wg0" ];
     91 
     92   networking.wireguard.interfaces = {
     93     # "wg0" is the network interface name. You can name the interface arbitrarily.
     94     wg0 = {
     95       # Determines the IP address and subnet of the server's end of the tunnel interface.
     96       ips = [ "10.100.0.1/24" ];
     97 
     98       listenPort = ports.wireguard;
     99 
    100       postSetup = ''
    101         ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s 10.100.0.0/24 -o enp30s0 -j MASQUERADE
    102       '';
    103 
    104       postShutdown = ''
    105         ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s 10.100.0.0/24 -o enp30s0 -j MASQUERADE
    106       '';
    107 
    108       privateKeyFile = "/home/jb55/.wg/private";
    109 
    110       peers = [
    111         { publicKey = "wcoun9+1GX4awQF2Yd0WbsQ6RKHE9SsOsYv3qR7mbB0="; # quiver
    112           allowedIPs = [ "10.100.0.2/32" ];
    113         }
    114         { publicKey = "vIh3IQgP92OhHaC9XBiJVDLlrs3GVcR6hlXaapjTiA0="; # phone
    115           allowedIPs = [ "10.100.0.3/32" ];
    116         }
    117         #{ publicKey = "Dp8Df75X8Kh9gd33e+CWyyhOvT4mT0X9ToPwBUEBU1k="; # macos
    118         #  allowedIPs = [ "10.100.0.4/32" ];
    119         #}
    120         #{ publicKey = "N4bIpjNL/IzV59y5KWHiR54n0rAKYcr3/BkVLzCmBBA="; # old-mac
    121         #  allowedIPs = [ "10.100.0.5/32" ];
    122         #}
    123         #{ publicKey = "Ynuism5cSJYUrMF/gWZti8W+PztLufaB/3mQlXV6HyY="; # vanessa-phone
    124         #  allowedIPs = [ "10.100.0.6/32" ];
    125         #} 
    126         { publicKey = "BklL4dTL8WK3xnmM899Hr50/UlXaLYhJQWllj2p4ZEg="; # charon
    127           allowedIPs = [ "10.100.0.7/32" ];
    128           endpoint = "45.79.91.128:51820";
    129         }
    130         { publicKey = "fj35gCObJ+uP/8tDpYsAD+b2XuSpa82umL/8LscIHwQ="; # pixel
    131           allowedIPs = [ "10.100.0.9/32" ];
    132         }
    133         { publicKey = "oYTNuXPl5GQsz53cL55MO9MfI61DyZBrBDy9ZFBpDWU="; # cross (air)
    134           allowedIPs = [ "10.100.0.8/32" ];
    135         } 
    136         { publicKey = "kBTRfnUGBwbTlyazK1J67VVpzNg/wLjgmSfI9+1J6S4="; # ipad-air
    137           allowedIPs = [ "10.100.0.12/32" ];
    138         } 
    139         { publicKey = "fj35gCObJ+uP/8tDpYsAD+b2XuSpa82umL/8LscIHwQ="; # pixel6-android
    140           allowedIPs = [ "10.100.0.9/32" ];
    141         }
    142       ];
    143     };
    144 
    145     rcx0 = {
    146      # Determines the IP address and subnet of the server's end of the tunnel interface.
    147      ips = [ "10.200.0.2/32" ];
    148 
    149      privateKeyFile = "/home/jb55/.wg/rcx/private";
    150 
    151      peers = [
    152        { publicKey = "wC+mEE9/PJDuIfr7DFZWnM8HbQz5fSOFHmmzQRxULzM="; # server
    153          allowedIPs = [ "10.200.0.1/32" ];
    154          endpoint = "159.89.143.225:53";
    155          persistentKeepalive = 25;
    156        }
    157        { publicKey = "vrKDdLPXAXAPP7XuuQl/dsD+z3dV/Z0uhgc+yjJ4Nys="; # winvm
    158          allowedIPs = [ "10.200.0.3/32" ];
    159          endpoint = "192.168.122.218:51820";
    160          persistentKeepalive = 25;
    161        }
    162      ];
    163     };
    164   };
    165 
    166 
    167   services.transmission = {
    168     enable = true;
    169     home = transmission-dir;
    170     settings = {
    171       incomplete-dir-enable = true;
    172       rpc-whitelist = "127.0.0.1";
    173     };
    174 
    175     port = 14325;
    176   };
    177 
    178   services.jellyfin.enable = false;
    179 
    180   services.plex = {
    181     enable = false;
    182     group = "transmission";
    183     openFirewall = true;
    184   };
    185 
    186   #services.xinetd.enable = true;
    187   #services.xinetd.services =
    188   #[
    189   #  { name = "gopher";
    190   #    port = 70;
    191   #    server = "${pkgs.gophernicus}/bin/in.gophernicus";
    192   #    serverArgs = "-nf -r /var/gopher";
    193   #    extraConfig = ''
    194   #      disable = no
    195   #      env = PATH=${pkgs.coreutils}/bin:${pkgs.curl}/bin
    196   #      passenv = PATH
    197   #    '';
    198   #  }
    199   #];
    200 
    201   services.nginx.httpConfig = lib.mkIf config.services.transmission.enable ''
    202     server {
    203       listen 80;
    204       listen ${extra.machine.ztip}:80;
    205       listen 192.168.87.26;
    206 
    207       # server names for this server.
    208       # any requests that come in that match any these names will use the proxy.
    209       server_name plex.jb55.com plez.jb55.com media.home plex.home;
    210 
    211       location = / {
    212           return 302 http://plex.jb55.com/web/index.html;
    213       }
    214 
    215       # this is where everything cool happens (you probably don't need to change anything here):
    216       location / {
    217         # if a request to / comes in, 301 redirect to the main plex page.
    218         # but only if it doesn't contain the X-Plex-Device-Name header
    219         # this fixes a bug where you get permission issues when accessing the web dashboard
    220 
    221         if ($http_x_plex_device_name = \'\') {
    222           rewrite ^/$ http://$http_host/web/index.html;
    223         }
    224 
    225         # set some headers and proxy stuff.
    226         proxy_set_header X-Real-IP $remote_addr;
    227         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    228 				proxy_set_header X-Forwarded-Proto $scheme;
    229 				proxy_set_header Host $server_addr;
    230 				proxy_set_header Referer $server_addr;
    231 				proxy_set_header Origin $server_addr; 
    232 
    233         # plex headers
    234 				proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier;
    235 				proxy_set_header X-Plex-Device $http_x_plex_device;
    236 				proxy_set_header X-Plex-Device-Name $http_x_plex_device_name;
    237 				proxy_set_header X-Plex-Platform $http_x_plex_platform;
    238 				proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version;
    239 				proxy_set_header X-Plex-Product $http_x_plex_product;
    240 				proxy_set_header X-Plex-Token $http_x_plex_token;
    241 				proxy_set_header X-Plex-Version $http_x_plex_version;
    242 				proxy_set_header X-Plex-Nocache $http_x_plex_nocache;
    243 				proxy_set_header X-Plex-Provides $http_x_plex_provides;
    244 				proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor;
    245 				proxy_set_header X-Plex-Model $http_x_plex_model;
    246 
    247 				# Websockets
    248 				proxy_http_version 1.1;
    249 				proxy_set_header Upgrade $http_upgrade;
    250 				proxy_set_header Connection "upgrade";
    251 
    252 				# Buffering off send to the client as soon as the data is received from Plex.
    253 				proxy_redirect off;
    254 				proxy_buffering off;
    255 
    256 				client_max_body_size 100M;
    257 				send_timeout 100m;
    258 
    259         # include Host header
    260         proxy_set_header Host $host;
    261 
    262         # proxy request to plex server
    263         proxy_pass http://plex.jb55.com:32400/;
    264       }
    265     }
    266 
    267     server {
    268       listen 80;
    269       listen ${extra.machine.ztip}:80;
    270       listen 192.168.87.26;
    271       server_name torrents.jb55.com torrentz.jb55.com torrents.home torrent.home;
    272 
    273       location = /download {
    274         return 301 " /download/";
    275       }
    276 
    277       location /download/ {
    278         alias ${download-dir}/;
    279         autoindex on;
    280       }
    281 
    282       location / {
    283         proxy_read_timeout 300;
    284         proxy_pass_header  X-Transmission-Session-Id;
    285         proxy_set_header   X-Forwarded-Host   $host;
    286         proxy_set_header   X-Forwarded-Server $host;
    287         proxy_set_header   X-Forwarded-For    $proxy_add_x_forwarded_for;
    288         proxy_pass         http://127.0.0.1:${toString config.services.transmission.port}/transmission/web/;
    289       }
    290 
    291       location /rpc {
    292         proxy_pass         http://127.0.0.1:${toString config.services.transmission.port}/transmission/rpc;
    293       }
    294 
    295       location /upload {
    296         proxy_pass         http://127.0.0.1:${toString config.services.transmission.port}/transmission/upload;
    297       }
    298     }
    299   '';
    300 
    301   systemd.services.transmission.enable = hasVPN;
    302   systemd.services.transmission.requires = [ "openvpn-pia.service" ];
    303   systemd.services.transmission.after    = [ "openvpn-pia.service" ];
    304   systemd.services.transmission.serviceConfig.User = lib.mkForce "root";
    305   systemd.services.transmission.serviceConfig.ExecStart = lib.mkForce (
    306     writeBash "start-transmission-under-vpn" ''
    307       ${pkgs.libcgroup}/bin/cgexec --sticky -g net_cls:pia \
    308       ${pkgs.sudo}/bin/sudo -u transmission \
    309       ${pkgs.transmission}/bin/transmission-daemon \
    310         -f \
    311         --port ${toString config.services.transmission.port};
    312     ''
    313   );
    314 
    315   networking.firewall.extraCommands =
    316     # openvpn stuff, we only want to do this once
    317     (if hasVPN then ''
    318       # create separate routing table
    319       ${ipr} rule add fwmark 11 table ${vpn.table}
    320 
    321       # add fallback route that blocks traffic, should the VPN go down
    322       ${ipr} route add blackhole default metric 2 table ${vpn.table}
    323 
    324     '' else "") + extraCommands;
    325 
    326   networking.firewall.extraStopCommands =
    327     (if hasVPN then ''
    328         # remove separate routing table
    329         ${ipr} rule del fwmark 11 table ${vpn.table} || true
    330         ${ipr} route del blackhole default metric 2 table ${vpn.table} || true
    331 
    332     '' else "") + extraStopCommands;
    333 
    334   users.extraGroups.vpn-pia.members = [ "jb55" "transmission" ];
    335   users.extraGroups.tor.members = [ "jb55" ];
    336 
    337   systemd.services.openvpn-pia.path = [ pkgs.libcgroup ];
    338   services.openvpn.servers = if hasVPN then {
    339     pia = {
    340       autoStart = false;
    341 
    342       config = ''
    343         client
    344         dev tun
    345         proto udp
    346         remote 37.19.212.142 1194
    347         resolv-retry infinite
    348         remote-random
    349         nobind
    350         tun-mtu 1500
    351         tun-mtu-extra 32
    352         mssfix 1450
    353         persist-key
    354         persist-tun
    355         ping 15
    356         ping-restart 0
    357         ping-timer-rem
    358         reneg-sec 0
    359         comp-lzo no
    360         verify-x509-name CN=ca1515.nordvpn.com
    361 
    362         remote-cert-tls server
    363 
    364         auth-user-pass ${vpn.credfile}
    365         route-noexec
    366         route-up ${vpn.routeup}
    367 
    368         verb 3
    369         pull
    370         fast-io
    371         cipher AES-256-CBC
    372         auth SHA512
    373         <ca>
    374         -----BEGIN CERTIFICATE-----
    375         MIIFCjCCAvKgAwIBAgIBATANBgkqhkiG9w0BAQ0FADA5MQswCQYDVQQGEwJQQTEQ
    376         MA4GA1UEChMHTm9yZFZQTjEYMBYGA1UEAxMPTm9yZFZQTiBSb290IENBMB4XDTE2
    377         MDEwMTAwMDAwMFoXDTM1MTIzMTIzNTk1OVowOTELMAkGA1UEBhMCUEExEDAOBgNV
    378         BAoTB05vcmRWUE4xGDAWBgNVBAMTD05vcmRWUE4gUm9vdCBDQTCCAiIwDQYJKoZI
    379         hvcNAQEBBQADggIPADCCAgoCggIBAMkr/BYhyo0F2upsIMXwC6QvkZps3NN2/eQF
    380         kfQIS1gql0aejsKsEnmY0Kaon8uZCTXPsRH1gQNgg5D2gixdd1mJUvV3dE3y9FJr
    381         XMoDkXdCGBodvKJyU6lcfEVF6/UxHcbBguZK9UtRHS9eJYm3rpL/5huQMCppX7kU
    382         eQ8dpCwd3iKITqwd1ZudDqsWaU0vqzC2H55IyaZ/5/TnCk31Q1UP6BksbbuRcwOV
    383         skEDsm6YoWDnn/IIzGOYnFJRzQH5jTz3j1QBvRIuQuBuvUkfhx1FEwhwZigrcxXu
    384         MP+QgM54kezgziJUaZcOM2zF3lvrwMvXDMfNeIoJABv9ljw969xQ8czQCU5lMVmA
    385         37ltv5Ec9U5hZuwk/9QO1Z+d/r6Jx0mlurS8gnCAKJgwa3kyZw6e4FZ8mYL4vpRR
    386         hPdvRTWCMJkeB4yBHyhxUmTRgJHm6YR3D6hcFAc9cQcTEl/I60tMdz33G6m0O42s
    387         Qt/+AR3YCY/RusWVBJB/qNS94EtNtj8iaebCQW1jHAhvGmFILVR9lzD0EzWKHkvy
    388         WEjmUVRgCDd6Ne3eFRNS73gdv/C3l5boYySeu4exkEYVxVRn8DhCxs0MnkMHWFK6
    389         MyzXCCn+JnWFDYPfDKHvpff/kLDobtPBf+Lbch5wQy9quY27xaj0XwLyjOltpiST
    390         LWae/Q4vAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqG
    391         SIb3DQEBDQUAA4ICAQC9fUL2sZPxIN2mD32VeNySTgZlCEdVmlq471o/bDMP4B8g
    392         nQesFRtXY2ZCjs50Jm73B2LViL9qlREmI6vE5IC8IsRBJSV4ce1WYxyXro5rmVg/
    393         k6a10rlsbK/eg//GHoJxDdXDOokLUSnxt7gk3QKpX6eCdh67p0PuWm/7WUJQxH2S
    394         DxsT9vB/iZriTIEe/ILoOQF0Aqp7AgNCcLcLAmbxXQkXYCCSB35Vp06u+eTWjG0/
    395         pyS5V14stGtw+fA0DJp5ZJV4eqJ5LqxMlYvEZ/qKTEdoCeaXv2QEmN6dVqjDoTAo
    396         k0t5u4YRXzEVCfXAC3ocplNdtCA72wjFJcSbfif4BSC8bDACTXtnPC7nD0VndZLp
    397         +RiNLeiENhk0oTC+UVdSc+n2nJOzkCK0vYu0Ads4JGIB7g8IB3z2t9ICmsWrgnhd
    398         NdcOe15BincrGA8avQ1cWXsfIKEjbrnEuEk9b5jel6NfHtPKoHc9mDpRdNPISeVa
    399         wDBM1mJChneHt59Nh8Gah74+TM1jBsw4fhJPvoc7Atcg740JErb904mZfkIEmojC
    400         VPhBHVQ9LHBAdM8qFI2kRK0IynOmAZhexlP/aT/kpEsEPyaZQlnBn3An1CRz8h0S
    401         PApL8PytggYKeQmRhl499+6jLxcZ2IegLfqq41dzIjwHwTMplg+1pKIOVojpWA==
    402         -----END CERTIFICATE-----
    403         </ca>
    404         key-direction 1
    405         <tls-auth>
    406         #
    407         # 2048 bit OpenVPN static key
    408         #
    409         -----BEGIN OpenVPN Static key V1-----
    410         e685bdaf659a25a200e2b9e39e51ff03
    411         0fc72cf1ce07232bd8b2be5e6c670143
    412         f51e937e670eee09d4f2ea5a6e4e6996
    413         5db852c275351b86fc4ca892d78ae002
    414         d6f70d029bd79c4d1c26cf14e9588033
    415         cf639f8a74809f29f72b9d58f9b8f5fe
    416         fc7938eade40e9fed6cb92184abb2cc1
    417         0eb1a296df243b251df0643d53724cdb
    418         5a92a1d6cb817804c4a9319b57d53be5
    419         80815bcfcb2df55018cc83fc43bc7ff8
    420         2d51f9b88364776ee9d12fc85cc7ea5b
    421         9741c4f598c485316db066d52db4540e
    422         212e1518a9bd4828219e24b20d88f598
    423         a196c9de96012090e333519ae18d3509
    424         9427e7b372d348d352dc4c85e18cd4b9
    425         3f8a56ddb2e64eb67adfc9b337157ff4
    426         -----END OpenVPN Static key V1-----
    427         </tls-auth>
    428       '';
    429 
    430       up = ''
    431         # enable ip forwarding
    432         echo 1 > /proc/sys/net/ipv4/ip_forward
    433 
    434         # create cgroup for 3rd party VPN (can change 'vpn' to your name of choice)
    435         mkdir -p /sys/fs/cgroup/net_cls/${vpn.name}
    436 
    437         # give it an arbitrary id
    438         echo 11 > /sys/fs/cgroup/net_cls/${vpn.name}/net_cls.classid
    439 
    440         # grant a non-root user access
    441         cgcreate -t jb55:vpn-pia -a jb55:vpn-pia -g net_cls:${vpn.name}
    442 
    443         # disable reverse path filtering for all interfaces
    444         for i in /proc/sys/net/ipv4/conf\/*/rp_filter; do echo 0 > $i; done
    445       '';
    446 
    447       down = ''
    448         echo 0 > /proc/sys/net/ipv4/ip_forward
    449 
    450         cgdelete -g net_cls:${vpn.name}
    451 
    452         # not sure if cgdelete does this...
    453         rm -rf /sys/fs/cgroup/net_cls/${vpn.name}
    454       '';
    455     };
    456   } else {};
    457 
    458   networking.firewall.checkReversePath = false;
    459   networking.firewall.logReversePathDrops = true;
    460   networking.firewall.logRefusedConnections = false;
    461 }