wg-quick: openbsd: set DNS with resolvd(8)

OpenBSD has introduced a new daemon named resolvd(8) to manage
resolv.conf. This creates problems with the old "horrible way" of
completely replacing resolv.conf. Resolvd will attempt to merge manual
changes with DNS servers discovered through dhcpleased(8) and slaacd(8).
Unfortunately, resolvd puts any manual modifications at the end of
resolv.conf, meaning that the wg-quick name servers will be queried
last.

The process for handling multiple name servers (at least with libc) is
to try a name server, and if the query times out, try the next, until
out of name servers, then repeat trying all name servers until a maximum
number of retries are performed. The name servers are queried in the
order listed in resolv.conf and the timeout is 5 seconds.

With this patch, we ensure the wg-quick name server is first in
resolv.conf (as route creates the name server with "static" priority),
but cannot ensure it is exclusive. Therfore, it may be possible that
queries are leaked to other name servers if the wg-quick name server
doesn't respond within 5 seconds.

We have another problem however, and that is if resolvd detects unwind
is running, it will set 127.0.0.1 as the only name server in
resolv.conf. unwind does not have deterministic name server selection in
the default configuration.  This means, all a user would need to do to
inadvertently cause persistent query leaks would be to run `rcctl enable
unwind`.

There are warnings added when these situations may occur.

The next step is to add an exclusive flag and search to route and
resolvd.

Reported-by: Matthieu Herrb <matthieu@herrb.eu>
Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Matt Dunwoodie 2021-09-07 21:48:53 +10:00 committed by Jason A. Donenfeld
parent af260d529e
commit 84ac6add7e
1 changed files with 14 additions and 4 deletions

View File

@ -283,15 +283,25 @@ monitor_daemon() {
set_dns() {
[[ ${#DNS[@]} -gt 0 ]] || return 0
# TODO: this is a horrible way of doing it. Has OpenBSD no resolvconf?
# TODO: add exclusive support for nameservers
if pgrep -qx unwind; then
echo "[!] WARNING: unwind will leak DNS queries" >&2
elif pgrep -qx resolvd; then
echo "[!] WARNING: resolvd may leak DNS queries" >&2
else
echo "[+] resolvd is not running, DNS will not be configured" >&2
return 0
fi
cmd cp /etc/resolv.conf "/etc/resolv.conf.wg-quick-backup.$INTERFACE"
{ cmd printf 'nameserver %s\n' "${DNS[@]}"
[[ ${#DNS_SEARCH[@]} -eq 0 ]] || cmd printf 'search %s\n' "${DNS_SEARCH[*]}"
} > /etc/resolv.conf
[[ ${#DNS_SEARCH[@]} -eq 0 ]] || cmd printf 'search %s\n' "${DNS_SEARCH[*]}" > /etc/resolv.conf
route nameserver ${REAL_INTERFACE} ${DNS[@]}
}
unset_dns() {
[[ -f "/etc/resolv.conf.wg-quick-backup.$INTERFACE" ]] || return 0
route nameserver ${REAL_INTERFACE}
cmd mv "/etc/resolv.conf.wg-quick-backup.$INTERFACE" /etc/resolv.conf
}