Hey Ken, ma 21.4.2025 klo 1.42 Ken Milmore (ken.milm...@gmail.com) kirjoitti: > > Package: dhcpcd-base > Version: 1:10.1.0-9 > > Description: > > When using dhcpcd-base together with systemd-resolved, the name server > settings for an interface are initially configured correctly from DHCP but > may then subsequently disappear, leaving no DNS server configured. > > This is because the dhcpcd hook scripts contain support for resolvconf, but > the implementation of resolvconf provided by systemd-resolved is very limited > and does not support the full semantics required (see below). > > > > Steps to Reproduce: > > 1. Install systemd-resolved (257.5-2) along with dhcpcd-base (1:10.1.0-9) and > ifupdown (0.8.44) > > 2. Configure an interface for DHCP in /etc/network/interfaces. > As an example I am using a usermode (slirp) interface in QEMU: > > allow-hotplug enp1s0 > iface enp1s0 inet dhcp > > 3. Reboot, or restart the interface with ifdown/ifup. > > 4. Observe the DNS server configuration with resolvectl, repeating a few > minutes later. > > > > Expected Behaviour: > > resolvectl should show the DNS server address configured by DHCP. Name > resolution should work. > > > > Observed Behaviour: > > Shortly after the interface is brought up, resolvectl does indeed show that a > DNS server has been configured, e.g.: > > Global > Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported > resolv.conf mode: stub > > Link 2 (enp1s0) > Current Scopes: DNS > Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS > DNSSEC=no/unsupported > Current DNS Server: 172.17.2.3 > DNS Servers: 172.17.2.3 > Default Route: yes > > > But a few minutes later, the server seems to have disappeared again and DNS > is no longer working: > > Global > Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported > resolv.conf mode: stub > > Link 2 (enp1s0) > Current Scopes: none > Protocols: -DefaultRoute -LLMNR -mDNS -DNSOverTLS > DNSSEC=no/unsupported > Default Route: no > > > > Investigation: > > Turning on the debug option for dhcpcd shows a number of hook script calls > after the interface has been configured, e.g: > > Apr 20 21:07:36 redacted ifup[1015]: enp1s0: executing: > /usr/lib/dhcpcd/dhcpcd-run-hooks PREINIT > Apr 20 21:07:36 redacted dhcpcd[1015]: enp1s0: executing: > /usr/lib/dhcpcd/dhcpcd-run-hooks PREINIT > Apr 20 21:07:36 redacted ifup[1015]: enp1s0: executing: > /usr/lib/dhcpcd/dhcpcd-run-hooks NOCARRIER > Apr 20 21:07:36 redacted dhcpcd[1015]: enp1s0: executing: > /usr/lib/dhcpcd/dhcpcd-run-hooks NOCARRIER > Apr 20 21:07:36 redacted ifup[1015]: enp1s0: executing: > /usr/lib/dhcpcd/dhcpcd-run-hooks CARRIER > Apr 20 21:07:36 redacted dhcpcd[1015]: enp1s0: executing: > /usr/lib/dhcpcd/dhcpcd-run-hooks CARRIER > Apr 20 21:07:39 redacted ifup[1015]: enp1s0: executing: > /usr/lib/dhcpcd/dhcpcd-run-hooks ROUTERADVERT > Apr 20 21:07:39 redacted dhcpcd[1015]: enp1s0: executing: > /usr/lib/dhcpcd/dhcpcd-run-hooks ROUTERADVERT > Apr 20 21:07:41 redacted ifup[1015]: enp1s0: executing: > /usr/lib/dhcpcd/dhcpcd-run-hooks BOUND > Apr 20 21:07:41 redacted dhcpcd[1015]: enp1s0: executing: > /usr/lib/dhcpcd/dhcpcd-run-hooks BOUND > Apr 20 21:12:20 redacted dhcpcd[1015]: enp1s0: executing: > /usr/lib/dhcpcd/dhcpcd-run-hooks ROUTERADVERT > Apr 20 21:21:56 redacted dhcpcd[1015]: enp1s0: executing: > /usr/lib/dhcpcd/dhcpcd-run-hooks ROUTERADVERT > Apr 20 21:28:29 redacted dhcpcd[1015]: enp1s0: executing: > /usr/lib/dhcpcd/dhcpcd-run-hooks ROUTERADVERT > > Examining the hook script /usr/lib/dhcpcd/dhcpcd-hooks/20-resolv.conf, shows > that when a resolvconf binary is present, each hook call will ultimately > invoke resolvconf to add or delete the DNS settings for a particular protocol > on the interface. This results in a series of invocations such as the > following: > > resolvconf -d enp1s0.dhcp -f > resolvconf -d enp1s0.link -f > resolvconf -d enp1s0.link -f > resolvconf -d enp1s0.ra -f > resolvconf -a enp1s0.dhcp (with a resolv.conf-formatted file piped to > stdin) > resolvconf -d enp1s0.ra -f > > This is where the difference in semantics becomes apparent between the > versions of Debian resolvconf/openresolv and the resolvconf provided by > systemd-resolved: > > The "traditional" resolvconf maintains a separate state for each protocol on > the interface, and generates a superposition of the information from all > protocols. By contrast, the systemd version ignores the protocol suffix > completely and stores a single state for all protocols. The last information > supplied for any protocol typically wins out. > > In the particular example above, it appears that an IPv6 router advertisement > for "enp1s0.ra" has deleted the DNS configuration previously set for > "enp1s0.ra". I expect that various other sequences of events may lead to a > similar result. > > > > Possible Solutions: > > I attach a patch which modifies the dhcpcd hook scripts to work around the > problem: We detect when the systemd version of resolvconf is being used and > provide it with a resolv.conf fragment that contains the superposition of all > the protocols on a given interface (retrieved from state stored under > /run/dhcpcd). > > I have not tested the patch extensively, although it has worked well enough > in my test cases. > > Note that the ifupdown and isc-dhcp-client packages already have a their own > hook scripts (borrowed from Ubuntu) for dealing with systemctl-resolved. > These scripts call resolvectl to set the DNS servers, and there is a shared > state that is maintained by both packages so they are to some extent > integrated together. Since dhcpcd has now replaced isc-dhcp-client as the > default DHCP client for trixie, this integration now seems to be rather > pointless. See as follows: > > https://sources.debian.org/src/ifupdown/0.8.44/debian/if-up.d/resolved/ > https://sources.debian.org/src/isc-dhcp/4.4.3-P1-7/debian/resolved/ > > > > Remarks: > > It seems to me that the need for all these hacky hook scripts has come about > because systemd's implementation of resolvconf is too limited to be of use as > a drop-in replacement for resolvconf with the various "legacy" networking > packages. Rather than propagating these bespoke workarounds into different > packages, it may be better if they could all continue to use the > "traditional" resolvconf/openresolv system to configure resolved. > > I think this could be accomplished fairly cleanly and easily if the > systemd-resolved package were to simply omit installing the "resolvconf" > symbolic link, and drop the "Provides: resolvconf" and "Conflicts: > resolvconf" dependences, allowing it to be installed alongside the > "traditional" resolvconf. At the same time, resolvconf/openresolv could be > equipped with a unified hook script to detect systemd-resolved and call > resolvectl. Then all the hacks elsewhere could go away! > > If anyone can suggest a better forum to raise that wider issue then please > let me know and I will do so.
Thanks for this bug report and very thorough analysis. Can you submit a report upstream and link to this bug? https://github.com/NetworkConfiguration/dhcpcd/issues/new Martin-Éric