Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package openresolv for openSUSE:Factory checked in at 2025-07-10 22:11:26 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/openresolv (Old) and /work/SRC/openSUSE:Factory/.openresolv.new.7373 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "openresolv" Thu Jul 10 22:11:26 2025 rev:9 rq:1291526 version:3.17.0 Changes: -------- --- /work/SRC/openSUSE:Factory/openresolv/openresolv.changes 2025-05-13 20:07:14.767313664 +0200 +++ /work/SRC/openSUSE:Factory/.openresolv.new.7373/openresolv.changes 2025-07-10 22:11:27.273983546 +0200 @@ -1,0 +2,9 @@ +Sat Jul 5 14:43:42 UTC 2025 - Andrea Manzini <andrea.manz...@suse.com> + +- update to 3.17.0: + * libc: only change resolv.conf if the signature matches + * resolvconf: -I now inits subscribers after clearing state + * resolvconf.8: resolvconf -I should be called during early boot + * resolvconf: remember if any subscriber errored + +------------------------------------------------------------------- Old: ---- openresolv-3.16.3.tar.xz openresolv-3.16.3.tar.xz.asc New: ---- openresolv-3.17.0.tar.xz openresolv-3.17.0.tar.xz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ openresolv.spec ++++++ --- /var/tmp/diff_new_pack.zPfKvR/_old 2025-07-10 22:11:27.870008336 +0200 +++ /var/tmp/diff_new_pack.zPfKvR/_new 2025-07-10 22:11:27.870008336 +0200 @@ -17,7 +17,7 @@ Name: openresolv -Version: 3.16.3 +Version: 3.17.0 Release: 0 Summary: DNS management framework License: BSD-2-Clause ++++++ openresolv-3.16.3.tar.xz -> openresolv-3.17.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openresolv-3.16.3/.gitignore new/openresolv-3.17.0/.gitignore --- old/openresolv-3.16.3/.gitignore 2025-05-09 15:00:01.000000000 +0200 +++ new/openresolv-3.17.0/.gitignore 2025-06-26 11:59:34.000000000 +0200 @@ -9,6 +9,7 @@ named pdnsd pdns_recursor +resolvectl systemd-resolved unbound diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openresolv-3.16.3/Makefile new/openresolv-3.17.0/Makefile --- old/openresolv-3.16.3/Makefile 2025-05-09 15:00:01.000000000 +0200 +++ new/openresolv-3.17.0/Makefile 2025-06-26 11:59:34.000000000 +0200 @@ -24,7 +24,8 @@ MANMODE?= 0444 RESOLVCONF= resolvconf resolvconf.8 resolvconf.conf.5 -SUBSCRIBERS= libc dnsmasq named pdnsd pdns_recursor systemd-resolved unbound +SUBSCRIBERS= libc dnsmasq named pdnsd pdns_recursor unbound +SUBSCRIBERS+= systemd-resolved resolvectl LIBC_SUBSCRIBERS= avahi-daemon mdnsd TARGET= ${RESOLVCONF} ${SUBSCRIBERS} ${LIBC_SUBSCRIBERS} SRCS= ${TARGET:C,$,.in,} # pmake diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openresolv-3.16.3/libc.in new/openresolv-3.17.0/libc.in --- old/openresolv-3.16.3/libc.in 2025-05-09 15:00:01.000000000 +0200 +++ new/openresolv-3.17.0/libc.in 2025-06-26 11:59:34.000000000 +0200 @@ -34,9 +34,18 @@ if [ ! -d "$KEYDIR" ] && [ -d "$VARDIR/interfaces" ]; then KEYDIR="$VARDIR/interfaces" fi + +CMD="$1" +KEY="$2" + NL=" " +warn() +{ + echo "$(basename $0): $*" >&2 +} + # sed may not be available, and this is faster on small files key_get_value() { @@ -113,7 +122,6 @@ resolv_conf_tail="$(cat "$SYSCONFDIR"/resolv.conf.tail)" fi -backup=true signature="# Generated by resolvconf" uniqify() @@ -131,7 +139,6 @@ case "${resolv_conf_passthrough:-NO}" in [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) - backup=false newest= for conf in "$KEYDIR"/*; do if [ -z "$newest" ] || [ "$conf" -nt "$newest" ]; then @@ -139,7 +146,7 @@ fi done [ -z "$newest" ] && exit 0 - newconf="$(cat "$newest")$NL" + newconf="$signature$NL$(cat "$newest")$NL" ;; /dev/null|[Nn][Uu][Ll][Ll]) : ${resolv_conf_local_only:=NO} @@ -215,13 +222,18 @@ # Check if the file has actually changed or not if [ -e "$resolv_conf" ]; then - [ "$(cat "$resolv_conf")" = "$(printf %s "$newconf")" ] && exit 0 -fi - -# If the old file does not have our signature, back it up. -if $backup && [ -e "$resolv_conf" ] && [ ! -e "$resolv_conf.bak" ]; then + if [ "$CMD" != u ] && \ + [ "$(cat "$resolv_conf")" = "$(printf %s "$newconf")" ] + then + exit 0 + fi read line <"$resolv_conf" if [ "$line" != "$signature" ]; then + if [ "$CMD" != u ]; then + warn "signature mismatch: $resolv_conf" + warn "run \`resolvconf -u\` to update" + exit 1 + fi cp "$resolv_conf" "$resolv_conf.bak" fi fi @@ -230,6 +242,8 @@ # instead of a temporary file and then moving it over. # The default is to write to resolv.conf as it has the least # issues and has been the long standing default behaviour. +# resolv.conf could also be bind mounted for network namespaces +# so we cannot move in this instance. case "${resolv_conf_mv:-NO}" in [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) # Protect against symlink attack, ensure new file does not exist diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openresolv-3.16.3/resolvconf.8.in new/openresolv-3.17.0/resolvconf.8.in --- old/openresolv-3.16.3/resolvconf.8.in 2025-05-09 15:00:01.000000000 +0200 +++ new/openresolv-3.17.0/resolvconf.8.in 2025-06-26 11:59:34.000000000 +0200 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 30, 2025 +.Dd June 26, 2025 .Dt RESOLVCONF 8 .Os .Sh NAME @@ -78,6 +78,14 @@ then updates .Pa /etc/resolv.conf as it thinks best. +If +.Pa /etc/resolv.conf +already exists and the top line does not match the expected signature, +then +.Nm +will refuse to update it unless the +.Fl u +update command is given. When a local resolver other than libc is installed, such as .Xr dnsmasq 8 or @@ -111,20 +119,6 @@ .Nm . .Pp .Nm -assumes it has a job to do. -In some situations -.Nm -needs to act as a deterrent to writing to -.Pa /etc/resolv.conf . -Where this file cannot be made immutable or you just need to toggle this -behaviour, -.Nm -can be disabled by adding -.Sy resolvconf Ns = Ns NO -to -.Xr resolvconf.conf 5 . -.Pp -.Nm can mark a .Pa resolv.conf as private and optionally non-searchable. @@ -154,7 +148,7 @@ with .Fl d Ar key arguments to clean up the -.Pa resol.conf +.Pa resolv.conf it added previously. For systems that support the concept of persisting configuration when the source is suspended, @@ -170,7 +164,7 @@ .Pa resolv.conf entries are processed. .Pp -Here are some options for the above commands:- +Here are some options for the above commands: .Bl -tag -width pattern_opt .It Fl f Ignore non existent @@ -205,7 +199,7 @@ .El .Pp .Nm -has some more commands for general usage:- +has some more commands for general usage: .Bl -tag -width pattern_opt .It Fl i Op Ar pattern List the keys stored, optionally matching @@ -248,19 +242,15 @@ .Pp .Nm also has some commands designed to be used by its subscribers and -system startup:- +system startup: .Bl -tag -width pattern_opt .It Fl I Initialise the state directory .Pa @VARDIR@ . -This only needs to be called if the initial system boot sequence does not -automatically clean it out; for example the state directory is moved -somewhere other than -.Pa /var/run . -If used, it should only be called once as early in the system boot sequence -as possible and before -.Nm -is used to add entries. +This should be called after the base state directory has either been +cleaned out or mounted as a memory backed filesystem during the +initial boot sequence before any daemon has the chance to call +.Nm . .It Fl R Echo the command used to restart a service. .It Fl r Ar service diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openresolv-3.16.3/resolvconf.conf.5.in new/openresolv-3.17.0/resolvconf.conf.5.in --- old/openresolv-3.16.3/resolvconf.conf.5.in 2025-05-09 15:00:01.000000000 +0200 +++ new/openresolv-3.17.0/resolvconf.conf.5.in 2025-06-26 11:59:34.000000000 +0200 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd May 8, 2025 +.Dd May 15, 2025 .Dt RESOLVCONF.CONF 5 .Os .Sh NAME @@ -73,7 +73,7 @@ .Va $keyword Ns / Ns Va $match Ns Op / Ns Va $keyword Ns / Ns Va $match .Pp For example given this configuration: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent exclude="search/foo*/nameserver/1.2.3.4 search/bar.org" .Ed .Pp @@ -82,13 +82,13 @@ .It Sy key_order These keys will always be processed first. If unset, defaults to the following: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent lo lo[0-9]* .Ed .It Sy dynamic_order These keys will be processed next, unless they have a metric. If unset, defaults to the following: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent tap[0-9]* tun[0-9]* vpn vpn[0-9]* wg[0-9]* ppp[0-9]* ippp[0-9]* .Ed .It Sy inclusive_keys @@ -98,7 +98,7 @@ option and you want to disable it easily. .It Sy local_nameservers If unset, defaults to the following: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent 127.* 0.0.0.0 255.255.255.255 ::1 .Ed .It Sy search_domains @@ -147,7 +147,7 @@ .Va $keyword Ns / Ns Va $match Ns / Ns Va $replacement .Pp Example, given this resolv.conf: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent domain foo.org search foo.org dead.beef nameserver 1.2.3.4 @@ -155,14 +155,14 @@ .Ed .Pp and this configuration: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent replace="search/foo*/bar.com" replace="$replace nameserver/1.2.3.4/5.6.7.8" replace="$replace nameserver/2.3.4.5/" .Ed .Pp you would get this resolv.conf instead: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent domain foo.org search bar.com nameserver 5.6.7.8 @@ -178,7 +178,7 @@ to .Sy replace_sub , you would get this resolv.conf instead: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent domain foo.org search bar.com dead.beef nameserver 5.6.7.8 @@ -220,6 +220,14 @@ .Nm is written to .Sy resolv_conf . +.It Sy resolv_conf_restore +When set to YES and +and an empty +.Pa resolv.conf +would be written, restore +.Pa resolv.conf.bak +instead if it exists. +Defaults to YES if not set. .It Sy resolv_conf_sortlist A libc resolver sortlist, as specified in .Xr resolv.conf 5 . @@ -259,7 +267,7 @@ To disable a subscriber, simply set its name to NO. If the subscriber name has a dash in it, then replace it with an underscore. For example, to disable the libc subscriber you would set: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent libc=NO .Ed .Bl -tag -width indent @@ -269,14 +277,14 @@ This file tells dnsmasq which name servers to use for global lookups. .Pp Example resolvconf.conf for dnsmasq: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent name_servers=127.0.0.1 dnsmasq_conf=/etc/dnsmasq-conf.conf dnsmasq_resolv=/etc/dnsmasq-resolv.conf .Ed .Pp Example dnsmasq.conf: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent listen-address=127.0.0.1 # If dnsmasq is compiled for DBus then we can take # advantage of not having to restart dnsmasq. @@ -292,14 +300,14 @@ This file tells named which name servers to use for specific domains. .Pp Example resolvconf.conf for named: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent name_servers=127.0.0.1 named_options=/etc/named-options.conf named_zones=/etc/named-zones.conf .Ed .Pp Example named.conf: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent options { listen-on { 127.0.0.1; }; include "/etc/named-options.conf"; @@ -320,14 +328,14 @@ .Pa pdnsd_conf . .Pp Example resolvconf.conf for pdnsd: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent name_servers=127.0.0.1 pdnsd_conf=/etc/pdnsd.conf # pdnsd_resolv=/etc/pdnsd-resolv.conf .Ed .Pp Example pdnsd.conf: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent global { server_ip = 127.0.0.1; status_ctl = on; @@ -343,24 +351,57 @@ This file tells pdns_recursor about specific and global name servers. .Pp Example resolvconf.conf for pdns_recursor: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent name_servers=127.0.0.1 pdns_zones=/etc/pdns/recursor-zones.conf .Ed .Pp Example recursor.conf: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent allow-from=127.0.0.0/8, ::1/128 forward-zones-file=/etc/pdns/recursor-zones.conf .Ed +.It Sy resolvectl +When set to YES, +.Xr resolvectl 1 +will be used to write per interface entries from +.Xr resolvconf 8 +to +.Xr systemd-resolved 8 . +A warning is emitted for any entry that cannot be matched to an +interface. +.Pp +This subscriber should only be used if your systemd-resolved does +not support DNS delegates and you need private or non searchable +.Xr resolvconf 8 +entries, or you're really beholden to seeing DNS setup per interface via +.Xr resolvectl 1 . +The systemd-resolved subscriber documented below is the better option. +.Pp +Example resolvconf.conf for resolvectl: +.Bd -literal -compact -offset indent +# Keep /etc/resolv.conf as systemd-resolved wants it +libc=NO +resolvectl=YES +.Ed +.It Sy systemd_resolved +When set to YES, global DNS will be written to the +.Sy systemd_resolved_conf +configuration file and DNS delegates will be written to the +.Sy systemd_delegate_dir +directory. .It Sy systemd_resolved_conf -This file tells systemd-resolved about global name servers. +Defaults to +.Pa /run/systemd/resolved.conf.d/60-resolvconf.conf . +.It Sy systemd_delegate_dir +Defaults to +.Pa /run/systemd/dns-delegate.d . .Pp Example resolvconf.conf for systemd-resolved: -.Bd -compact -literal -offset indent -name_servers=127.0.0.53 -resolv_conf_options="edns0 trust-ad" -systemd_resolved_conf=/run/systemd/resolved.conf.d/60-resolvconf.conf +.Bd -literal -compact -offset indent +# Keep /etc/resolv.conf as systemd-resolved wants it +libc=NO +systemd_resolved=YES .Ed .It Sy unbound_conf This file tells unbound about specific and global name servers. @@ -373,13 +414,13 @@ Each option should be separated by an embedded new line. .Pp Example resolvconf.conf for unbound: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent name_servers=127.0.0.1 unbound_conf=/etc/unbound-resolvconf.conf .Ed .Pp Example unbound.conf: -.Bd -compact -literal -offset indent +.Bd -literal -compact -offset indent include: /etc/unbound-resolvconf.conf .Ed .El @@ -433,5 +474,13 @@ Each distribution is a special snowflake and likes to name the same thing differently, namely the named service script. .Pp +Swapping between resolvectl and systemd-resolved subscribers at runtime +is not supported. +Files referenced by systemd_resolved_conf and systemd_delegate_dir +need to be removed by hand. +A reboot is recommended so that stale data is removed. +While you could run them both at the same time, only using one is the +recommended approach. +.Pp Please report them to .Lk https://roy.marples.name/projects/openresolv diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openresolv-3.16.3/resolvconf.in new/openresolv-3.17.0/resolvconf.in --- old/openresolv-3.16.3/resolvconf.in 2025-05-09 15:00:01.000000000 +0200 +++ new/openresolv-3.17.0/resolvconf.in 2025-06-26 11:59:34.000000000 +0200 @@ -25,7 +25,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. RESOLVCONF="$0" -OPENRESOLV_VERSION="3.16.3" +OPENRESOLV_VERSION="3.17.0" SYSCONFDIR=@SYSCONFDIR@ LIBEXECDIR=@LIBEXECDIR@ VARDIR=@VARDIR@ @@ -336,7 +336,7 @@ { OIFS="$IFS" IFS=/ - set -- "$@" + set -- $@ IFS="$OIFS" if [ -n "$1" ]; then printf %s . @@ -569,7 +569,7 @@ if [ "$list_cmd" = -i ] || [ "$list_cmd" = -l ]; then for i in $@; do if [ ! -f "$i" ]; then - if ! $force; then + if ! $force && [ "$i" != "*" ]; then echo "No resolv.conf for key $i" >&2 fi retval=2 @@ -1061,14 +1061,6 @@ fi fi -# -I inits the state dir -if [ "$cmd" = I ]; then - if [ -d "$VARDIR" ]; then - rm -rf "$VARDIR"/* - fi - exit $? -fi - # -D ensures that the listed config file base dirs exist if [ "$cmd" = D ]; then config_mkdirs "$@" @@ -1135,7 +1127,7 @@ error_exit "Key not specified" fi ;; -u) ;; +I|u) ;; *) if [ -n "$cmd" ] && [ "$cmd" != h ]; then error_exit "Unknown option $cmd" @@ -1364,7 +1356,7 @@ if $changedfile; then printf "%s\n" "$resolv" >"$KEYDIR/$key" || exit $? - elif ! $changed; then + elif ! $changed && [ ! -e "$VARDIR"/error ]; then exit 0 fi unset changed changedfile oldmetric newmetric x oldexcl @@ -1385,7 +1377,7 @@ "$EXCLUSIVEDIR/"*" $i" || exit $? done - if ! $changed; then + if ! $changed && [ ! -e "$VARDIR"/error ]; then # Set the return code based on the forced flag $force exit $? @@ -1404,7 +1396,9 @@ echo " " >"$i" || exit $? fi done - $changed || exit 0 + if ! $changed && [ ! -e "$VARDIR"/error ]; then + exit 0 + fi unset changed i ;; @@ -1419,10 +1413,22 @@ rm "$i" || exit $? fi done - $changed || exit 0 + if ! $changed && [ ! -e "$VARDIR"/error ]; then + exit 0 + fi unset changed i fi ;; +I) + # Init the state dir, keeping our lock and key directories only + for i in "$VARDIR"/*; do + case "$i" in + "$LOCKDIR") ;; + "$KEYDIR") rm -rf "$KEYDIR"/*;; + *) rm -rf "$i";; + esac + done + ;; esac case "${resolvconf:-YES}" in @@ -1461,5 +1467,9 @@ retval=$(($retval + $?)) fi done +if [ "$retval" = 0 ]; then + rm -f "$VARDIR"/error +else + echo "$retval" >"$VARDIR"/error +fi exit $retval - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openresolv-3.16.3/resolvectl.in new/openresolv-3.17.0/resolvectl.in --- old/openresolv-3.16.3/resolvectl.in 1970-01-01 01:00:00.000000000 +0100 +++ new/openresolv-3.17.0/resolvectl.in 2025-06-26 11:59:34.000000000 +0200 @@ -0,0 +1,159 @@ +#!/bin/sh +# Copyright (c) 2025 Roy Marples +# All rights reserved + +# resolvectl subscriber for resolvconf + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +[ -f "@SYSCONFDIR@"/resolvconf.conf ] || exit 0 +. "@SYSCONFDIR@/resolvconf.conf" || exit 1 + +case "${resolvectl:-NO}" in +[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) ;; +*) exit 0;; +esac + +# If we don't have resolvectl or systemd-resolved isn't running then +# we can't do much. +# We can't persist our data in /run/systemd/resolve/netif/$ifindex +# because systemd-resolved keeps it somehow, ie we can't change it +# once we have inserted it +if ! [ -d /sys/class/net ] || \ + ! type resolvectl >/dev/null 2>&1 || \ + ! pidof systemd-resolved >/dev/null +then + exit 1 +fi + +# resolvectl only accepts resolv.conf setup per physical interface +# although resolvconf has always hinted that the named configuration +# should be $interface.$protocol, this has never been a fixed requirement. +# Because resolvectl only accepts one configuration per interface we need +# to try and merge the resolv.conf's together. +# Luckily resolvconf makes this easy for us. + +# Returns a list of resolvconf entries for a real interface +get_resolvconf_interfaces() { + IFACE="$1" + [ -d /sys/class/net/"$IFACE" ] || return 1 + + IFACES= + for IFACE_PROTO in $(@SBINDIR@/resolvconf -Li "$IFACE" "$IFACE.*" 2>/dev/null); do + # ens5 will work with ens5.dhcp and ens5.ra, + # but not ens5.5 or ens5.5.dhcp + if [ "$IFACE_PROTO" != "$IFACE" ]; then + # Ensure that ens5.5.dhcp doesn't work for ens5 + if [ "${IFACE_PROTO%.*}" != "$IFACE" ]; then + continue + fi + # Ensure that ens5.dhcp isn't a real interface + # as ens5.5 likely is and the .5 matches the .dhcp + if [ -d /sys/class/net/"$IFACE_PROTO" ]; then + continue + fi + fi + IFACES="$IFACES${IFACES:+ }$IFACE_PROTO" + done + echo "$IFACES" +} + +# For the given interface, apply a list of resolvconf entries +apply_resolvconf() { + IFACE="$1" + shift + + if [ -z "$1" ]; then + resolvectl revert "$IFACE" + return + fi + + # Set the default-route property first to avoid leakage. + # If any entry is private, the whole interface has to be private. + # If a more granular approach is needed, consider using the + # systemd-resolved subscriber instead which supports DNS delegates. + if [ -n "$(@SBINDIR@/resolvconf -p $@)" ]; then + resolvectl default-route "$IFACE" false + else + resolvectl default-route "$IFACE" true + fi + + # Now set domain and dns + DOMAIN=$(@SBINDIR@/resolvconf -L $@ 2>/dev/null | sed -n -e "s/domain //p" -e "s/search //p") + NS=$(@SBINDIR@/resolvconf -L $@ 2>/dev/null | sed -n -e "s/nameserver //p") + if [ -n "$DOMAIN" ]; then + # If any entry is marked as not searchable, we mark all the + # domains as non searchable. + # If a more granular approach is needed, consider using the + # systemd-resolved subscriber instead which supports DNS delegates. + if [ -n "$(@SBINDIR@/resolvconf -pp $@)" ]; then + ND= + for d in $DOMAIN; do + ND="$ND${ND:+ }~$d" + done + DOMAIN="$ND" + fi + resolvectl domain "$IFACE" $DOMAIN + else + resolvectl domain "$IFACE" "" + fi + if [ -n "$NS" ]; then + resolvectl dns "$IFACE" $NS + else + resolvectl dns "$IFACE" "" + fi +} + +# To get the full features of resolvconf, we need to work out each interface +# for every resolvconf addition and deletion +# This is because resolvconf.conf might have changed OR an exclusive +# interface deleted which makes other interfaces visible. +cd /sys/class/net +for IFACE in *; do + if [ "$IFACE" = lo ]; then + # systemd-resolved doesn't work with lo + continue + fi + + IFACES=$(get_resolvconf_interfaces "$IFACE") + apply_resolvconf "$IFACE" $IFACES +done + +# warn about resolv.conf with no matching interface +FAILED= +for IFACE_PROTO in $(@SBINDIR@/resolvconf -Li); do + IFACE="${IFACE_PROTO%.*}" + if [ "$IFACE" = lo ]; then + # Don't warn about loopback interface as that is typically + # used to configure libc for a nameserver on it and the libc + # subscriber will process that just fine. + continue + fi + + if ! [ -d "/sys/class/net/$IFACE" ]; then + FAILED="$FAILED${FAILED:+ }$IFACE_PROTO" + fi +done +if [ -n "$FAILED" ]; then + echo "Could not apply resolv.conf to resolvectl: $FAILED" >&2 +fi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openresolv-3.16.3/systemd-resolved.in new/openresolv-3.17.0/systemd-resolved.in --- old/openresolv-3.16.3/systemd-resolved.in 2025-05-09 15:00:01.000000000 +0200 +++ new/openresolv-3.17.0/systemd-resolved.in 2025-06-26 11:59:34.000000000 +0200 @@ -28,49 +28,68 @@ [ -f "@SYSCONFDIR@"/resolvconf.conf ] || exit 0 . "@SYSCONFDIR@/resolvconf.conf" || exit 1 -[ -n "$systemd_resolved_conf" ] || exit 0 + +case "${systemd_resolved:-NO}" in +[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) ;; +*) exit 0;; +esac + [ -n "$RESOLVCONF" ] || eval "$(@SBINDIR@/resolvconf -v)" NL=" " -: ${resolved_delegate_dir:="/etc/systemd/dns-delegate"} +: ${systemd_resolved_conf:=/run/systemd/resolved.conf.d/60-resolvconf.conf} +: ${systemd_delegate_dir:=/run/systemd/dns-delegate.d} + +# Try to ensure that config dirs exist +if command -v config_mkdirs >/dev/null 2>&1; then + config_mkdirs "$systemd_resolved_conf" "$systemd_delegate_dir/x" +else + @SBINDIR@/resolvconf -D "$systemd_resolved_conf" "$systemd_delegate_dir/x" +fi header="# Generated by resolvconf$NL" -header="${conf}$NL" -header="${conf}[Resolve]$NL" +header="${header}$NL" +header="${header}[Resolve]$NL" conf="$header" # We emit blank values to force them to reset on SIGHUP conf="${conf}DNS=$NAMESERVERS$NL" # Indicate these nameservers are for all domain lookups by using ~. -conf="${conf}Domains=$SEARCH ~.$NL" +conf="${conf}Domains=$SEARCH${NAMESERVERS:+ ~.}$NL" -# Try to ensure that config dirs exist -if command -v config_mkdirs >/dev/null 2>&1; then - config_mkdirs "$systemd_resolved_conf" -else - @SBINDIR@/resolvconf -D "$systemd_resolved_conf" -fi +printf %s "$conf" >"$systemd_resolved_conf" -# Once https://github.com/systemd/systemd/issues/20485 is resolved, -# via https://github.com/systemd/systemd/pull/34368 -# we could put the domain nameservers as DNS Delegates like so: -#if command -v config_mkdirs >/dev/null 2>&1; then -# config_mkdirs "$resolved_delegate_dir/resolvconf" -#else -# @SBINDIR@/resolvconf -D "$resolved_delegate_dir/resolvconf" -#fi -#rm -f "$resolved_delegate_dir/resolvconf-"*".dns-delegate" -# XXX Test that removing delegate files unloads them from resolved via SIGHUP. -#for d in $DOMAINS; do -# dn="${d%%:*}" -# ns="${d#*:}" -# dconf="${header}Domains=~$dn$NL" -# dconf="${dconf}DNS=$ns$NL" -# printf %s "$dconf" >"$resolved_delegate_dir/resolvconf-$dn.dns-delegate" -#done +# DNS Delegates requires https://github.com/systemd/systemd/pull/34368 +rm -f "$systemd_delegate_dir/resolvconf-"*".dns-delegate" +header="# Generated by resolvconf$NL" +header="${header}$NL" +header="${header}[Delegate]$NL" +for d in $DOMAINS; do + dn="${d%%:*}" + ns="${d#*:}" + dconf="${header}Domains=" + search=false + for sd in $SEARCH; do + if [ "$sd" = "$dn" ]; then + search=true + break + fi + done + if ! $search; then + dconf="${dconf}~" + fi + dconf="${dconf}$dn$NL" + dconf="${dconf}DNS=" + while [ -n "$ns" ]; do + dconf="$dconf${ns%%,*} " + [ "$ns" = "${ns#*,}" ] && break + ns="${ns#*,}" + done + dconf="$dconf$NL" + printf %s "$dconf" >"$systemd_delegate_dir/resolvconf-$dn.dns-delegate" +done -printf %s "$conf" >"$systemd_resolved_conf" pid=$(pidof systemd-resolved) if [ -n "$pid" ]; then kill -HUP $pid