{ pkgs, lib, config, hosts, ... }: let inherit (builtins) hasAttr removeAttrs; inherit (config.security) gnupg; inherit (config.boot) initrd; iface = "wg-intra"; wg = config.networking.wireguard.interfaces.${iface}; relay = hosts.mermet.extraArgs // hosts.mermet.config.networking.wireguard.interfaces.${iface} // lib.head (lib.filter (peer: peer.endpoint != null && builtins.match "^\(.*\):[0-9]*$" peer.endpoint == [hosts.mermet.extraArgs.ipv4]) wg.peers); in { imports = [ ../../../../networking/wireguard/wg-intra.nix ]; config = { networking.wireguard.interfaces.${iface} = { privateKeyFile = gnupg.secrets."wireguard/${iface}/privateKey".path; }; security.gnupg.secrets."wireguard/${iface}/privateKey" = { /* systemdConfig.serviceConfig = { before = [ "wireguard-${iface}.service" ]; wantedBy = [ "wireguard-${iface}.service" ]; requiredBy = [ "wireguard-${iface}.service" ]; }; */ }; systemd.services."wireguard-${iface}" = { after = [ gnupg.secrets."wireguard/${iface}/privateKey".service ]; requires = [ gnupg.secrets."wireguard/${iface}/privateKey".service ]; serviceConfig.Upholds = [ "upnpc-${toString wg.listenPort}.service" ]; }; networking.nftables.ruleset = '' # Allow initiating connection to and from other peers add rule inet filter fw2net udp sport ${toString wg.listenPort} counter accept comment "${iface} output to peers" add rule inet filter net2fw udp dport ${toString wg.listenPort} counter accept comment "${iface} input from peers" # Hook ${iface} into relevant chains add rule inet filter input iifname "${iface}" jump intra2fw add rule inet filter input iifname "${iface}" log level warn prefix "intra2fw: " counter drop add rule inet filter output oifname "${iface}" jump fw2intra add rule inet filter output oifname "${iface}" log level warn prefix "fw2intra: " counter drop # ${iface} firewalling add rule inet filter fw2intra counter accept ${lib.concatMapStringsSep "\n" (ip: '' add rule inet filter intra2fw ip saddr ${ip} counter accept comment "relay" '') relay.ips} add rule inet filter forward iifname "${iface}" jump fwd-intra ''; # Apparently required to get NAT reflection. services.upnpc.redirections = [ { description = "WireGuard"; externalPort = wg.listenPort; protocol = "UDP"; duration = 30 * 60; service.requiredBy = [ "wireguard-${iface}.service" ]; service.before = [ "wireguard-${iface}.service" ]; } ]; boot.kernel.sysctl."net.ipv4.ip_forward" = 1; # 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/${iface}.key" = "/root/initrd/${iface}.key"; /* installer.ssh-nixos.script = '' # Send the wireguard key of the initrd gpg --decrypt '${gnupg.store}/wireguard/${iface}/privateKey.gpg' | ssh '${config.installer.ssh-nixos.target}' \ install -D -m 400 -o root -g root /dev/stdin /root/initrd/${iface}.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 ${iface} type wireguard ${lib.concatMapStringsSep "\n" (ip: '' ip address add ${ip} dev ${iface} '') wg.ips} wg set ${iface} private-key /root/initrd/${iface}.key \ listen-port ${toString wg.listenPort} ip link set up dev ${iface} wg set ${iface} peer ${relay.publicKey} \ endpoint ${relay.ipv4}:${toString relay.listenPort} \ allowed-ips ${relay.ipv4}/32 \ persistent-keepalive 5 ip route replace ${relay.ipv4}/32 dev ${iface} table main ''; boot.initrd.postMountCommands = lib.mkIf initrd.network.flushBeforeStage2 '' ip link del dev ${iface} ''; }; }