New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
nixos/modules/networking/wg-quick Add wg-quick options support #53043
Conversation
f5b765d
to
1cace9f
Compare
c60fe08
to
42fd5e0
Compare
@fpletz pretty sure you will have some opinion on this as well. |
description = "The IP addresses of the interface."; | ||
}; | ||
|
||
dns = mkOption { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this use networking.nameservers
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No because wg-quick overrides everything by design and only while the VPN tunnel is up.
This ensures that users don't leak dns queries
@zx2c4 I say you doing some similar work only after i opened this PR. I feel like using wg-quick to get the default and safe behaviour around routing/dns/etc. is not a bad approach. |
a82dddf
to
daba929
Compare
Hey @exi, are you still working on this? |
@NinjaTrappeur sure but nobody responded to my PR |
Sorry for the delay in responding here. I haven't read the commit yet but I vaguely recall being poked, at some point, about my opinion replacing the nixos backend with a wg-quick powered backend. My general feeling about this is that wg-quick is a pile of hacks, and that distributions that already have control over the networking stack can do much better with something custom and focused. I'm happy to help the nix module if there are particular problems with it that need fixing. Alternatively, if man power is short and you do prefer just relying on the wg-quick stuff, I guess that's fine too, but it probably won't be as slick as the optimal nix-centric integration. There was some discussion in #31250 IIRC. |
See also #52411 |
I have been using this approach for some time now and would like to have it merged. We would have to replicate something like this because for many VPN use-cases, people don't want to invoke nix just to enable/disable their VPN. |
This is an implementation of wireguard support using wg-quick config generation. This seems preferrable to the existing wireguard support because it handles many more routing and resolvconf edge cases than the current wireguard support. It also includes work-arounds to make key files work. This has one quirk: We need to set reverse path checking in the firewall to false because it interferes with the way wg-quick sets up its routing.
@globin ping |
associated routes to. Setting this is useful for e.g. policy routing | ||
("ip rule") or virtual routing and forwarding ("ip vrf"). Both numeric | ||
table IDs and table names (/etc/rt_tables) can be used. Defaults to | ||
"main". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the default be declared in the option's default
instead?
I'd prefer this to use the same option names as in Otherwise I think this preferable to |
@globin I would prefer to keep the names identical to every wg-quick config out there but i don't really have a strong opinion. If you still prefer to make it match our own special snowflake names i could do that as well. |
Ah then fine by me, when deprecating we can easily add the renames. |
Would it make sense to backport this to 19.03? |
I would love to see this backported; it's a huge quality-of-life improvement for using Wireguard, and it doesn't break anything. |
environment.systemPackages = [ pkgs.wireguard-tools ]; | ||
# 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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think a service module should silently change the firewall behaviour
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to request @fpletz opinion on this :
is it something we should keep as-is for the next release?
Should this module configure the firewall to allow incoming UDP packets on the specified port? |
Not automatically, the policy is that opening ports should always be an explicit user configuration (SSH being the only exception to avoid locking oneself out of a remote machine). The module description could indicate that additional firewall config is needed. |
The reason it is not considered a valid mark is because we receive a packet from the network without a mark but sent the response with a mark because wg-quick uses firewall marks only for outgoing packages because it makes it really easy to bypass the default routing table. However this causes us to use a different return path from the perspective of rp_filter, which considers (incoming, nomark) and (outgoing, mark) as two different paths as long as --validmark is set. And if it considers these to be two different paths, it will drop the packets. |
Not sure, for wg-quick we have outgoing packets first. So incoming packets would fall into a RELATED state and i presume (without checking) that related packets are already allowed. |
Is it not supposed to be used on the server? |
Yes you are right. We may need some complex logic to figure out what port to open where. |
Yeah I don't think we should open a port either, as it seems to be against the general guidelines. Maybe just mention in the module that whatever port one specifies should be opened for a server-like peer. |
Maybe have a I dunno; no strong opinions here, but I think it's worth optimizing for the easy case here; most people that set up a Wireguard server will need to set the rpfilter/port networking options anyway. Other thoughts:
|
Yes that's the usual approach for modules that needs some firewall rules : description should explain it has to be configured by the user. Then it's left to the user to open the right port on the right interfaces (or all interfaces) according to his own setup.
That could be an extra precaution. |
This is an implementation of wireguard support using wg-quick config
generation.
This seems preferable to the existing wireguard support because
it handles many more routing and resolvconf edge cases than the
current wireguard support.
I'm aware that there are situations where you want the explicit control over wireguard provided by the existing networking.wireguard module but other distributions are also shipping wg-quick@.service units to make it very hard to do the wrong thing.
Our hand baked wireguard setups already diverge from wg-quick in significant ways and for the worse.
Wrong ipv6 routing and missing dns handling make it very easy to accidentally pass traffic past wireguard even if allowedIps is set to ::/0.
I'm not advocating to remove networking.wireguard but i would like to offer a way to get the "easy and secure by default" behavior that wg-quick provides.
It also includes workarounds to make key files work.
Things done
sandbox
innix.conf
on non-NixOS)nix-shell -p nox --run "nox-review wip"
./result/bin/
)nix path-info -S
before and after)