office: simple-scan: install
[julm/julm-nix.git] / nixos / profiles / wireguard / wg-intra.nix
index 40ed4750e662298d61baa37c706bd810b6470319..ca4bcdf710e6fc8161ca6994038afc62b42686aa 100644 (file)
-{ pkgs, lib, config, hostName, credentials, ... }:
+{ inputs, lib, config, hostName, ... }:
 let
-  iface = "wg-intra";
+  wgIface = "wg-intra";
   peers = import wg-intra/peers.nix;
-  wg = config.networking.wireguard.interfaces.${iface};
+  wg = config.networking.wireguard.interfaces.${wgIface};
 in
 {
-# Each peer select the other peers allowed to connect to it
-options.networking.wireguard.${iface}.peers =
-  lib.genAttrs (lib.attrNames peers) (peerName: {
-    enable = lib.mkEnableOption "this peer";
-  });
-config = {
-systemd.services."wireguard-${iface}".serviceConfig.LoadCredentialEncrypted = "privateKey:${credentials}/wireguard/${iface}/privateKey.secret";
-networking.wireguard.interfaces.${iface} = lib.recursiveUpdate
-  (removeAttrs peers.${hostName} ["ipv4" "persistentKeepalive" "peer"])
-  {
-    peers =
-      lib.mapAttrsToList (peerName: peer:
-        lib.recursiveUpdate
-          {
-            persistentKeepalive =
-              peer.persistentKeepalive # Useful if this peer is behind a NAT
-              or peers.${hostName}.persistentKeepalive # Useful if this host is behind a NAT
-              or null;
-          }
-          peer.peer)
-        (removeAttrs
-          (lib.filterAttrs (peerName: _: config.networking.wireguard.${iface}.peers.${peerName}.enable) peers)
-          [hostName]);
-    privateKeyFile = "$CREDENTIALS_DIRECTORY/privateKey";
+  # Each peer select the other peers allowed to connect to it
+  options.networking.wireguard.${wgIface}.peers =
+    lib.genAttrs (lib.attrNames peers) (_peerName: {
+      enable = lib.mkEnableOption "this peer";
+    });
+  config = {
+    #systemd.services."wireguard-${wgIface}".serviceConfig.LoadCredentialEncrypted =
+    #  [ "privateKey:${inputs.self}/hosts/${hostName}/wireguard/${wgIface}/privateKey.cred" ];
+    networking.wireguard.interfaces.${wgIface} = lib.recursiveUpdate
+      (removeAttrs peers.${hostName} [ "ipv4" "persistentKeepalive" "peer" ])
+      {
+        peers =
+          lib.mapAttrsToList
+            (_peerName: peer:
+              lib.recursiveUpdate
+                {
+                  persistentKeepalive =
+                    peer.persistentKeepalive # Useful if this peer is behind a NAT
+                      or peers.${hostName}.persistentKeepalive # Useful if this host is behind a NAT
+                      or null;
+                }
+                peer.peer)
+            (removeAttrs
+              (lib.filterAttrs (peerName: _: config.networking.wireguard.${wgIface}.peers.${peerName}.enable) peers)
+              [ hostName ]);
+        privateKeyFile = "\$CREDENTIALS_DIRECTORY/privateKey";
 
-    # Set the MTU to a minimum
-    # (IPv4 requires at least 68 but it's 1280 for IPv6).
-    # This prevents connections to stall on huge packets,
-    # or delaying their initializing due to TCP PMTU probing.
-    postSetup = ''
-      ip link set dev ${iface} mtu 1280
-    '';
-  };
-networking.hosts = lib.mkMerge [
-  (lib.mapAttrs' (hostName: host:
-    lib.nameValuePair host.ipv4 [ "${hostName}.wg" ]) peers)
-  {
-    "${peers.losurdo.ipv4}" = [
-      "nix-extracache.losurdo.wg"
-      "nix-localcache.losurdo.wg"
-      "sftp.losurdo.wg"
+        # Set the MTU to a minimum
+        # (IPv4 requires at least 68 but it's 1280 for IPv6).
+        # This prevents connections to stall on huge packets,
+        # or delaying their initializing due to TCP PMTU probing.
+        postSetup = ''
+          ip link set dev ${wgIface} mtu 1280
+        '';
+      };
+    networking.hosts = lib.mkMerge [
+      (lib.mapAttrs'
+        (hostName: host:
+          lib.nameValuePair host.ipv4 [ "${hostName}.wg" ])
+        peers)
+      {
+        "${peers.losurdo.ipv4}" = [
+          "nix-extracache.losurdo.wg"
+          "nix-localcache.losurdo.wg"
+          "sftp.losurdo.wg"
+        ];
+      }
     ];
-  }
-];
-networking.firewall.extraCommands = lib.optionalString (wg.listenPort != null) ''
-  ip46tables -A nixos-fw -i any -p udp -m udp --dport ${toString wg.listenPort} -j ACCEPT
-'';
-
-networking.nftables.ruleset = lib.optionalString (wg.listenPort != null) ''
-  # Allow initiating connection to and from other peers
-  add rule inet filter net2fw udp dport ${toString wg.listenPort} counter accept comment "Wireguard ${iface} input from peers"
-  add rule inet filter fw2net udp sport ${toString wg.listenPort} counter accept comment "Wireguard ${iface} output to peers"
-  add rule inet filter lan2fw udp dport ${toString wg.listenPort} counter accept comment "Wireguard ${iface} input from peers"
-  add rule inet filter fw2lan udp sport ${toString wg.listenPort} counter accept comment "Wireguard ${iface} output to peers"
-
-  # Hook ${iface} into the input chain
-  add chain inet filter intra2fw
-  add rule inet filter input  iifname ${iface} jump intra2fw
-  add rule inet filter input  iifname ${iface} log level warn prefix "intra2fw: " counter drop
+    networking.firewall.extraCommands = lib.optionalString (wg.listenPort != null) ''
+      ip46tables -A nixos-fw -i any -p udp -m udp --dport ${toString wg.listenPort} -j ACCEPT
+    '';
 
-  # Hook ${iface} into the output chain
-  add chain inet filter fw2intra
-  add rule inet filter output oifname ${iface} jump fw2intra
-  add rule inet filter output oifname ${iface} log level warn prefix "fw2intra: " counter drop
+    networking.nftables.ruleset = lib.optionalString (wg.listenPort != null) ''
+      table inet filter {
+        chain input-lan {
+          udp dport ${toString wg.listenPort} counter accept \
+            comment "Wireguard ${wgIface} input from peers"
+        }
+        chain input-net {
+          udp dport ${toString wg.listenPort} counter accept \
+            comment "Wireguard ${wgIface} input from peers"
+        }
+        chain input-intra {
+          ${lib.optionalString (peers.${hostName}.peer.endpointsUpdater.enable or false) ''
+            tcp dport ${toString peers.${hostName}.listenPort} ip daddr ${peers.${hostName}.ipv4} counter accept comment "Wireguard ${wgIface} from peers to endpointUpdater"
+            ''
+          }
+        }
+        chain input {
+          iifname ${wgIface} jump input-intra
+          iifname ${wgIface} log level warn prefix "input-intra: " counter drop
+        }
 
-  # Allow connections to peers acting as an endpointsUpdater
-  ${lib.concatStringsSep "\n"
-      (lib.mapAttrsToList (peerName: peer: ''
-        add rule inet filter fw2intra tcp dport ${toString peer.listenPort} ip daddr ${peer.ipv4} \
-        counter accept comment "Wireguard ${iface} to endpointUpdater ${peerName}"
-        '')
-        (lib.filterAttrs (peerName: peer:
-          config.networking.wireguard.${iface}.peers.${peerName}.enable &&
-          (peers.${peerName}.peer.endpointsUpdater.enable or false))
-          peers))
-  }
-  ${lib.optionalString (peers.${hostName}.peer.endpointsUpdater.enable or false) ''
-      # Allow connections from peers when acting as an endpointsUpdater
-      add rule inet filter intra2fw tcp dport ${toString peers.${hostName}.listenPort} ip daddr ${peers.${hostName}.ipv4} \
-      counter accept comment "Wireguard ${iface} from peers to endpointUpdater"
-      ''
-  }
-'';
+        chain output-lan {
+          udp sport ${toString wg.listenPort} counter accept \
+            comment "Wireguard ${wgIface} output to peers"
+        }
+        chain output-net {
+          udp sport ${toString wg.listenPort} counter accept \
+            comment "Wireguard ${wgIface} output to peers"
+        }
+        chain output-intra {
+          ${lib.concatStringsSep "\n"
+              (lib.mapAttrsToList (peerName: peer: ''
+                ip daddr ${peer.ipv4} \
+                  tcp dport ${toString peer.listenPort} \
+                  counter accept \
+                  comment "Wireguard ${wgIface} to endpointUpdater ${peerName}"
+                '')
+                (lib.filterAttrs (peerName: peer:
+                  config.networking.wireguard.${wgIface}.peers.${peerName}.enable &&
+                  (peers.${peerName}.peer.endpointsUpdater.enable or false))
+                  peers))
+          }
+        }
+        chain output {
+          oifname ${wgIface} jump output-intra
+          oifname ${wgIface} log level warn prefix "output-intra: " counter drop
+        }
+      }
+    '';
 
-services.fail2ban.ignoreIP = lib.concatMap
-  (host: host.peer.allowedIPs)
-  (lib.attrValues peers);
-networking.networkmanager.unmanaged = ["wg-intra"];
-};
+    services.fail2ban.ignoreIP = lib.concatMap
+      (host: host.peer.allowedIPs)
+      (lib.attrValues peers);
+    networking.networkmanager.unmanaged = [ wgIface ];
+  };
 }