9.16.x: listen-on-v6 { any; }; no longer works as documented on FreeBSD
Summary
In 9.14.x running on FreeBSD, 'listen-on-v6 { any; )' functions as documented in the ARM:
When { any; } is specified as the address_match_list for the listen-on-v6 option, the server does not bind a separate socket to each IPv6 interface address as it does for IPv4 if the operating system has enough API support for IPv6 (specifically if it conforms to RFC 3493 and RFC 3542). Instead, it listens on the IPv6 wildcard address. If the system only has incomplete API support for IPv6,however, the behavior is the same as that for IPv4.
In 9.16.x, it does not function as documented.
9.14.x:
root@devns1:~ # fgrep listen-on-v6 /etc/namedb/named.conf
listen-on-v6 { any; };
root@devns1:~ # sockstat | grep named
bind named 44277 3 dgram -> /var/run/logpriv
bind named 44277 21 tcp6 *:53 *:*
bind named 44277 23 tcp4 127.0.0.1:53 *:*
bind named 44277 24 tcp4 127.0.0.1:953 *:*
bind named 44277 25 tcp6 ::1:953 *:*
bind named 44277 512 udp6 *:53 *:*
bind named 44277 514 udp4 127.0.0.1:53 *:*
9.16.1 (also verified on 9.16.2):
root@devns1:~ # fgrep listen-on-v6 /etc/namedb/named.conf
listen-on-v6 { any; };
root@devns1:~ # sockstat | grep named
bind named 617 27 udp6 ::1:53 *:*
bind named 617 28 tcp6 ::1:53 *:*
bind named 617 29 tcp6 ::1:53 *:*
bind named 617 30 udp6 fe80::1%lo0:53 *:*
bind named 617 31 tcp6 fe80::1%lo0:53 *:*
bind named 617 32 tcp6 fe80::1%lo0:53 *:*
bind named 617 33 udp4 127.0.0.1:53 *:*
bind named 617 34 tcp4 127.0.0.1:53 *:*
bind named 617 35 tcp4 127.0.0.1:53 *:*
bind named 617 36 tcp4 127.0.0.1:953 *:*
bind named 617 37 tcp6 ::1:953 *:*
BIND version used
9.16.2 exhibits the bug:
BIND 9.16.2 (Stable Release) <id:b310dc7>
running on FreeBSD amd64 11.3-RELEASE-p7 FreeBSD 11.3-RELEASE-p7 #0: Tue Mar 17 08:32:23 UTC 2020 root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC
built by make with '--disable-linux-caps' '--localstatedir=/var' '--sysconfdir=/usr/local/etc/namedb' '--with-dlopen=yes' '--with-libxml2' '--with-openssl=/usr/local' '--with-readline=-L/usr/local/lib -ledit' '--with-dlz-filesystem=yes' '--disable-dnstap' '--disable-fixed-rrset' '--disable-geoip' '--without-maxminddb' '--without-gssapi' '--with-libidn2=/usr/local' '--with-json-c' '--disable-largefile' '--with-lmdb=/usr/local' '--disable-native-pkcs11' '--without-python' '--disable-querytrace' 'STD_CDEFINES=-DDIG_SIGCHASE=1' '--enable-tcp-fastopen' '--with-tuning=default' '--disable-symtable' '--prefix=/usr/local' '--mandir=/usr/local/man' '--infodir=/usr/local/share/info/' '--build=amd64-portbld-freebsd11.3' 'build_alias=amd64-portbld-freebsd11.3' 'CC=cc' 'CFLAGS=-O2 -pipe -DLIBICONV_PLUG -fstack-protector-strong -isystem /usr/local/include -fno-strict-aliasing ' 'LDFLAGS= -L/usr/local/lib -ljson-c -Wl,-rpath,/usr/local/lib -fstack-protector-strong ' 'LIBS=-L/usr/local/lib' 'CPPFLAGS=-DLIBICONV_PLUG -isystem /usr/local/include' 'CPP=cpp' 'PKG_CONFIG=pkgconf'
compiled by CLANG 4.2.1 Compatible FreeBSD Clang 8.0.0 (tags/RELEASE_800/final 356365)
compiled with OpenSSL version: OpenSSL 1.1.1f 31 Mar 2020
linked to OpenSSL version: OpenSSL 1.1.1f 31 Mar 2020
compiled with libxml2 version: 2.9.10
linked to libxml2 version: 20910
compiled with json-c version: 0.13.1
linked to json-c version: 0.13.1
compiled with zlib version: 1.2.11
linked to zlib version: 1.2.11
threads support is enabled
default paths:
named configuration: /usr/local/etc/namedb/named.conf
rndc configuration: /usr/local/etc/namedb/rndc.conf
DNSSEC root key: /usr/local/etc/namedb/bind.keys
nsupdate session key: /var/run/named/session.key
named PID file: /var/run/named/pid
named lock file: /var/run/named/named.lock
Steps to reproduce
- System running FreeBSD 11.3-RELEASE or 12.1-RELEASE.
- Install BIND916 either from ports (with default options).
- Create an lo1 interface with (an) IPv6 address(es). We use lo1 for the service addresses of our anycast instances.
ifconfig lo1 down
- Start named with a basic recursive or authoritative config, with
listen-on-v6 { any; };
configured. -
sockstat | grep named
. named will not be listening on the wildcard -nor- on the IPv6 addresses configured on lo1. This is because FreeBSD supports Enhanced DAD on all interfaces and marks all v6 addresses as 'tentative' until the interface comes up. ifconfig lo1 up
-
sockstat | grep named
. named is still not listening on lo1's IPv6 addresses. - Attempt to query the server on the IPv6 address on lo1. It will time out.
rndc scan
- repeat steps 8 and 9. Still not listening on the lo1 addresses and not responding.
- RESTART named. It is now listening on the new lo1 addresses.
With 9.14.x, queries to the new address do not time out because named is properly listening on the wildcard.
WORKAROUND:
ifconfig lo1 no_dad
. This disables DAD processing on the loopback (not clear why you need it there anyway) and clears the tentative
flag even if lo1 is down. named will listen explicitly on the IPv6 addresses whether lo1 is marked "UP" or "DOWN." Note that this does not work reliably on FreeBSD 11.3-RELEASE, but does work on 12.1-RELEASE.