{ pkgs, lib, config, inputs, ... }: let inherit (config.boot) initrd; wgIface = "wg-intra"; wg = config.networking.wireguard.interfaces.${wgIface}; wg-intra-peers = import (inputs.julm-nix + "/nixos/profiles/wireguard/wg-intra/peers.nix"); relay = wg-intra-peers.mermet; in { imports = [ (inputs.julm-nix + "/nixos/profiles/wireguard/wg-intra.nix") ]; systemd.services."wireguard-${wgIface}" = { serviceConfig = { LoadCredentialEncrypted = [ "privateKey:${./. + "/${wgIface}/privateKey.cred"}" ]; }; unitConfig = { Upholds = [ "upnpc-${toString wg.listenPort}.service" ]; }; }; networking.wireguard.${wgIface}.peers = { mermet.enable = true; oignon.enable = true; patate.enable = true; carotte.enable = true; aubergine.enable = true; }; networking.nftables.ruleset = '' table inet filter { chain input-intra { tcp dport ssh counter accept comment "SSH" udp dport 60000-61000 counter accept comment "Mosh" } chain output-intra { tcp dport { ssh, 2222 } counter accept comment "SSH" udp dport 60001-60010 counter accept comment "Mosh" tcp dport { http, https } counter accept comment "HTTP" tcp dport git counter accept comment "Git" } } table inet nat { chain postrouting { iifname ${wgIface} oifname netIface masquerade } } ''; # Apparently required to get NAT reflection. services.upnpc.enable = true; services.upnpc.redirections = [ { description = "WireGuard"; externalPort = wg.listenPort; protocol = "UDP"; duration = 30 * 60; service.requiredBy = [ "wireguard-${wgIface}.service" ]; service.before = [ "wireguard-${wgIface}.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.wg root@losurdo.wg -p 2222 # TODO: use a dedicated interface wg-initrd boot.initrd.secrets."/root/initrd/${wgIface}.key" = "/run/credentials/wireguard-${wgIface}.service/privateKey"; boot.initrd.kernelModules = [ "wireguard" ]; systemd.network = { netdevs = { "50-${wgIface}" = { netdevConfig = { Kind = "wireguard"; Name = wgIface; MTUBytes = "1280"; }; wireguardConfig = { PrivateKeyFile = "/root/initrd/${wgIface}.key"; ListenPort = wg.listenPort; }; wireguardPeers = [ { wireguardPeerConfig = { PublicKey = relay.peer.publicKey; AllowedIPs = [ "${relay.ipv4}/32" ]; PersistentKeepalive = 5; }; } ]; }; }; networks.wgIface = { name = wgIface; address = wg.ips; }; }; }