Fixing wg-quick's DNS= directive with a hatchet
Jason A. Donenfeld
Jason at zx2c4.com
Sat Oct 28 04:24:08 CEST 2017
On Sat, Oct 28, 2017 at 12:06 AM, Daniel Kahn Gillmor
<dkg at fifthhorseman.net> wrote:
> fwiw, i'm *not* ok with resolvconf. I tried to help co-maintain it for
> several years and stepped back from it in disappointment. I don't even
> remember the details at this point, but I'm not convinced that it's
> particularly architecturally sound. I haven't looked at openresolv
Rightfully so: Debian's resolvconf is junk and really should be
removed from the distro. Roy Marples, the openresolv guy, tried to fix
the situation a while back, but for whatever reason the maintainer of
the Debian one didn't follow through, and we are where we are today.
Openresolv is a fine piece of code that works reliably; I'd encourage
you to check it out, especially before you dismiss the whole idea and
start recommending dbus instead. It's a tiny component where you can
see all of its parts as clear transparent components. Many apps can
interact with it through a consistent mechanism. It doesn't require a
daemon, nor does it require any central management. Every distribution
has adopted the resolvconf method -- except for Redhat land, where
they have different ideas about things (NetworkManager,
dhclient-script) -- and I think it's mostly a historical accident and
maintenance oversight that Debian wound up with the butchered one.
Fortunately that should be somewhat easy to fix.
For this reason, I've gravitated strongly in favor of your suggestion
on IRC: support resolvconf, be it the debian frankenstein or the
openresolv one, and have distributions that don't have resolvconf
figure out something else within their package. At some point, maybe
Redhat will come around, or every other distribution will come around
to Redhat, and then we'll converge, but for now, with basically one
camp out, it seems easiest to just punt the problem to that one camp,
where the hatchet hopefully will be a sufficient stop-gap measure for
them (unless they come up with something better).
> I personally think that the hatchet is an unfortunate distraction from
> wireguard. If Jason decides to ship it upstream, i'll include it in the
> debian packages as part of his decision. However, i suspect it will
> break some people's DNS resolution in ways that they don't know how to
> recover from besides a reboot (maybe it'll come back after a reboot too?
For this reason, and at Kalin's suggestion as the first reply on the
thread, I prefix this onto resolv.conf with the hatchet:
# This file was generated by wg-quick(8) for use with
# the WireGuard interface wg0. It cannot be
# removed or altered directly. You may remove this file
# by running `wg-quick down wg0', or if that
# poses problems, run `umount /etc/resolv.conf'.
Not perfect, of course, but I imagine this simple comment will address
85% of confused users very quickly.
> hijacked an important system configuration file out from under whatever
> was maintaining it in the first place.
When you set DNS=, you expect for that configuration file to be
modified, but then put back how it was when things are turned off.
That's why mount points, resolvconf, and so forth present a
"stackable" interface. This is what Debian has long provided with the
integration between resolvconf and openvpn, even.
Of the current methods an options available, I see three
possibilities, with one of them being obviously unacceptable to me,
and this unacceptability should shed light on how I'm approaching the
1) Use openresolv, which supports -x, and if it isn't there, fall back
to the hatchet, which emulates openresolv's -x.
2) Use openresolv, which supports -x, and if it isn't there, fall back
to Debian resolvconf, which doesn't support -x, and if it isn't there,
fall back to the hatchet, which emulates -x.
3) Use openresolv, which supports -x, and if it isn't there, fall back
to Debian resolvconf, which doesn't support -x.
It might be a surprise to you to learn that (2) is actually the
unacceptable option! The reason is that I will hedge my bets on the
hatchet if it's for the purpose of making unified semantic behavior of
the DNS= option, with regards to -x. This to me is a worthy goal that
would justify such things. Thus, allowing for the hatchet in the same
setting where I'd allow for the incorrect behavior of Debian's missing
-x option is inconsistent and therefore indefensible.
This, then, leaves (1) and (3). The reason for (1) has already been
stated: to enable consistant -x behavior everywhere. The reasons for
going with (3), instead, would be some of the points you brought up on
IRC, in your email, and some additional ones too:
a) Messing with mount points is heavy handed and potentially confusing.
b) The application should choose *one* good mechanism for setting the
DNS, choosing the mechanism that's most widely supported, and punting
the issue to distributions if they don't have that mechanism available
to them. The reason is that the rabbit hole of supporting _every
possible DNS configuration ability_ is vast and horrible, and things
should be stopped before they slide this way.
c) Calling resolvconf is extremely simple to do, and something called
wg-"quick" should only contain pieces of logic that are simple.
d) The hatchet can be provided on a case by case basis as a patch by
distributions who are unable to provide a desired level of
e) By not being pedantic about the fact that Debian's resolvconf
doesn't support -x, I remind users that avoiding extratunnicular leaks
is better achieved with something like https://א.cc/KXez5GRr (taken
from the man page of wg-quick(8)), rather than trying to whack-a-mole
with things like -x DNS configuration.
f) The current "tun." prefix hack to simultaneously work with Debian's
resolvconf and openresolv is "good enough".
g) I'm not keen on the escalating arms race that the hatchet causes
when it's included in upstream software -- will programs add code to
do a stat(2) followed by an inode comparison and then run umount(2),
when open(2) returns -EROFS? I don't think this arms race concern
follows through to downstream distros, though, since they're usually
more agile with removing these things before they become a problem, if
they're becoming one.
Of these, I'm most compelled by (c), (e), and (f).
> you asked me to set up the DNS but i only know how to do that with
> openresolv installed. Please install openresolv and try again!
So, based on the above, my intention is to do this, but in the context
of option (3), which means I'll only warn if there's no resolvconf,
permitting Debian's resolvconf to provide its limited support if it's
there and openresolv isn't.
> As for what the right solution looks like on a modern GNU/Linux system:
> A sensible approach (which i think should be the default on machines
> running systemd) is to use systemd-resolved as a local resolving cache.
> If your networking is configured by systemd-networkd, then everything
> else JustWorks™
It really doesn't "just work" (and systemd-networkd is mostly for
servers, but not for dynamically changing "desktop linux" machines,
due to a currently very limited external interface into it). As you
said, systemd-resolved not on by default in distros, which means
people have to likely change their whole networking situation to use
it. (When it is ubiquitous, perhaps things can be reconsidered.) More
importantly, the dbus interface to interact with it is not pleasant.
This deserves a line break:
I don't want to manually construct dbus messages from bash.
I think resolvconf is the right interface for DNS configuration. I
understand that systemd-resolved doesn't want to manage things with
files -- because they wish to integrate deeper with NSS and
multi-machine tenancy and so forth, which are all interesting projects
-- but I still think resolvconf, as a command line program, is the
right interface for ad-hoc things to configure DNS. For this reason, I
filed this issue with systemd --
https://github.com/systemd/systemd/issues/7202 -- and I'll be curious
to hear their take on it. Maybe they'll provide an interesting new
perspective, or just confirm this one.
More information about the WireGuard