10   peers = import wg-intra/peers.nix;
 
  11   wg = config.networking.wireguard.interfaces.${wgIface};
 
  14   # Each peer select the other peers allowed to connect to it
 
  15   options.networking.wireguard.${wgIface}.peers = lib.genAttrs (lib.attrNames peers) (_peerName: {
 
  16     enable = lib.mkEnableOption "this peer";
 
  19     #systemd.services."wireguard-${wgIface}".serviceConfig.LoadCredentialEncrypted =
 
  20     #  [ "privateKey:${inputs.self}/hosts/${hostName}/wireguard/${wgIface}/privateKey.cred" ];
 
  21     networking.wireguard.interfaces.${wgIface} =
 
  23         (removeAttrs peers.${hostName} [
 
  35                     peer.persistentKeepalive # Useful if this peer is behind a NAT
 
  36                       or peers.${hostName}.persistentKeepalive # Useful if this host is behind a NAT
 
  41                 removeAttrs (lib.filterAttrs (
 
  42                   peerName: _: config.networking.wireguard.${wgIface}.peers.${peerName}.enable
 
  45           privateKeyFile = "\$CREDENTIALS_DIRECTORY/privateKey";
 
  47           # Set the MTU to a minimum
 
  48           # (IPv4 requires at least 68 but it's 1280 for IPv6).
 
  49           # This prevents connections to stall on huge packets,
 
  50           # or delaying their initializing due to TCP PMTU probing.
 
  52             ip link set dev ${wgIface} mtu 1280
 
  55     networking.hosts = lib.mkMerge [
 
  56       (lib.mapAttrs' (hostName: host: lib.nameValuePair host.ipv4 [ "${hostName}.wg" ]) peers)
 
  58         "${peers.losurdo.ipv4}" = [
 
  59           "nix-extracache.losurdo.wg"
 
  60           "nix-localcache.losurdo.wg"
 
  65     networking.firewall.extraCommands = lib.optionalString (wg.listenPort != null) ''
 
  66       ip46tables -A nixos-fw -i any -p udp -m udp --dport ${toString wg.listenPort} -j ACCEPT
 
  69     networking.nftables.ruleset = lib.optionalString (wg.listenPort != null) ''
 
  72           udp dport ${toString wg.listenPort} counter accept \
 
  73             comment "Wireguard ${wgIface} input from peers"
 
  76           udp dport ${toString wg.listenPort} counter accept \
 
  77             comment "Wireguard ${wgIface} input from peers"
 
  80           ${lib.optionalString (peers.${hostName}.peer.endpointsUpdater.enable or false) ''
 
  82               toString peers.${hostName}.listenPort
 
  83             } ip daddr ${peers.${hostName}.ipv4} counter accept comment "Wireguard ${wgIface} from peers to endpointUpdater"
 
  87           iifname ${wgIface} jump input-intra
 
  88           iifname ${wgIface} log level warn prefix "input-intra: " counter drop
 
  92           udp sport ${toString wg.listenPort} counter accept \
 
  93             comment "Wireguard ${wgIface} output to peers"
 
  96           udp sport ${toString wg.listenPort} counter accept \
 
  97             comment "Wireguard ${wgIface} output to peers"
 
 100           ${lib.concatStringsSep "\n" (
 
 103                 ip daddr ${peer.ipv4} \
 
 104                   tcp dport ${toString peer.listenPort} \
 
 106                   comment "Wireguard ${wgIface} to endpointUpdater ${peerName}"
 
 111                   config.networking.wireguard.${wgIface}.peers.${peerName}.enable
 
 112                   && (peers.${peerName}.peer.endpointsUpdater.enable or false)
 
 118           oifname ${wgIface} jump output-intra
 
 119           oifname ${wgIface} log level warn prefix "output-intra: " counter drop
 
 124     services.fail2ban.ignoreIP = lib.concatMap (host: host.peer.allowedIPs) (lib.attrValues peers);
 
 125     networking.networkmanager.unmanaged = [ wgIface ];