Flatcar icon indicating copy to clipboard operation
Flatcar copied to clipboard

/etc/resolv.conf should point to /run/systemd/resolve/stub-resolv.conf

Open f0o opened this issue 4 years ago • 10 comments

Current situation currently /etc/resolv.conf points to /run/systemd/resolve/resolv.conf which basically merges all DNS entries from all links and configs into 1 file regardless of hierarchy, caching, routing or other settings.

Impact Routed Domains become inherently unsupported as well as systemd-resolved's caching and other advanced features

Ideal future situation By using /run/systemd/resolve/stub-resolv.conf you effectively use systemd-resolved's stub resolver which leverages all features including caching and routed domains instead.

Implementation options ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

Additional information NOTE: Docker/Rkt will need to point to a different resolv.conf (namely /run/systemd/resolve/resolv.conf) as the stubresolver does not exist for containers. This is in accordance to the documentation (systemd+docker).

f0o avatar Dec 04 '20 15:12 f0o

Thanks for creating the ticket, yes, the default /etc/resolv.conf is not using 127.0.0.53 because it may get propagated into another network namespace where an separate loopback interface exists. Most non-container programs on the host will be using the /etc/nsswitch.conf where adding hosts: … resolve [!UNAVAIL=return] dns myhostname would be enough to make it use systemd-resolved directly without going through /etc/resolve.conf. I think trying out if that breaks something is the best solution because your proposed change will also just make non-container programs use systemd-resolved but with the additional loopback connection which is not needed with the proper /etc/nsswitch.conf entry.

pothos avatar Dec 04 '20 16:12 pothos

If that's the sole reason then why not skip resolved? There's no necessity as networkd will propagate /etc/resolv.conf by itself if I remember right.

Right now we employ resolved and have it consume resources but do not use any part of it whatsoever as we default to the discouraged /run/systemd/resolve/resolv.conf file.

docker, rkt & containerd are systemd-resolved aware and will switch by themselves to /run/systemd/resolve/resolv.conf instead of /run/systemd/resolve/stub-resolv.conf (even if symlinked) so containerized applications are not an issue.

when you say namespaced, do you mean manually ip ns'd programs? if so then I would put that burden on those users/maintainers as they seem to know what they're doing if they deviate from containers and run their own network-isolation

f0o avatar Dec 04 '20 16:12 f0o

You are right, we can try it if all parts are ready and we call it out as breaking change. Nevertheless I think it would be good to first get nsswitch.conf to use resolved directly since, at least on the first look, that it doesn't do it right now which surprises me. Fixing that would address the initial issues you stated.

pothos avatar Dec 04 '20 16:12 pothos

~~For nss-switch there might be https://www.freedesktop.org/software/systemd/man/nss-resolve.html as option. Untested but I can run a quick portage run and see what happens~~

Turns out /usr/lib64/libnss_systemd.so.2 already exists, let's test nsswitch's config

Update:

# /etc/nsswitch.conf:

passwd:      files usrfiles sss systemd
shadow:      files usrfiles sss
group:       files usrfiles sss systemd

hosts:       mymachines resolve [!UNAVAIL=return] files myhostname dns
networks:    files usrfiles dns

services:    files usrfiles
protocols:   files usrfiles
rpc:         files usrfiles

ethers:      files
netmasks:    files
netgroup:    files
bootparams:  files
automount:   files
aliases:     files

Seems to work as expected. However tools that dont support nsswitch (ironically docker uses /etc/resolv.conf when pulling/pushing) will still use the non-stub resolv.conf and thus not use any of the routed-domain settings (or caching, ...)

f0o avatar Dec 04 '20 16:12 f0o

I will submit a PR to the baselayout with the nsswitch changes

f0o avatar Dec 04 '20 17:12 f0o

I would like to keep this issue open despite the merge as the fundamental issue is still the same. I agree that having nsswitch working with systemd is a step in the right direction but ideally we should have all parties using resolved and not a patchwork like it is now.

f0o avatar Dec 04 '20 17:12 f0o

Ok opened 3 PRs, One is for keeping the current status-quo regarding /etc/resolv.conf and only deals with nsswitch labelled as partial fix. It does not change the behavior of namespaced applications as they still rely on /etc/resolv.conf.

The other 2 PRs are for the Full fix, which mean re-enabling stub-resolver and changing the symlink back to it.

Those are potentially breaking changes as the changes are more severe and can come as unexpected if the application relies heavily on /etc/resolv.conf and isn't a container by docker/rkt/containerd/podman.

All 3 PRs together would fully leverage systemd-resolved from all angles (nsswitch + resolv.conf)

f0o avatar Dec 04 '20 17:12 f0o

Great, thank you so much, I'll run some tests, too, when the changes look good.

pothos avatar Dec 04 '20 18:12 pothos

For the record, the symlink /etc/resolv.conf was not switched yet because kublet/coredns don't detect the symlink and that they should use /run/systemd/resolve/resolv.conf for the container (or use host network namespace, or some other trick like setting up port forwarding).

pothos avatar Feb 23 '21 14:02 pothos

Here a workaround to use systemd-resolved from any container (that takes /etc/resolv.conf without checking if it's a symlink to the stub) through a hack (systemd does not directly allow using the "external" IP address in the resolve.conf instead of 127.0.0.53):

/etc/systemd/network/10-resolve.netdev:

[NetDev]
Name=resolve
Kind=dummy

/etc/systemd/network/10-resolve.network (assuming you don't use the 192.0.2.254/32 address somewhere else):

[Match]
Name=resolve
[Link]
RequiredForOnline=no
[Address]
Address=192.0.2.254/32
Scope=host
[Network]
DHCP=no
LinkLocalAddressing=no

/etc/systemd/system/use-systemd-resolved.service (here is the hack part):

[Unit] 
Description=Workaround to have /etc/resolv.conf pointing to systemd-resolved but still be useable for the Kubelet/CoreDNS
PartOf=systemd-resolved.service
After=systemd-resolved.service
[Service]
Type=simple
Restart=always
RestartSec=1s
ExecStart=/bin/sh -c "while true; do sed -i 's/127.0.0.53/192.0.2.254/g' /run/systemd/resolve/stub-resolv.conf; ln -fs /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf; sleep 1; done"
[Install]
RequiredBy=systemd-resolved.service

Then do networkctl reload, systemctl restart systemd-resolved, systemctl enable --now use-systemd-resolved.service

pothos avatar Jan 28 '22 15:01 pothos