1 { inputs, pkgs, lib, config, hostName, ... }:
 
   4   peers = import wg-intra/peers.nix;
 
   5   wg = config.networking.wireguard.interfaces.${wgIface};
 
   8 # Each peer select the other peers allowed to connect to it
 
   9 options.networking.wireguard.${wgIface}.peers =
 
  10   lib.genAttrs (lib.attrNames peers) (peerName: {
 
  11     enable = lib.mkEnableOption "this peer";
 
  14 systemd.services."wireguard-${wgIface}".serviceConfig.LoadCredentialEncrypted =
 
  15   "privateKey:" + inputs.self.outPath + "/hosts/${hostName}/wireguard/${wgIface}/privateKey.cred";
 
  16 networking.wireguard.interfaces.${wgIface} = lib.recursiveUpdate
 
  17   (removeAttrs peers.${hostName} ["ipv4" "persistentKeepalive" "peer"])
 
  20       lib.mapAttrsToList (peerName: peer:
 
  24               peer.persistentKeepalive # Useful if this peer is behind a NAT
 
  25               or peers.${hostName}.persistentKeepalive # Useful if this host is behind a NAT
 
  30           (lib.filterAttrs (peerName: _: config.networking.wireguard.${wgIface}.peers.${peerName}.enable) peers)
 
  32     privateKeyFile = "$CREDENTIALS_DIRECTORY/privateKey";
 
  34     # Set the MTU to a minimum
 
  35     # (IPv4 requires at least 68 but it's 1280 for IPv6).
 
  36     # This prevents connections to stall on huge packets,
 
  37     # or delaying their initializing due to TCP PMTU probing.
 
  39       ip link set dev ${wgIface} mtu 1280
 
  42 networking.hosts = lib.mkMerge [
 
  43   (lib.mapAttrs' (hostName: host:
 
  44     lib.nameValuePair host.ipv4 [ "${hostName}.wg" ]) peers)
 
  46     "${peers.losurdo.ipv4}" = [
 
  47       "nix-extracache.losurdo.wg"
 
  48       "nix-localcache.losurdo.wg"
 
  53 networking.firewall.extraCommands = lib.optionalString (wg.listenPort != null) ''
 
  54   ip46tables -A nixos-fw -i any -p udp -m udp --dport ${toString wg.listenPort} -j ACCEPT
 
  57 networking.nftables.ruleset = lib.optionalString (wg.listenPort != null) ''
 
  60       udp dport ${toString wg.listenPort} counter accept \
 
  61         comment "Wireguard ${wgIface} input from peers"
 
  64       udp dport ${toString wg.listenPort} counter accept \
 
  65         comment "Wireguard ${wgIface} input from peers"
 
  68       ${lib.optionalString (peers.${hostName}.peer.endpointsUpdater.enable or false) ''
 
  69         tcp dport ${toString peers.${hostName}.listenPort} ip daddr ${peers.${hostName}.ipv4} counter accept comment "Wireguard ${wgIface} from peers to endpointUpdater"
 
  74       iifname ${wgIface} jump input-intra
 
  75       iifname ${wgIface} log level warn prefix "input-intra: " counter drop
 
  79       udp sport ${toString wg.listenPort} counter accept \
 
  80         comment "Wireguard ${wgIface} output to peers"
 
  83       udp sport ${toString wg.listenPort} counter accept \
 
  84         comment "Wireguard ${wgIface} output to peers"
 
  87       ${lib.concatStringsSep "\n"
 
  88           (lib.mapAttrsToList (peerName: peer: ''
 
  89             ip daddr ${peer.ipv4} \
 
  90               tcp dport ${toString peer.listenPort} \
 
  92               comment "Wireguard ${wgIface} to endpointUpdater ${peerName}"
 
  94             (lib.filterAttrs (peerName: peer:
 
  95               config.networking.wireguard.${wgIface}.peers.${peerName}.enable &&
 
  96               (peers.${peerName}.peer.endpointsUpdater.enable or false))
 
 101       oifname ${wgIface} jump output-intra
 
 102       oifname ${wgIface} log level warn prefix "output-intra: " counter drop
 
 107 services.fail2ban.ignoreIP = lib.concatMap
 
 108   (host: host.peer.allowedIPs)
 
 109   (lib.attrValues peers);
 
 110 networking.networkmanager.unmanaged = [ wgIface ];
 
 111 systemd.services.sshd.after = ["wireguard-${wgIface}.service"];
 
 112 services.openssh.listenAddresses = [
 
 113   { addr = peers.${hostName}.ipv4; port = 22; }