{ config, pkgs, lib, ... }: let inherit (pkgs) iptables; inherit (lib) mkIf mkEnableOption mkOption ; cfg = config.foundation.wireguard; # TODO: we might want to configure these through options? wireguardPort = 51820; wireguardIPv4 = number: subnet: "10.123.10.${number}/${subnet}"; wireguardIPv6 = number: subnet: "fd0f:123::${number}/${subnet}"; wireguardInterface = "wg0"; peerIPs = peerNumber: [ (wireguardIPv4 peerNumber "32") (wireguardIPv6 peerNumber "128") ]; peers = [ # mel { publicKey = "vnZoHXapCLLUhZ8A8R5W0iJ8LpWVLve29z41kkoT0BU="; allowedIPs = peerIPs "2"; } # andrei { publicKey = "qqU4uYImLfUohIwl4KBshPtTINFcs0JVALjbmwpfxRg="; allowedIPs = peerIPs "3"; } # sergo { publicKey = "qbZGMNIDZFCJC6SHtlyNIlIdGWHELceXClJCcagrj2Y="; allowedIPs = peerIPs "4"; } ]; in { options.foundation.wireguard = { server = { enable = mkEnableOption "wireguard vpn server"; externalInterface = mkOption { type = lib.types.string; default = "eth0"; }; }; }; config = mkIf cfg.server.enable { age.secrets.wireguard-private-key = { file = ../../secrets/wireguard-private-key.age; }; # enable nat, to rename internal wireguard ips to external ip (w/ iptables) networking = { nat = { enable = true; internalInterfaces = [ wireguardInterface ]; inherit (cfg.server) externalInterface; }; firewall = { allowedUDPPorts = [ wireguardPort ]; }; }; # enable kernel support for ipv6 forwarding boot.kernel.sysctl = { "net.ipv6.conf.all.forwarding" = 1; "net.ipv6.conf.default.forwarding" = 1; }; networking.wireguard.interfaces.${wireguardInterface} = let inherit (cfg.server) externalInterface; in { inherit peers; # ip address of server + subnet of network ips = [ (wireguardIPv4 "1" "24") (wireguardIPv6 "1" "112") ]; listenPort = wireguardPort; # route wireguard traffic to the internet # also requires clients to have dns set. (i think) # to avoid, maybe? use wg-quick + dnsmasq? postSetup = '' ${iptables}/bin/iptables -t nat -A POSTROUTING -s ${wireguardIPv4 "0" "24"} -o ${externalInterface} -j MASQUERADE ${iptables}/bin/ip6tables -t nat -A POSTROUTING -s ${wireguardIPv6 "0" "112"} -o ${externalInterface} -j MASQUERADE ''; postShutdown = '' ${iptables}/bin/iptables -t nat -D POSTROUTING -s ${wireguardIPv4 "0" "24"} -o ${externalInterface} -j MASQUERADE ${iptables}/bin/ip6tables -t nat -D POSTROUTING -s ${wireguardIPv6 "0" "112"} -o ${externalInterface} -j MASQUERADE ''; privateKeyFile = config.age.secrets.wireguard-private-key.path; }; }; }