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

Reply via email to