Skip to content

Commit a21cc3b

Browse files
committed
resolvectl: initial suport for it
resolvconf as supplied by systemd-resolved doesn't work with different programs or protocols suppling dns for the same interface. This new subscriber allows openresolv to be installed as resolvconf and still allows systemd-resolved to work fine. Any resolvconf entries that cannot be matched to an interface are emitted as a warning on update - this is a systemd-resolved limitation. If you are beholden to it, use something else! You may want to consider setting resolv_conf=/dev/null in /etc/resolvconf.conf to avoid resolvconf stamping on the systemd-resolved /etc/resolv.conf file.
1 parent 24e41c6 commit a21cc3b

File tree

3 files changed

+95
-1
lines changed

3 files changed

+95
-1
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ libc
99
named
1010
pdnsd
1111
pdns_recursor
12+
resolvectl
1213
unbound
1314

1415
avahi-daemon

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ DOCMODE?= 0644
2424
MANMODE?= 0444
2525

2626
RESOLVCONF= resolvconf resolvconf.8 resolvconf.conf.5
27-
SUBSCRIBERS= libc dnsmasq named pdnsd pdns_recursor unbound
27+
SUBSCRIBERS= libc dnsmasq named pdnsd pdns_recursor resolvectl unbound
2828
LIBC_SUBSCRIBERS= avahi-daemon mdnsd
2929
TARGET= ${RESOLVCONF} ${SUBSCRIBERS} ${LIBC_SUBSCRIBERS}
3030
SRCS= ${TARGET:C,$,.in,} # pmake

resolvectl.in

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#!/bin/sh
2+
# Copyright (c) 2007-2025 Roy Marples
3+
# All rights reserved
4+
5+
# resolvectl subscriber for resolvconf
6+
7+
# Redistribution and use in source and binary forms, with or without
8+
# modification, are permitted provided that the following conditions
9+
# are met:
10+
# * Redistributions of source code must retain the above copyright
11+
# notice, this list of conditions and the following disclaimer.
12+
# * Redistributions in binary form must reproduce the above
13+
# copyright notice, this list of conditions and the following
14+
# disclaimer in the documentation and/or other materials provided
15+
# with the distribution.
16+
#
17+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21+
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
29+
# If we don't have resolvectl or systemd-resolved isn't running then
30+
# we can't do much.
31+
if ! [ -d /sys/class/net ] || \
32+
! type resolvectl >/dev/null 2>&1 || \
33+
! pidof systemd-resolved >/dev/null
34+
then
35+
exit 0
36+
fi
37+
38+
# resolved only accepts resolv.conf setup per physical interface
39+
# although resolvconf has always hinted that the named configuration
40+
# should be $interface.$protocol, this has never been a fixed requirement
41+
cd /sys/class/net
42+
for IFACE in *; do
43+
if [ "$IFACE" = lo ]; then
44+
# resolved doesn't work with lo
45+
continue
46+
fi
47+
48+
IFACES=
49+
for IFACE_PROTO in $(resolvconf -i "$IFACE" "$IFACE.*" 2>/dev/null); do
50+
# ens5 will work with ens5.dhcp and ens5.ra,
51+
# but not ens5.5 or ens5.5.dhcp
52+
if [ "${IFACE_PROTO%.*}" = "$IFACE" ]; then
53+
IFACES="$IFACES${IFACES:+ }$IFACE_PROTO"
54+
fi
55+
done
56+
if [ -z "$IFACES" ]; then
57+
resolvectl revert "$IFACE"
58+
continue
59+
fi
60+
61+
# Set the default-route property first to avoid leakage
62+
if [ "$(resolvconf -i $IFACES)" = "$(resolvconf -p $IFACES)" ]; then
63+
resolvectl default-route "$IFACE" false
64+
else
65+
resolvectl default-route "$IFACE" true
66+
fi
67+
68+
# Now set domain and dns
69+
DOMAIN=$(resolvconf -l $IFACES 2>/dev/null | sed -n -e "s/domain //p" -e "s/search //p")
70+
NS=$(resolvconf -l $IFACES 2>/dev/null | sed -n -e "s/nameserver //p")
71+
if [ -n "$DOMAIN" ]; then
72+
resolvectl domain "$IFACE" $DOMAIN
73+
else
74+
resolvectl domain "$IFACE" ""
75+
fi
76+
if [ -n "$NS" ]; then
77+
resolvectl dns "$IFACE" $NS
78+
else
79+
resolvectl dns "$IFACE" ""
80+
fi
81+
done
82+
83+
# warn about resolv.conf with no matching interface
84+
FAILED=
85+
for IFACE_PROTO in $(resolvconf -i); do
86+
IFACE="${IFACE_PROTO%.*}"
87+
if ! [ -d "/sys/class/net/$IFACE" ] || [ "$IFACE" = lo ]; then
88+
FAILED="$FAILED${FAILED:+ }$IFACE_PROTO"
89+
fi
90+
done
91+
if [ -n "$FAILED" ]; then
92+
echo "Could not apply resolv.conf to resolvectl: $FAILED" >&2
93+
fi

0 commit comments

Comments
 (0)