diff --git a/modules/vpn.nix b/modules/vpn.nix index e40e095d0..4385218e6 100644 --- a/modules/vpn.nix +++ b/modules/vpn.nix @@ -1,14 +1,16 @@ # debugging: # - `journalctl -u systemd-networkd` +# - `networkctl --help` # # docs: # - wireguard (nixos): # - wireguard (arch): # -# to route all internet traffic through a VPN endpoint, run `systemctl start vpn-${vpnName}` +# to route all internet traffic through a VPN endpoint, run `sane-vpn up ${vpnName}` # to route an application's traffic through a VPN: `sane-vpn do ${vpnName} ${command[@]}` # to show the routing table: `ip rule` # to show the NAT rules used for bridging: `sudo iptables -t nat --list-rules -v` +# to force a peer address change (e.g. DNS change): `wg set "${interface}" peer "${publicKey}" endpoint "${endpoint}"` # # the rough idea here is: # 1. each VPN has an IP address: if we originate a packet, and the source address is the VPN's address, then it gets routed over the VPN trivially. @@ -179,6 +181,23 @@ let # but i couldn't get that to work for netns with SNAT, so set rpfilter to "loose". networking.firewall.checkReversePath = "loose"; + systemd.services."${name}-refresh" = { + # periodically re-apply peers, to ensure DNS mappings stay fresh + # borrowed from + wantedBy = [ "network.target" ]; + path = with pkgs; [ wireguard-tools ]; + serviceConfig.Restart = "always"; + serviceConfig.RestartSec = "60"; #< retry delay when we fail (because e.g. there's no network) + serviceConfig.Type = "simple"; + unitConfig.StartLimitIntervalSec = 0; + script = '' + while wg set ${name} peer ${publicKey} endpoint ${endpoint}; do + # in the normal case that DNS resolves, and whatnot, sleep before the next attempt + sleep 180 + done + ''; + }; + # networking.firewall.extraCommands = with pkgs; '' # # wireguard packet marking. without this, rpfilter drops responses from a wireguard VPN # # because the "reverse path check" fails (i.e. it thinks a response to the packet would go out via a different interface than what the wireguard packet arrived at).