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
resolvconf/resolvectl fails to make DNS servers exclusive #17529
Comments
|
what's the "resolvectl" output in this case? My guess is that that the underlying iface also wants "exclusive" DNS traffic, and if two ifaces want that they both get it. Basically there's are only three levels of priority defined when routing in resolved: "preferable", "regular", "noway". If we look-up a domain and there's an interface with a preferable domain name route, it will get it, and that's the end. If there are multiple "preferable" interfaces, they all get it. If there are no "preferable" interfaces, then the "regular" ones will get it. All of them. (Well, it's slightly more complex, since we also take the "closeness" of the match into account, i.e. if we look up "foo.bar.com" and one iface has "com" as listed routing domain and the other has "bar.com", then we will only route to the latter, since it's the "closer" match of the two. But in this case this doesn#t matter). resolvconf's "-x" switch s mapped to the "preferable" routing priority. Anyway, "resolvectl" should reveal what is configured precisely, and my educated guess is that the other, underlying interface also has a "preferable" routing set up for it, i.e. did the equivalent of "resolvconf -x", too. |
|
Looks like that's what's going on, judging by the So this would be a bug in whatever is assigning the DNS servers? Fresh Fedora 33, so I assume that's networkmanager setting the "preferred" status instead of "regular"? CC @thom311 |
|
yes, "~." means "please please preferably route DNS traffic for all domains" here. Both wg0 and enp0s2 have that set, hence both get the traffic. I am not sure why NM would set this on a regular ethernet interface though. I mean, it makes sense to set something like this on vpn devices, but on regular devices? maybe NM actively manages the |
That seems reasonable to me. Waiting for @thom311's input. |
How is this priority configured? Is it:
And, I assume that if a link does not have |
|
Note there is a corresponding Red Hat bug where I have left a couple comments.
Correct. If this VPN was configured by NetworkManager, it would do the right thing: either set ~. on the VPN interface (e.g. for a full-tunnel VPN), or leave it on the Ethernet interface and set some other specific DNS domain on the VPN interface (e.g. for a corporate VPN).
No, that's no good because it will result in DNS leaks. Users expect that DNS goes only where they have configured it to go. Consider the case of a corporate VPN when there is no ~. search domain on the ethernet interface: then requests to pornhub.com or whatever could leak to the VPN interface by mistake. IMO the problem here is inconsistent use of NetworkManager. You should either (a) use NetworkManager to configure the VPN, or (b) totally disable NetworkManager. Going behind NetworkManager's back like this is a problem. Tools like wg-quick are great for systems that don't use NetworkManager. If using NetworkManager, I don't see why you would want to use them when you could configure your VPN in NetworkManager instead. |
|
Well, I'm not 100% certain whether NetworkManager developers would completely agree with that. Let's ask @thom311. It's possible that having NetworkManager try to account for VPN interfaces that it doesn't control might be possible. I don't think we should expect it to, but maybe it would be possible. |
I think NetworkManager should always set ~. on exactly one interface. |
|
NetworkManager should not set ~. on non-VPN interfaces. That's preposterous and makes any outside systems' interactions with systemd-resolved impossible. |
|
You must be able to set up a vpn outside NetworkManager. If not, then you are suddenly saying that all VPNs outside the ones supported by NM will never work with any distro using NM. The VPN support on Linux suddenly become quite bad. |
As I've tried to explain: if you try to change this behavior, you're going to cause unexpected DNS leaks. There are really very major consequences to suggesting that this change. We passed the systemd-resolved Fedora change proposal based on promises that NetworkManager would always configure a ~. domain. If NetworkManager stops doing this, then many of the criticisms we received about systemd-resolved's default behavior of sending DNS to every configured server would become valid. E.g. my statements here would no longer be true, as would various other promises I made throughout that conversation. |
|
Changing that would also invalidate everything written here, which is almost the entire justification for switching to systemd-resolved in the first place. (If we can't do split DNS correctly, the only significant remaining benefit would be the shared DNS cache.) |
I too very much disagree with this. For people who use VPN or VPNs for work, NM setting ~. on non-VPN interfaces is crucial.
No, there is no rule that "ethernet" is somehow always inferior to "vpn". For different people, different things have priority. Both cases are very much valid. In fact, people may have multiple VPNs active, with higher and lower priority.
Yeah, but in that case you somehow need to tell NM to use a different config. Essentially, NM was told that the ethernet connection is to be preferably used for all traffic, and it's adhering to that. If you want different config, NM needs to be told somehow. |
I'm not sure I follow what you're saying. Do I have it backwards? Do you have it backwards? If you use a VPN for work, then you want your VPN interface to have (Maybe you're somehow worried about the reverse? Sending your personal traffic over your company's VPN? But in that case, shouldn't the more specific domain suffix for your company's VPN handle that anyway?) More generally, the exclusivity of At least that's my understanding from Lennart's description above of preferable/regular/noway. |
This isn't hard if the wireguard interface corresponds to a NetworkManager connection profile: just give it ipv{4,6}.dns-priority = -1 if it is to be a full-tunnel VPN. That should work. But in this case, the wireguard connection is not configured via NetworkManager, which complicates things a lot. I'm not sure if there is actually any way to do this or not....
Yes, definitely. In this case, you must not have ~. on the ethernet/wifi interface. That is one of the two main use-cases for VPNs, and the default case in NetworkManager. But as for the second main use-case:
Correct, that's indeed the problem. This is the second main use-case for VPNs. In this case, you must have ~. on the ethernet/wifi interface or you will leak DNS to the VPN. In gnome-control-center, you achieve this use-case by selecting "Use this connection only for resources on its network." (Well, that doesn't work for Wireguard yet, since GNOME sadly doesn't support Wireguard yet, but it works for other types of VPNs that can be configured graphically.) With that checkbox checked, you're in this case two, corporate VPN. Otherwise, you get case one, full tunnel VPN. So you see, the requirements for this second case are the opposite of the requirements for the first case. In case one, we must not have ~. on the non-VPN interface. In case two, we must have it there. NetworkManager has to satisfy both cases, and it will do the right thing depending on whether you checked that checkbox in the UI or not. (I'm honestly not certain what lower-level setting the checkbox corresponds to, but of course there's some non-GUI way to get that behavior as well.) To make sure there is no ambiguity about where DNS goes, NetworkManager ensures there is always a ~. domain on exactly one interface. If your query matches some more specific-domain, then that controls where it goes; otherwise, it goes to the DNS server corresponding to the interface with the ~. domain. Any configured global domains are ignored and unused. This ensures there are no surprises, at least if you use NetworkManager to configure your VPN. But now we have a problem with wg-quick:
Again correct. This basically means that But note that limitation is documented behavior, see resolvconf(1): I don't think Probably a better solution for be for wg-quick to use resolvectl or the D-Bus API instead, and manually remove ~. from other interfaces. That would probably be more reliable. (But again, I wonder if NetworkManager will undo that if it gets restarted, for example.)
Well, there's where we have a couple problems:
|
Thinking about this more... maybe we should just do this, and see how well it works in practice. I bet that will be fine. |
|
Hmm, so DNS routing in resolved has actually one more feature, that I didn't mention above: the "default-route" boolean that an iface can have. If a name is looked up for which no route exists it will be routed to all interfaces that have "default-route" set to true, but not to any that have it to false. (the field defaults to true for all interfaces) Let's put together a set of typical interfaces:
So, now let's see what happens if these ifaces are turned on.
So in all listed cases the right thing happens. And now to come back to the this issue itself. In this combination, "resolvectl -x" actually does the right thing, the way @zx2c4 expects it, as it -x translates to the exact same settings as applied for Does this make sense? |
Right, it seems like you've got all bases covered in resolved. I'm pretty sure the issue is that @thom311 misunderstood how ~. works in systemd, because networkmanager has a similar syntax with slightly different semantics. So the thing to do now would be to stop setting ~. on every interface from networkmanager, which totally destroys the resolved scheme. |
|
Hm, yes, that sounds like a good proposal. If @thom311 agrees, then we would not need any changes in systemd or in wg-quick: we would only need changes in NetworkManager. (NetworkManager currently doesn't touch the DefaultRoute setting at all, since it uses ~. to force the DNS to go where expected.) (wg-quick should still probably use something more sophisticated than resolvconf to configure systemd-resolved. But whatever. :) |
|
I agree, this needs fixing in NetworkManager. I opened https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/687 for that. Thanks @poettering for elaborating. Makes sense. IMO this issue can be closed. |
Fixes: systemd#17588 systemd#17512 Prompted-by: systemd#17529 (Also relevant: systemd#6076)
Fixes: systemd#17588 systemd#17512 Prompted-by: systemd#17529 (Also relevant: systemd#6076)
|
I put together some docs in #17678 that rehash what was discussed here, and extend a bit on it (i.e. there's also focus on reverse domain lookup, i.e. corporate VPNs should probably add some |
Fixes: systemd#17588 systemd#17512 Prompted-by: systemd#17529 (Also relevant: systemd#6076)
WireGuard's
wg-quick(8)utility uses the resolvconf interface to manage DNS servers in a cross-platform manner. It uses the-xoption so that DNS queries are sent only to the specified servers on an interface and not to other servers. The invocation is something like:When this was added years ago, I was under the impression that it worked, but recently Fedora 33 users have reported that systemd-resolved strangely sends queries both out of the WireGuard interface/dns-servers AND out of the plaintext ethernet interface, leaking DNS queries into the clear. For many, that's a quasi-serious privacy and/or security issue.
I went and tested this to confirm the bug reports on a fresh Fedora 33 VM. The servers get added to systemd-resolved correctly (checked with resolvectl), but queries are still sent out of the plaintext interface:
The text was updated successfully, but these errors were encountered: