Skip to content
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(8) compat interface #8296

Merged
merged 2 commits into from Mar 12, 2018
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -612,7 +612,7 @@ manpages = [
'ENABLE_RANDOMSEED'],
['systemd-rc-local-generator', '8', [], ''],
['systemd-remount-fs.service', '8', ['systemd-remount-fs'], ''],
['systemd-resolve', '1', [], 'ENABLE_RESOLVE'],
['systemd-resolve', '1', ['resolvconf'], 'ENABLE_RESOLVE'],
['systemd-resolved.service', '8', ['systemd-resolved'], 'ENABLE_RESOLVE'],
['systemd-rfkill.service',
'8',
@@ -47,7 +47,8 @@

<refnamediv>
<refname>systemd-resolve</refname>
<refpurpose>Resolve domain names, IPV4 and IPv6 addresses, DNS resource records, and services</refpurpose>
<refname>resolvconf</refname>
<refpurpose>Resolve domain names, IPV4 and IPv6 addresses, DNS resource records, and services; introspect and reconfigure the DNS resolver</refpurpose>
</refnamediv>

<refsynopsisdiv>
@@ -134,6 +135,18 @@
<command> --revert</command>
</cmdsynopsis>

<cmdsynopsis>
<command>resolvconf</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<command> -a <replaceable>INTERFACE</replaceable> &lt; <replaceable>FILE</replaceable></command>
</cmdsynopsis>

<cmdsynopsis>
<command>resolvconf</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<command> -d <replaceable>INTERFACE</replaceable></command>
</cmdsynopsis>

</refsynopsisdiv>

<refsect1>
@@ -399,6 +412,82 @@
</variablelist>
</refsect1>

<refsect1>
<title>Compatibility with <citerefentry><refentrytitle>resolvconf</refentrytitle><manvolnum>8</manvolnum></citerefentry></title>

This comment has been minimized.

Copy link
@keszybz

keszybz Feb 27, 2018

Member

I think this also needs an entry in the synopsis.


<para><command>systemd-resolve</command> is a multi-call binary. When invoked as <literal>resolvconf</literal>
(generally achieved by means of a symbolic link of this name to the <command>systemd-resolve</command> binary) it
is run in a limited <citerefentry><refentrytitle>resolvconf</refentrytitle><manvolnum>8</manvolnum></citerefentry>
compatibility mode. It accepts mostly the same arguments and pushes all data into
<citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
similar to how <option>--set-dns=</option> and <option>--set-domain=</option> operate. Note that
<command>systemd-resolved.service</command> is the only supported backend, which is different from other
implementations of this command. Note that not all operations supported by other implementations are supported
natively. Specifically:</para>

<variablelist>
<varlistentry>
<term><option>-a</option></term>
<listitem><para>Registers per-interface DNS configuration data with
<command>systemd-resolved</command>. Expects a network interface name as only command line argument. Reads
<citerefentry><refentrytitle>resolv.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> compatible DNS
configuration data from its standard input. Relevant fields are <literal>nameserver</literal> and
<literal>domain</literal>/<literal>search</literal>. This command is mostly identical to invoking
<command>systemd-resolve</command> with a combination of <option>--set-dns=</option> and
<option>--set-domain=</option>.</para></listitem>
</varlistentry>

<varlistentry>
<term><option>-d</option></term>
<listitem><para>Unregisters per-interface DNS configuration data with <command>systemd-resolved</command>. This
command is mostly identical to invoking <command>systemd-resolve</command> with
<option>--revert</option>.</para></listitem>
</varlistentry>

<varlistentry>
<term><option>-f</option></term>

<listitem><para>When specified <option>-a</option> and <option>-d</option> will not complain about missing
network interfaces and will silently execute no operation in that case.</para></listitem>
</varlistentry>

<varlistentry>
<term><option>-x</option></term>

<listitem><para>This switch for "exclusive" operation is supported only partially. It is mapped to an
additional configured search domain of <literal>~.</literal> — i.e. ensures that DNS traffic is preferably
routed to the DNS servers on this interface, unless there are other, more specific domains configured on other
interfaces.</para></listitem>
</varlistentry>

<varlistentry>
<term><option>-m</option></term>
<term><option>-p</option></term>

<listitem><para>These switches are not supported and are silently ignored.</para></listitem>
</varlistentry>

<varlistentry>
<term><option>-u</option></term>
<term><option>-I</option></term>
<term><option>-i</option></term>
<term><option>-l</option></term>

This comment has been minimized.

Copy link
@zx2c4

zx2c4 Feb 28, 2018

Contributor

Would you consider supporting -l [interface]? The information and logic to support it is easily available, and so it wouldn't be cumbersome to support. This is used by wg-quick(8) to (optionally) save the active runtime configuration when deleting the interface.

This comment has been minimized.

Copy link
@poettering

poettering Feb 28, 2018

Author Member

I think providing the API for 3rd party tools to hook into is priority, and I figure that's mostly -a and -d. OTOH -l is mostly user-facing, and we do have "systemd-resolve --status" covering that already (and without the skewedness because resolved's and resolvconf's concept don't match 100%).

That said, I think we can totally add support for that later on, if people want that (and apparently they do, as you have just shown). But I think it's just the cherry on top, and not not necessary to make the basic functionality work.

Or to say this differently: a PR adding support for that on top of this once it's merged would be very welcome!

This comment has been minimized.

Copy link
@zx2c4

zx2c4 Feb 28, 2018

Contributor

Indeed the other program supports many things too, but the point of having resolvconf in the first place is to maintain compatibility with scripts, just like shutdown and the rest. wg-quick(8) won't be growing support for a cornucopia of different DNS management invocations, preferring instead to use a single API (resolvconf). It's just a shell script after all.

You can see its usage of -l here: https://git.zx2c4.com/WireGuard/tree/src/tools/wg-quick.bash#n194

But I think it's just the cherry on top, and not necessary to make the basic functionality work.

It's certainly required to make wg-quick(8) work, rather than being a mere cherry.

This comment has been minimized.

Copy link
@poettering

poettering Feb 28, 2018

Author Member

note that "-l" is only supported by openresolv, btw, it's not available in the original Debian implementation.

This comment has been minimized.

Copy link
@poettering

poettering Feb 28, 2018

Author Member

Hmm, that script uses -m 0 -x btw, which isn't in the debian implementation. It appears the script only works with openresolv.

What confuses me a bit is this line in that script:

resolvconf -a "tun.$INTERFACE" -m 0 -x

The interface argument is reversed: According to the manpages you are supposed to specified the interface first, and the protocol second. i.e. it should be $INTERFACE.tun and not tun.$INTERFACE. (Oh, and I think it would be more expressive if you'd use "wguard or so instead of "tun" as protocol ID).

This comment has been minimized.

Copy link
@poettering

poettering Feb 28, 2018

Author Member

See these two links regarding Debian's own implementation of the script, and the one from "openresolv". Debian packages both interestingly:

https://manpages.debian.org/stretch/resolvconf/resolvconf.8.en.html
https://manpages.debian.org/stretch/openresolv/resolvconf.8.en.html

The FreeBSD version is even different:

https://www.freebsd.org/cgi/man.cgi?query=resolvconf&sektion=8

This comment has been minimized.

Copy link
@poettering

poettering Feb 28, 2018

Author Member

I figure if you want to be compatible with Debian's, openresolv's and FreeBSD's implementation you'd have to rewrite your command line to use this syntax:

IF_METRIC=0 IF_EXCLUSIVE=1 resolvconf -a $INTERFACE.wireguard <

That line also does the right thing with the implementation provided by this PR, as it also honours the IF_EXCLUSIVE command line arguments.

And I fear that the "-l" thing you can't use if you care about general Debian compatibility.

This comment has been minimized.

Copy link
@zx2c4

zx2c4 Feb 28, 2018

Contributor

Actually those arguments are silently ignored, which is why, I assume, they're also ignored on systemd. This allows us to keep compat on both.

We're then doing the tun. prefix hack do that the interface is ordered on top, as Debian's uses a fixed order based on interface prefix. This simulates the -m 0 behavior, though we're out on -x. I hadn't seen those environment variables before and I wonder if they're new. I'll take a look and add those in, since they importantly won't do harm on other implementations.

The take away is that since Debian turns unknown instructions into no-ops, we can support multiple ones at the same time.

This comment has been minimized.

Copy link
@zx2c4

zx2c4 Feb 28, 2018

Contributor

FreeBSD uses openresolv, by the way.

This comment has been minimized.

Copy link
@poettering

poettering Feb 28, 2018

Author Member

Actually those arguments are silently ignored, which is why, I assume, they're also ignored on systemd.

are they? i just checked out the resolvconf upstream git repo, and if i run the command there with -x it will say "resolvconf: Error: Command not recognized" and refuse operation. I don't think -x and -m works on the Debian resolvconv. Hence if you want to communicate the metric or exclusive mode to resolvconf where it's supported then you have to go the env var way

This comment has been minimized.

Copy link
@poettering

poettering Feb 28, 2018

Author Member

We're then doing the tun. prefix hack do that the interface is ordered on top, as Debian's uses a fixed order based on interface prefix.

Uh, but that's against the documentation, and I am pretty sure will break various backend implementations that actually care that the interface name you specify is valid. I mean, the original resolvconf exists precisely to allow multiple backends, no? If you use it on top of classic bind, then the interface name needs to be parsable properly, as one exaple.

The compat implementation of this PR also expects that the interface name is valid. It will generate an error if it isn't.

This comment has been minimized.

Copy link
@poettering

poettering Feb 28, 2018

Author Member

FreeBSD uses openresolv, by the way.

I think it's based on it, yes, but it deviates, has new options and the file locations are all different.

This comment has been minimized.

Copy link
@zx2c4

zx2c4 Feb 28, 2018

Contributor

I think it's based on it, yes,

That man page you linked explicitly mentions openresolv, anyhow.

This comment has been minimized.

Copy link
@zx2c4

zx2c4 Feb 28, 2018

Contributor

are they? i just checked out the resolvconf upstream git repo, and if i run the command there

I'm reading this source: https://anonscm.debian.org/cgit/resolvconf/resolvconf.git/tree/bin/resolvconf

The key is to make -x the second argument, not the first. Then you avoid the error message and have future compatibility with openresolv.

This comment has been minimized.

Copy link
@zx2c4

zx2c4 Feb 28, 2018

Contributor

The compat implementation of this PR also expects that the interface name is valid. It will generate an error if it isn't.

Ahh, okay, that could be problematic, then, unless what you're saying about IF_EXCLUSIVE is actually true in current versions, in which case, I wouldn't need the tun. prefix hack. I can't find that, though:

zx2c4@thinkpad /tmp $ git clone https://anonscm.debian.org/cgit/resolvconf/resolvconf.git
Cloning into 'resolvconf'...
remote: Counting objects: 3635, done.
remote: Compressing objects: 100% (1474/1474), done.
remote: Total 3635 (delta 2510), reused 3044 (delta 2125)
Receiving objects: 100% (3635/3635), 598.85 KiB | 3.09 MiB/s, done.
Resolving deltas: 100% (2510/2510), done.
zx2c4@thinkpad /tmp/resolvconf $ grep -ri IF_EXCLUSIVE
zx2c4@thinkpad /tmp/resolvconf $ 

That seems to be, rather, an openresolv option, not a Debian one.


Anyway, I've just committed this: https://git.zx2c4.com/WireGuard/commit/?id=92320b60b6d85dc13a1932079366465569683b1e So hopefully the strict naming requirements of systemd should now be satisfied.

This comment has been minimized.

Copy link
@zx2c4

zx2c4 Feb 28, 2018

Contributor

note that "-l" is only supported by openresolv, btw, it's not available in the original Debian implementation.

https://git.zx2c4.com/WireGuard/commit/?id=6ed55dec679b2aaa36b4170632cdc510475fc310

So, it might be a good idea for systemd to support the modern interface for this instead of the old Debian cruft.

<term><option>-R</option></term>
<term><option>-r</option></term>
<term><option>-v</option></term>
<term><option>-V</option></term>
<term><option>--enable-updates</option></term>
<term><option>--disable-updates</option></term>
<term><option>--are-updates-enabled</option></term>

<listitem><para>These switches are not supported and the command will fail if used.</para></listitem>
</varlistentry>

</variablelist>

<para>See <citerefentry><refentrytitle>resolvconf</refentrytitle><manvolnum>8</manvolnum></citerefentry> for details on this command line options.</para>
</refsect1>

<refsect1>
<title>Examples</title>

@@ -477,7 +566,8 @@ _443._tcp.fedoraproject.org IN TLSA 0 0 1 19400be5b7a31fb733917700789d2f0a2471c0
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.dnssd</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
<citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>resolvconf</refentrytitle><manvolnum>8</manvolnum></citerefentry>

This comment has been minimized.

Copy link
@keszybz

keszybz Mar 1, 2018

Member

We'll probably need to make this optional, since people install systemd into their root file system and might not want to overwrite their installed resolvconf. But this can be done later.

</para>
</refsect1>
</refentry>
@@ -1632,6 +1632,10 @@ if conf.get('ENABLE_RESOLVE') == 1
install_rpath : rootlibexecdir,
install : true)
public_programs += [exe]

meson.add_install_script(meson_make_symlink,
join_paths(bindir, 'systemd-resolve'),
join_paths(rootsbindir, 'resolvconf'))

This comment has been minimized.

Copy link
@keszybz

keszybz Mar 1, 2018

Member

That doesn't make much sense to cross from rootsbindir to bindir. resolvconf is in /sbin on Ubuntu/Debian, sp the second argument has to use rootsbindir. We can either say "who cares" and live with the fact that we'll have a dangling symlink until /usr is mounted, or move systemd-resolve to /bin. I don't care either way, maybe people who use split-usr can chime in?

@mbiebl, @martinpitt, does /sbin/resolvconf need to be usable before /usr is mounted?

This comment has been minimized.

Copy link
@xnox

xnox Mar 2, 2018

Member

@keszybz on the systems that boot with systemd, our initramfs insures that /usr is mounted. So no. But there are things that use resolvconf state in the initramfs and hope that it will be transfered into the root filesystem, post initramfs. I have not yet checked, but it would be extra nice if there is e.g. path&service unit combos that process /run/resolvconf/interface/$IFACE files on boot. I didn't read all of the pull request, to check if this is done or not.

This comment has been minimized.

Copy link
@poettering

poettering Mar 2, 2018

Author Member

no, we only provide command line compat with openresolv and debian's resolvconf, nothing else.

that said, if you run resolved in the initrd (which should be safe now) it should pass on its data 1:1 without isses to the main system

endif

if conf.get('ENABLE_LOGIND') == 1
@@ -80,7 +80,12 @@ systemd_resolved_sources = files('''
resolved-etc-hosts.c
'''.split())

systemd_resolve_sources = files('resolve-tool.c')
systemd_resolve_sources = files('''
resolvconf-compat.c
resolvconf-compat.h
resolve-tool.c
resolve-tool.h
'''.split())

############################################################

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.