{ config, pkgs, ... }: let hostname = "tunnels"; domain = "example.com"; resolvers = [ "9.9.9.9" "2620:fe::fe" ]; egress = { interface = "eth0"; ipv4.gateway = "198.51.100.10"; ipv4.address = "198.51.100.1/24"; ipv6.gateway = "fe80::1"; ipv6.address = "2001:DB8:10:cafe:dcaf::3210/64"; }; tunnels = [{ interface = "wg0"; serverPort = 51820; serverAddress = "2001:db8:de:ff0::1/128"; clientAddress = "2001:db8:de:ff0::2/128"; clientSubnet = "2001:db8:de:f00::/60"; serverPrivateKeyFile = "wg0-server-private"; clientPublicKeyFile = "wg0-client-public"; }]; in { networking.hostName = hostname; networking.domain = domain; # Enable systemd-networkd systemd.network.enable = true; networking.useNetworkd = true; # Tools for monitoring/key generation environment.systemPackages = with pkgs; [ wireguard-tools tcpdump ]; # Configure Ethernet interface (eth0) systemd.network.networks."10-egress" = { matchConfig.Name = egress.interface; networkConfig = { DHCP = "no"; IPv6AcceptRA = "no"; IPv6PrivacyExtensions = "yes"; IPv6Forwarding = "yes"; }; address = [ egress.ipv4.address egress.ipv6.address ]; gateway = [ egress.ipv4.gateway egress.ipv6.gateway ]; dns = resolvers; }; imports = [ ./wireguard.nix ]; wireguard.interfaces = tunnels; networking.firewall = { allowedUDPPorts = map (x: x.serverPort) tunnels; }; networking.nat = { enable = true; externalInterface = egress.interface; internalInterfaces = map (x: x.interface) tunnels; }; }