{ pkgs, lib, config, hosts, hostName, wireguard, ... }: let inherit (builtins) hasAttr removeAttrs; inherit (config.security) gnupg; inherit (config.boot) initrd; wg = "wg-intra"; relay = hosts.mermet.extraArgs.wireguard.${wg}; peers = lib.filterAttrs (peerName: host: hasAttr "${wg}" host.extraArgs.wireguard ) (removeAttrs hosts [hostName]) // { "oignon".extraArgs.wireguard.${wg} = rec { ipv4 = "192.168.42.3"; peer = { publicKey = "tE4fzqDrr7BgfOo9tWgGnpu3v0JRDEUZbJnm9e2F/GA="; allowedIPs = [ "${ipv4}/32" ]; }; }; }; in { security.gnupg.secrets."wireguard/${wg}/privateKey" = { /* systemdConfig.serviceConfig = { before = [ "wireguard-${wg}.service" ]; wantedBy = [ "wireguard-${wg}.service" ]; requiredBy = [ "wireguard-${wg}.service" ]; }; */ }; systemd.services."wireguard-${wg}" = { after = [ gnupg.secrets."wireguard/${wg}/privateKey".service ]; requires = [ gnupg.secrets."wireguard/${wg}/privateKey".service ]; }; networking.nftables.ruleset = '' # Allow initiating connection for ${wg} add rule inet filter fw2net ip daddr ${hosts.mermet.extraArgs.ipv4} udp dport ${toString relay.listenPort} counter accept comment "${wg}" #add rule inet filter fw2net udp sport ${toString wireguard.${wg}.listenPort} counter accept comment "${wg}" # Allow peers to initiate connection for ${wg} add rule inet filter net2fw udp dport ${toString wireguard.${wg}.listenPort} counter accept comment "${wg}" # Hook ${wg} into relevant chains add rule inet filter input iifname "${wg}" jump intra2fw add rule inet filter input iifname "${wg}" log level warn prefix "intra2fw: " counter drop add rule inet filter output oifname "${wg}" jump fw2intra add rule inet filter output oifname "${wg}" log level warn prefix "fw2intra: " counter drop # ${wg} firewalling add rule inet filter fw2intra counter accept add rule inet filter intra2fw ip saddr ${relay.ipv4} counter accept comment "relay" add rule inet filter forward iifname "${wg}" jump fwd-intra ''; boot.kernel.sysctl."net.ipv4.ip_forward" = 1; networking.wireguard.interfaces.${wg} = { ips = [ "${wireguard.${wg}.ipv4}/24" ]; listenPort = wireguard.${wg}.listenPort; privateKeyFile = gnupg.secrets."wireguard/${wg}/privateKey".path; peers = lib.mapAttrsToList (peerName: host: host.extraArgs.wireguard.${wg}.peer // { inherit (wireguard.${wg}) persistentKeepalive; } ) peers; }; networking.hosts = lib.mapAttrs' (peerName: peer: lib.nameValuePair peer.extraArgs.wireguard.${wg}.ipv4 [ "${peerName}.wg" ] ) peers; services.upnpc.redirections = [ { description = "WireGuard"; externalPort = wireguard.${wg}.listenPort; protocol = "UDP"; duration = 30 * 60; service.wantedBy = ["wireguard-${wg}.service"]; service.partOf = ["wireguard-${wg}.service"]; } ]; # Open a wireguard tunnel to a relay # in case the host is hosted behind a NAT and has no SSH port forwarding. # This enables to send the disk password to the initrd, like that: # ssh -J mermet.sourcephile.fr root@losurdo.wg -p 2222 boot.initrd.secrets."/root/initrd/${wg}.key" = "/root/initrd/${wg}.key"; /* installer.ssh-nixos.script = '' # Send the wireguard key of the initrd gpg --decrypt '${gnupg.store}/wireguard/${wg}/privateKey.gpg' | ssh '${config.installer.ssh-nixos.target}' \ install -D -m 400 -o root -g root /dev/stdin /root/initrd/${wg}.key ''; */ boot.initrd.kernelModules = [ "wireguard" ]; boot.initrd.extraUtilsCommands = '' #copy_bin_and_libs ${pkgs.wireguard-tools}/bin/wg cp -fpdv ${pkgs.wireguard-tools}/bin/.wg-wrapped $out/bin/wg ''; boot.initrd.network.postCommands = '' ip link add dev ${wg} type wireguard ip address add ${wireguard.${wg}.ipv4}/24 dev ${wg} wg set ${wg} private-key /root/initrd/${wg}.key \ listen-port ${toString wireguard."${wg}".listenPort} ip link set up dev ${wg} wg set ${wg} peer ${relay.peer.publicKey} \ endpoint ${hosts.mermet.extraArgs.ipv4}:${toString relay.listenPort} \ allowed-ips ${relay.ipv4}/32 \ persistent-keepalive 5 ip route replace ${relay.ipv4}/32 dev ${wg} table main ''; boot.initrd.postMountCommands = lib.mkIf initrd.network.flushBeforeStage2 '' ip link del dev ${wg} ''; environment.systemPackages = [ pkgs.natpunch-go ]; }