tailscale/net/dns/resolvconf-workaround.sh
Will Norris 71029cea2d all: update copyright and license headers
This updates all source files to use a new standard header for copyright
and license declaration.  Notably, copyright no longer includes a date,
and we now use the standard SPDX-License-Identifier header.

This commit was done almost entirely mechanically with perl, and then
some minimal manual fixes.

Updates #6865

Signed-off-by: Will Norris <will@tailscale.com>
2023-01-27 15:36:29 -08:00

63 lines
2.2 KiB
Bash

#!/bin/sh
# Copyright (c) Tailscale Inc & AUTHORS
# SPDX-License-Identifier: BSD-3-Clause
#
# This script is a workaround for a vpn-unfriendly behavior of the
# original resolvconf by Thomas Hood. Unlike the `openresolv`
# implementation (whose binary is also called resolvconf,
# confusingly), the original resolvconf lacks a way to specify
# "exclusive mode" for a provider configuration. In practice, this
# means that if Tailscale wants to install a DNS configuration, that
# config will get "blended" with the configs from other sources,
# rather than override those other sources.
#
# This script gets installed at /etc/resolvconf/update-libc.d, which
# is a directory of hook scripts that get run after resolvconf's libc
# helper has finished rewriting /etc/resolv.conf. It's meant to notify
# consumers of resolv.conf of a new configuration.
#
# Instead, we use that hook mechanism to reach into resolvconf's
# stuff, and rewrite the libc-generated resolv.conf to exclusively
# contain Tailscale's configuration - effectively implementing
# exclusive mode ourselves in post-production.
set -e
if [ -n "$TAILSCALE_RESOLVCONF_HOOK_LOOP" ]; then
# Hook script being invoked by itself, skip.
exit 0
fi
if [ ! -f tun-tailscale.inet ]; then
# Tailscale isn't trying to manage DNS, do nothing.
exit 0
fi
if ! grep resolvconf /etc/resolv.conf >/dev/null; then
# resolvconf isn't managing /etc/resolv.conf, do nothing.
exit 0
fi
# Write out a modified /etc/resolv.conf containing just our config.
(
if [ -f /etc/resolvconf/resolv.conf.d/head ]; then
cat /etc/resolvconf/resolv.conf.d/head
fi
echo "# Tailscale workaround applied to set exclusive DNS configuration."
cat tun-tailscale.inet
if [ -f /etc/resolvconf/resolv.conf.d/base ]; then
# Keep options and sortlist, discard other base things since
# they're the things we're trying to override.
grep -e 'sortlist ' -e 'options ' /etc/resolvconf/resolv.conf.d/base || true
fi
if [ -f /etc/resolvconf/resolv.conf.d/tail ]; then
cat /etc/resolvconf/resolv.conf.d/tail
fi
) >/etc/resolv.conf
if [ -d /etc/resolvconf/update-libc.d ] ; then
# Re-notify libc watchers that we've changed resolv.conf again.
export TAILSCALE_RESOLVCONF_HOOK_LOOP=1
exec run-parts /etc/resolvconf/update-libc.d
fi