{ pkgs, lib, config, ... }: { options.wireguard = { enable = lib.mkEnableOption "wireguard"; port = lib.mkOption { default = 51820; description = "The port for wireguard to use."; type = lib.types.int; }; externalInterface = lib.mkOption { description = "The external networking interface for wireguard to use."; type = lib.types.str; }; internalInterface = lib.mkOption { default = "wg0"; description = "The networking interface for wireguard to use."; type = lib.types.str; }; privateKeyFile = lib.mkOption { description = "The path to the private key of the wireguard server."; type = lib.types.path; }; }; config = lib.mkIf config.wireguard.enable { networking.nat.enable = true; networking.nat.externalInterface = config.wireguard.externalInterface; networking.nat.internalInterfaces = [ config.wireguard.internalInterface ]; networking.firewall.allowedUDPPorts = [ config.wireguard.port ]; networking.wireguard.interfaces = { ${config.wireguard.internalInterface} = { # Determines the IP address and subnet of the server's end of the tunnel interface. ips = [ "10.100.0.1/24" ]; listenPort = config.wireguard.port; # This allows the wireguard server to route your traffic to the internet and hence be like a VPN # For this to work you have to set the dnsserver IP of your router (or dnsserver of choice) in your clients postSetup = '' ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s 10.100.0.0/24 -o eth0 -j MASQUERADE ''; # This undoes the above command postShutdown = '' ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s 10.100.0.0/24 -o eth0 -j MASQUERADE ''; # Path to the servers private key file. privateKeyFile = config.wireguard.privateKeyFile; # TODO: add config option? peers = [ { publicKey = "L+NlTn0E9pgCoEoTYs4aDewZSMmyeyC1Os9DCdwYTjY="; allowedIPs = [ "10.100.0.2/32" ]; } ]; }; }; }; }