{ config, lib, pkgs, nodes, builtins, secrets, ... }: with lib; { imports = [ ./options.nix ./roaming.nix ]; config = mkIf config.wireguard.enable ( let cfg = config.wireguard; peers = let attrPeers = mapAttrs (n: node: let peer = node.config.wireguard; endpointIP = node.config.wireguard.endpoint; in { endpoint = "${endpointIP}:${toString peer.port}"; publicKey = peer.publicKey; persistentKeepalive = 25; allowedIPs = [ "${peer.v4.address}/32" "${peer.v6.ula}::${peer.v6.address}/128" "${peer.v6.gua}::${peer.v6.address}/128" ] ++ peer.allowedIPs; }) (filterAttrs (n: node: node.config.wireguard.enable) nodes); peers = attrValues attrPeers; in peers; in { secrets = mkIf config.wireguard.enable { wireguard = { source = ../../secrets + ("/" + "${config.networking.hostName}.privkey"); dest = "/root/wireguard/privkey"; }; }; networking.firewall.allowedUDPPorts = mkIf config.wireguard.enable [ 51820 ]; networking.wireguard.interfaces = mkIf config.wireguard.enable { wg0 = with { ifname = "wg0"; }; { ips = [ "${cfg.v4.address}/${toString cfg.v4.prefixLength}" "${cfg.v6.ula}::${cfg.v6.address}/128" "${cfg.v6.gua}::${cfg.v6.address}/128" ]; listenPort = cfg.port; postSetup = '' ${pkgs.nftables}/bin/nft add table ${ifname} ${pkgs.nftables}/bin/nft 'add chain ${ifname} prerouting { type nat hook prerouting priority 0 ; }' ${pkgs.nftables}/bin/nft 'add chain ${ifname} postrouting { type nat hook postrouting priority 100 ; }' ${pkgs.nftables}/bin/nft add rule ${ifname} postrouting ip saddr ${cfg.v4.network}/${ toString cfg.v4.prefixLength } oif ${cfg.natInterface} masquerade ''; postShutdown = '' ${pkgs.nftables}/bin/nft flush table ${ifname} || true ${pkgs.nftables}/bin/nft delete table ${ifname} || true ''; privateKeyFile = "/root/wireguard/privkey"; peers = peers; }; }; boot.kernel.sysctl = { "net.ipv4.ip_forward" = lib.mkDefault true; "net.ipv6.conf.all.forwarding" = true; "net.netfilter.nf_conntrack_tcp_be_liberal" = true; }; } ); }