citadel

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

default.nix (16340B)


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