Change:
I'm unable to route all traffic through a properly configured Wireguard interface using both and wg-quick(8); when using I'm unable to ping any system outside my own, except for my router. If some other IP range is allowed, say , I am able to ping the interface, but my traffic is not routed through it. a valid Wireguard configuration in with under . . Or alternatively: a Wireguard interface via with . system.
likewise. I can ping the interface with allowedIPs of exactly, but with a catchall rule of , I can't even ping the interface anymore
one potential fix for this might be implementing the network user-namespace based approach I've feature requested in
I needed to set . Does that work?
the issue remains.
I was able to route (almost) all traffic, by either excluding the server endpoint ip from , or running after wg interface is brought up
I was able to route (almost) all traffic What traffic is not routed?
I was a bit lazy and did not specify all public ip ranges when excluding server endpoint from allowedIPs. Should be routing all traffic if you do though. Option 2 should cover anything other than the server endpoint itself, but I would have to add more rules to exclude private ip ranges.
I wasn't able to get this working, even after adding a manual route to the wireguard server (through my default gateway and regular eth0). Any suggestions?
I have the same problem. Doesn't matter whether I use wg-quick or the nixos options approach. Wireguard otherwise works fine when having only specific IP:s allowed, but now I wanted to route all traffic.
So I solved my specific problem a bit differently. I now move the wireguard interface(s) into a different Linux network namespace and then start my compositor (sway) within that network namespace. This works really well for me with the benefit of effectively forcing all processes run within sway such as firefox, mail client etc. to use only the wireguard interface(s) (because there aren't any other interfaces). It also prompted me to write this simple utility to do what I need: While not exactly what the wireguard dev suggests (I found it a bit too messy/difficult to launch dhcpd, wpa_supplicant or iwd + wireguard within a different namespace), it's close enough for me.
Hi interesting solution - is there a benefit to your over using ? I arrived at a similar solution by taking the existing, (seemingly complete or abandoned) . It uses underneath, but achieves a similar effect as you've described - I'm left with a tmux session (easily changed to or whatever) that is running in a netns with only / inside.
yeah I saw that one but I wanted a setuid binary so that I could run it as my normal user. The ip command has such a large surface area so I wouldn't want to make that setuid. I have a very basic... well "display manager" (if you squint hard) based on and I run that on tty1 and tty2 - so I get some options like "sway private" for example. For that to be seamless combined with network namespaces I need to be able to run it as my normal user. See and Also messing around with the gpg-agent service from home-manager as it must run within the same network namespace when you use the gnome3 pinentry variant (this is a socket activated service). I've gotten it to work but it's still a bit wip, nothing committed yet (and certainly no pull req against home-manager, if I ever do one).
I actually found another project today called exactly (same as mine) but quite a few years old written in C - this I opted to keep my version written in Rust since it's less code and hopefully somewhat more trustworthy because of Rust but it probably doesn't matter much in the end whichever one uses. What that other project did have however was which is a shell script for making the abstract dbus socket into a normal socket which can be used from within a namespace. So I adapted that a bit and now I don't need to run gpg-agent in any special way, can just use the service defs from home-manager which is pretty awesome overall. See here: and here: (as a reminder - I've had issues with gpg-agent because of pinentry gnome3 which uses dbus... if you're using some other pinentry variant you probably won't have this issue).
I have encountered the same issue when I was trying to connect my new NixOS setup to the same wireguard server my other devices are using. Using I was able to route the ipv4 traffic over the server, however, routing ipv6 still did not work. If anyone else reading this has the same issue: In the end, I found it a lot easier to use [see PR for details) instead of networking.wireguard. With it, everything mostly worked out-of-the-box without me having to add any routes manually. I had to change only a few things in my (for example rename to for the interface configuration). It would be really useful / awesome to have more information on how to set this up in the NixOS Wiki.
I am facing this issue, and used to fix it. IIRC, runs this command when you start it, how come doesn't do it?
I'm facing this issue myself. When you're describing this command to fix the issue: Is this run on the server or the client? Should the be the public IP of the server or the tunnel endpoint?
I'm using good ol' stateful Wireguard interface configuration on my laptop with interactive on the command line. It also didn't work for me but adding this line from the NixOS module to my made it work:
client : the public IP of the server : the ip of your router : the physical interface, e.g. PS: I just realised that is optional and would personally recommend to not specify it.
Great, thanks. This may be a bit difficult for me, given I'd like to support mobile devices that may not be able to run commands like that, but I may be able to get it to run on my macOS client.
The {server ip} as in my suggested update to the wiki endpoint = "{server ip}:"; # ToDo: route to endpoint not automatically configured
Should the endpoint route be by For my part I will test the use of instead of networking.wireguard.interfaces for configuring my client and report back if that worksforme.
worksforme (without setting DNS). I get DNS via my original non wireguarded IP connection. A separate topic for me is to understand the best way of handling DNS in a wireguarded environment.
Hello, I've currently tried following both regular wireguard and wg-quick approaches as mentioned in the wiki, is there a tl;dr version to configure the server so that it can allow all IPs? I'm a newbie to all of this and have been scratching at this for a few days now, thanks in advance.
isn't really meant for "redirect all traffic" usecases, as elaborated in It might change in the future once we get declarative network namespace support through networkd. However, using wg-quick should work. When it comes to debugging individual setups or server configurations, please ask in the Forums or on IRC, closing this issue.
is working, but i prefer to keep Reverse Path Filter enabled against IP spoofing attacks in bash:

Discussion:
certain packets anyway, you can insert rules at the start of this chain. <del> - ‘nixos-fw-rpfilter’ is used as the main chain in the raw table, </del> <ins> - ‘nixos-fw-rpfilter’ is used as the main chain in the mangle table, </ins> called from the built-in ‘PREROUTING’ chain.  If the kernel supports it and `cfg.checkReversePath` is set this chain will perform a reverse path filter test.

ip46tables -N nixos-fw # Clean up rpfilter rules <del> ip46tables -t raw -D PREROUTING -j nixos-fw-rpfilter 2> /dev/null || true ip46tables -t raw -F nixos-fw-rpfilter 2> /dev/null || true ip46tables -t raw -X nixos-fw-rpfilter 2> /dev/null || true </del> <ins> ip46tables -t mangle -D PREROUTING -j nixos-fw-rpfilter 2> /dev/null || true ip46tables -t mangle -F nixos-fw-rpfilter 2> /dev/null || true ip46tables -t mangle -X nixos-fw-rpfilter 2> /dev/null || true </ins> ${optionalString (kernelHasRPFilter && (cfg.checkReversePath != false)) '' # Perform a reverse-path test to refuse spoofers <del> # For now, we just drop, as the raw table doesn't have a log-refuse yet ip46tables -t raw -N nixos-fw-rpfilter 2> /dev/null || true ip46tables -t raw -A nixos-fw-rpfilter -m rpfilter --validmark ${optionalString (cfg.checkReversePath == "loose") "--loose"} -j RETURN </del> <ins> # For now, we just drop, as the mangle table doesn't have a log-refuse yet ip46tables -t mangle -N nixos-fw-rpfilter 2> /dev/null || true ip46tables -t mangle -A nixos-fw-rpfilter -m rpfilter --validmark ${optionalString (cfg.checkReversePath == "loose") "--loose"} -j RETURN </ins> # Allows this host to act as a DHCP4 client without first having to use APIPA <del> iptables -t raw -A nixos-fw-rpfilter -p udp --sport 67 --dport 68 -j RETURN </del> <ins> iptables -t mangle -A nixos-fw-rpfilter -p udp --sport 67 --dport 68 -j RETURN </ins> # Allows this host to act as a DHCPv4 server <del> iptables -t raw -A nixos-fw-rpfilter -s 0.0.0.0 -d 255.255.255.255 -p udp --sport 68 --dport 67 -j RETURN </del> <ins> iptables -t mangle -A nixos-fw-rpfilter -s 0.0.0.0 -d 255.255.255.255 -p udp --sport 68 --dport 67 -j RETURN </ins> ${optionalString cfg.logReversePathDrops '' <del> ip46tables -t raw -A nixos-fw-rpfilter -j LOG --log-level info --log-prefix "rpfilter drop: " </del> <ins> ip46tables -t mangle -A nixos-fw-rpfilter -j LOG --log-level info --log-prefix "rpfilter drop: " </ins> ''} <del> ip46tables -t raw -A nixos-fw-rpfilter -j DROP </del> <ins> ip46tables -t mangle -A nixos-fw-rpfilter -j DROP </ins> <del> ip46tables -t raw -A PREROUTING -j nixos-fw-rpfilter </del> <ins> ip46tables -t mangle -A PREROUTING -j nixos-fw-rpfilter </ins> ''} # Accept all traffic on the trusted interfaces.

ip46tables -D INPUT -j nixos-fw 2>/dev/null || true ${optionalString (kernelHasRPFilter && (cfg.checkReversePath != false)) '' <del> ip46tables -t raw -D PREROUTING -j nixos-fw-rpfilter 2>/dev/null || true </del> <ins> ip46tables -t mangle -D PREROUTING -j nixos-fw-rpfilter 2>/dev/null || true </ins> ''} ${cfg.extraStopCommands}

config = mkIf (cfg.interfaces != {}) { boot.extraModulePackages = optional (versionOlder kernel.kernel.version "5.6") kernel.wireguard; environment.systemPackages = [ pkgs.wireguard-tools ]; <del> # This is forced to false for now because the default "--validmark" rpfilter we apply on reverse path filtering # breaks the wg-quick routing because wireguard packets leave with a fwmark from wireguard. networking.firewall.checkReversePath = false; </del> systemd.services = mapAttrs' generateUnit cfg.interfaces; # Prevent networkd from clearing the rules set by wg-quick when restarted (e.g. when waking up from suspend).