git: ignore formatting with nixfmt-rfc-style
[julm/julm-nix.git] / nixos / profiles / wireguard / wg-intra.nix
index add589a178c082f0dd837bed4fc04f3674386774..c070e91a8f6696e02993943f86ead60d20d8238d 100644 (file)
-{ pkgs, lib, config, hostName, private, ... }:
+{
+  inputs,
+  lib,
+  config,
+  hostName,
+  ...
+}:
 let
-  iface = "wg-intra";
-  hosts = import wg-intra/hosts.nix;
-  wg = config.networking.wireguard.interfaces.${iface};
+  wgIface = "wg-intra";
+  peers = import wg-intra/peers.nix;
+  wg = config.networking.wireguard.interfaces.${wgIface};
 in
 {
-networking.wireguard.interfaces.${iface} = lib.recursiveUpdate
-  (removeAttrs hosts.${hostName} ["ipv4" "persistentKeepalive" "peer"])
-  {
-    peers =
-      lib.mapAttrsToList (peerName: peer: lib.recursiveUpdate
-        { persistentKeepalive =
-          peer.persistentKeepalive # Useful if this peer is behind a NAT
-          or hosts.${hostName}.persistentKeepalive # Useful if this host is behind a NAT
-          or null; }
-        peer.peer
-      ) (removeAttrs hosts [hostName]);
-    privateKeyFile = lib.mkDefault "${private}/${hostName}/wireguard/${iface}/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
+          # 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) ''
+      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
+        }
+
+        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 = [ wgIface ];
   };
-networking.hosts = lib.mkMerge [
-  (lib.mapAttrs' (hostName: host:
-    lib.nameValuePair host.ipv4 [ "${hostName}.wg" ]) hosts)
-  { "${hosts.losurdo.ipv4}" = [
-    "nix-extracache.losurdo.wg"
-    "nix-localcache.losurdo.wg"
-  ]; }
-];
-networking.firewall.extraCommands = ''
-  ip46tables -A nixos-fw -i ${iface} -p tcp -m tcp --dport 22 -j ACCEPT
-'' + lib.optionalString (wg.listenPort != null) ''
-  ip46tables -A nixos-fw -i any -p udp -m udp --dport ${toString wg.listenPort} -j ACCEPT
-'';
-services.fail2ban.ignoreIP = lib.concatMap
-  (host: host.peer.allowedIPs)
-  (lib.attrValues hosts);
 }