Create /etc/resolv.conf in initramfs for tailscale client

On Debian systems, unless configured by something else, there isn't an
/etc/resolv.conf in the initramfs, which hinders DNS resolution.
Tailscale has its fallback DNS functionality, but that has problems [1]
in the corner-case situation of a Debian initramfs environment:

- no /etc/resolv.conf means tailscale (or golang?) attempts to use
  127.0.0.1 as a DNS resolver
- the loopback interface (lo) isn't brought up in the initramfs. linux
  sends the DNS traffic off-device (destined for 127.0.0.1)

Even with the Tailscale fix for that issue, it's a fallback and there's
a noticeable delay, so do the correct thing here and create
/etc/resolv.conf.

[1] https://github.com/tailscale/tailscale/issues/6110
This commit is contained in:
Paul Aurich
2023-05-03 19:43:14 -07:00
parent 166df1dd88
commit 564c3c3539
3 changed files with 51 additions and 1 deletions

View File

@@ -43,6 +43,18 @@ TAILSCALE_AUTHKEY=
#
#TAILSCALE_LOGOUT=
#
# Space-delimited list of DNS server(s) to put in /etc/resolv.conf in the
# initramfs if /etc/resolv.conf doesn't exist and if no DNS servers were
# returned from DHCP.
#
# Tailscale will eventually fall back to bootstrapping DNS itself, but there's
# no reason to rely on that (adds a slight delay). Tailscale's fallback is
# also problematic in some corner cases in some versions (see
# https://github.com/tailscale/tailscale/issues/6110).
#
#FALLBACK_DNS_SERVERS=
#
# Bring down interfaces matching this pattern before passing out of the
# initramfs. (Same behavior as dropbear-initramfs)

7
debian/changelog vendored
View File

@@ -1,3 +1,10 @@
tailscale-initramfs (0.3) unstable; urgency=medium
* Configure resolv.conf in initramfs if it isn't already, so the tailscale
client can reach the control server more reliably.
-- Paul Aurich <paul@darkrain42.org> Wed, 03 May 2023 19:52:49 -0700
tailscale-initramfs (0.2) unstable; urgency=medium
* Keep trying to bring up the network until it either comes up or the boot

View File

@@ -39,12 +39,39 @@ network_up()
{
for conf in /run/net-*.conf /run/net6-*.conf; do
if [ -e "$conf" ]; then
# shellcheck disable=SC1090
. "$conf"
return 0
fi
done
return 1
}
# shellcheck disable=SC3043
create_resolv_conf()
{
if [ -e /etc/resolv.conf ]; then
return
fi
local ns
for ns in "${IPV4DNS0:-}" "${IPV4DNS1:-}" "${IPV6DNS0:-}" "${IPV6DNS1:-}"; do
if [ -n "$ns" ] && [ "$ns" != "0.0.0.0" ]; then
echo "nameserver $ns" >> /etc/resolv.conf
fi
done
if [ -e /etc/resolv.conf ]; then
return
fi
for ns in ${FALLBACK_DNS_SERVERS:-}; do
if [ -n "$ns" ]; then
echo "nameserver $ns" >> /etc/resolv.conf
fi
done
}
# shellcheck disable=SC2039,SC2086,SC3043
run_tailscale()
{
@@ -62,7 +89,11 @@ run_tailscale()
# in a subshell and wait for it.
configure_networking &
wait $!
if ! [ -e "$PIDFILE" ] || network_up; then
if ! [ -e "$PIDFILE" ]; then
break
fi
if network_up; then
create_resolv_conf
break
fi
done