What’s the rationale behind the “–enable-prometheus-metrics” compile-time option? If this code were compiled by default, would it do any harm?
The reason I’m asking this is that features that can be enabled/disabled at compile-time make package distribution complicated. It can result in a scenario where NSD packages on different operating systems or distributions have different features. It’s especially confusing to an operator reading the “nsd.conf” man page, noticing the option “metrics-enable”, setting it to “yes” and discovering that it doesn’t work, because the feature isn’t compiled in.
Let’s take Homebrew as an example. My brew-installed nsd doesn’t have RRL compiled it, so even if I want to test it, I cannot. I have to download the sources and compile it. Now, my nsd.conf doesn’t mention RRL, because the source of the nsd.conf man page has “rrlstart” and “rrlend” markers, which probably allow the build process to leave out the RRL sections because the feature is not compiled in.
But I do not see any such markers for “metrics”. The nsd.conf.5 man page that is generated shows the “metrics-enable” option, but it’s not actually compiled in. It’s quite confusing.
Years ago, nsd used to have a compile-time option called “–enable-root-server”. This prevented a standard nsd build from being used as a root name server, unless one explicitly enabled it when compiling. I never liked this, and after some discussion, the nsd developers agreed with me that making it a default was fine.
I think that similarly, it is better if all of nsd’s features are just compiled in, so that a standard package just has them all available. The features should default to “off”, naturally. Operators can enable the features they need in the config file.
1. maybe not new: I like to have NSTATS/XSTATS get *not* logged. I've to use 'configure --disable-bind8-stats' for this.
Simply not using '--enable-bind8-stats' is not enough ...
Is the nsd.conf option 'statistics' still relevant if -disable-bind8-stats is used?
2. I agree with Anand that features should be better a configuration option rather then compile time option.
This change was heading to 4.12 but we pulled it because it was breaking software that implicitly sends the SOA probe over UDP.
Maybe a more lenient approach should be used, but the change needs more development time at the moment; not something that could be addressed for this release cycle.
I cannot imagine a scenario for any (resolver?) software to implicitly send a SOA probe over UDP to port 853 / not port 53
Could you clarify this, please?
There is also a difference to the same solution for that problem in unbound:
While "netstat -lnpu" does not show open UDP sockets for DoT and DoH on unbound, NSD is different:
"netstat -lnpu" shows an open Port for Do53 and DoT. Do53/UDP does timeout on Port 853, though.
It looks like #437 works very different the the code implemented in unbound.
this errors out on OpenBSD (which has libevent1 in base) thusly:
$ ./configure --enable-prometheus-metrics
[...]
checking for library containing evhttp_free... no
./configure: >&for : illegal file descriptor name
configure: error: is
Thanks,
Florian
$ ./configure --enable-prometheus-metrics
checking for gcc... no
checking for cc... cc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether the compiler supports GNU C... yes
checking whether cc accepts -g... yes
checking for cc option to enable C11 features... none needed
checking for stdio.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for strings.h... yes
checking for sys/stat.h... yes
checking for sys/types.h... yes
checking for unistd.h... yes
checking for wchar.h... yes
checking for minix/config.h... no
checking for vfork.h... no
checking whether it is safe to define __EXTENSIONS__... yes
checking whether _XOPEN_SOURCE should be defined... no
checking whether the compiler supports GNU C... (cached) yes
checking whether cc accepts -g... (cached) yes
checking for cc option to enable C11 features... (cached) none needed
checking for a sed that does not truncate output... /usr/bin/sed
checking for gawk... gawk
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for flex... flex
checking for lex output file root... lex.yy
checking for lex library... none needed
checking whether yytext is a pointer... yes
checking for bison... bison -y
checking whether ln -s works... yes
checking for a BSD-compatible install... /usr/bin/install -c
checking whether lex accepts -i... yes
checking if lex defines yy_current_buffer... no
checking whether cc supports -g... yes
checking whether cc supports -O2... yes
checking if cc supports -flto... yes
checking for an ANSI C-conforming const... yes
checking for inline... inline
checking for uid_t... yes
checking for gid_t... yes
checking for pid_t... yes
checking for size_t... yes
checking for off_t... yes
checking whether the C compiler (cc) accepts the "format" attribute... yes
checking whether the C compiler (cc) accepts the "unused" attribute... yes
checking whether the C compiler (cc) accepts the "weak" attribute... yes
checking whether the C compiler (cc) accepts the "noreturn" attribute... yes
checking if memcmp compares unsigned... yes
checking whether ctime_r works with two arguments... yes
checking for libevent... found in /usr/local
checking for library containing clock_gettime... none required
checking for event.h... yes
checking for cc options needed to detect all undeclared functions... -fno-builtin
checking whether EV_VERSION_MAJOR is declared... no
checking for library containing event_set... -levent
checking for event_base_free... yes
checking for event_base_once... yes
checking for event_base_new... yes
checking for event_base_get_method... yes
checking for ev_loop... no
checking for ev_default_loop... no
checking for sys/wait.h that is POSIX.1 compatible... yes
checking for time.h... yes
checking for arpa/inet.h... yes
checking for signal.h... yes
checking for string.h... (cached) yes
checking for strings.h... (cached) yes
checking for fcntl.h... yes
checking for limits.h... yes
checking for netinet/in.h... yes
checking for netinet/tcp.h... yes
checking for stddef.h... yes
checking for sys/param.h... yes
checking for sys/socket.h... yes
checking for sys/un.h... yes
checking for syslog.h... yes
checking for unistd.h... (cached) yes
checking for sys/select.h... yes
checking for stdarg.h... yes
checking for stdint.h... (cached) yes
checking for netdb.h... yes
checking for sys/bitypes.h... no
checking for tcpd.h... no
checking for glob.h... yes
checking for grp.h... yes
checking for endian.h... yes
checking for sys/random.h... no
checking for ifaddrs.h... yes
checking for double definition of struct va_list... no
checking whether strptime needs defines... no
checking for library containing inet_pton... none required
checking for library containing socket... none required
checking whether strptime works... yes
checking if nonblocking sockets work... yes
checking whether mkdir has one arg... no
checking how to run the C preprocessor... cc -E
checking for egrep -e... (cached) /usr/bin/grep -E
checking for int8_t... yes
checking for int16_t... yes
checking for int32_t... yes
checking for int64_t... yes
checking for uint8_t... yes
checking for uint16_t... yes
checking for uint32_t... yes
checking for uint64_t... yes
checking for socklen_t... yes
checking for sig_atomic_t... yes
checking for ssize_t... yes
checking for suseconds_t... yes
checking for in_addr_t... yes
checking for struct sockaddr_storage.ss_family... yes
checking for struct stat.st_mtimensec... yes
checking for struct stat.st_mtim.tv_nsec... yes
checking for struct sockaddr_un.sun_len... yes
checking build system type... x86_64-unknown-openbsd7.7
checking host system type... x86_64-unknown-openbsd7.7
checking for working chown... yes
checking for fork... yes
checking for vfork... yes
checking for working fork... yes
checking for working vfork... (cached) yes
checking for GNU libc compatible malloc... yes
checking for declarations of fseeko and ftello... yes
checking for cc option to enable large file support... none needed
checking size of void*... 8
checking size of off_t... 8
checking for getrandom... no
checking for arc4random... yes
checking for arc4random_uniform... yes
checking for library containing setusercontext... none required
checking for login_cap.h... yes
checking for tzset... yes
checking for alarm... yes
checking for chroot... yes
checking for dup2... yes
checking for endpwent... yes
checking for gethostname... yes
checking for memset... yes
checking for memcpy... yes
checking for pwrite... yes
checking for socket... yes
checking for strcasecmp... yes
checking for strchr... yes
checking for strdup... yes
checking for strerror... yes
checking for strncasecmp... yes
checking for strtol... yes
checking for writev... yes
checking for getaddrinfo... yes
checking for getnameinfo... yes
checking for freeaddrinfo... yes
checking for gai_strerror... yes
checking for sigaction... yes
checking for sigprocmask... yes
checking for strptime... yes
checking for strftime... yes
checking for localtime_r... yes
checking for setusercontext... yes
checking for glob... yes
checking for initgroups... yes
checking for setresuid... yes
checking for setreuid... yes
checking for setresgid... yes
checking for setregid... yes
checking for getpwnam... yes
checking for mmap... yes
checking for ppoll... yes
checking for clock_gettime... yes
checking for accept4... yes
checking for getifaddrs... yes
checking for struct mmsghdr... yes
checking for sched.h... yes
checking for sys/cpuset.h... no
checking for cpu_set_t... no
checking for cpuset_t... no
checking for cpuid_t... yes
checking for sched_setaffinity... no
checking for basename... yes
checking for inet_aton... yes
checking for inet_pton... yes
checking for inet_ntop... yes
checking for snprintf... yes
checking for strlcat... yes
checking for strlcpy... yes
checking for strptime... (cached) yes
checking for b64_pton... no
checking for b64_ntop... no
checking for pselect... yes
checking for memmove... yes
checking for setproctitle... yes
checking for explicit_bzero... yes
checking for reallocarray... yes
checking whether reallocarray is declared... yes
checking for pselect prototype in sys/select.h... yes
checking for ctime_r prototype in time.h... yes
checking for struct timespec... yes
checking for SSL... found in /usr
checking if libssl needs libdl... no
checking for EVP_sha256 in -lcrypto... yes
checking for openssl/ssl.h... yes
checking for openssl/err.h... yes
checking for openssl/rand.h... yes
checking for openssl/ocsp.h... yes
checking for openssl/core_names.h... no
checking for openssl/x509v3.h... yes
checking for HMAC_CTX_reset... yes
checking for HMAC_CTX_new... yes
checking for EVP_cleanup... yes
checking for ERR_load_crypto_strings... yes
checking for OPENSSL_init_crypto... yes
checking for CRYPTO_memcmp... yes
checking for EC_KEY_new_by_curve_name... yes
checking for EVP_MAC_CTX_new... no
checking for EVP_MAC_CTX_set_params... no
checking for EVP_MAC_CTX_get_mac_size... no
checking for SHA1_Init... yes
checking for ASN1_STRING_get0_data... yes
checking if SHA1_Init is deprecated... no
checking whether SSL_CTX_set_ecdh_auto is declared... yes
checking whether SSL_CTX_set_tmp_ecdh is declared... yes
checking whether TLS1_3_VERSION is declared... yes
checking for OPENSSL_init_ssl... yes
checking for SSL_get1_peer_certificate... no
checking for SSL_CTX_set_security_level... yes
checking for ERR_load_SSL_strings... yes
checking if ERR_load_SSL_strings is deprecated... no
checking for library containing evhttp_free... no
./configure: >&for : illegal file descriptor name
configure: error: is
I cannot imagine a scenario for any (resolver?) software to implicitly send a SOA probe over UDP to port 853 / not port 53
Could you clarify this, please?
Unbound is an example when configured with auth zones, it will send the SOA prove over UDP before starting a zone transfer.
There is also a difference to the same solution for that problem in unbound:
While "netstat -lnpu" does not show open UDP sockets for DoT and DoH on unbound, NSD is different:
"netstat -lnpu" shows an open Port for Do53 and DoT. Do53/UDP does timeout on Port 853, though.
Just to be clear with terminology (Do53 does not help if the port is not 53 :), you want to say that when a #437-patched NSD is configured for TLS over port 853 you expect to see only TCP open on 853 but you also see UDP open on 853?
If that is the case, the PR also needs more work apparently
It looks like #437 works very different the the code implemented in unbound.
Unbound and NSD are very different on how they setup listening interfaces.
this errors out on OpenBSD (which has libevent1 in base) thusly:
$ ./configure --enable-prometheus-metrics
[...]
checking for library containing evhttp_free... no
./configure: >&for : illegal file descriptor name
configure: error: is
Thanks for reporting. This particular error will be obsolete in the
release tomorrow, but was caused by missing brackets in the configure.ac
script. However, prometheus metrics depend on libevent2 and will stay
deactivated with previous versions.
with tcpdump I saw unbound
- asking 10.0.0.2@53 via UDP for a SOA-Record
then
- transfering the zone over a TLS conection to 10.0.0.2@853 / TCP
I do not saw any traffic to 10.0.0.2@853 / UDP
Hmm, I wasn't expecting that. This looks like a feature in this case?
I would expect Unbound to not know about port 53 with this configuration, but since the probe will go over UDP it "correctly" uses port 53?
But that doesn't sound right if your config is like:
primary: 10.0.0.2@54
I'll look into that and probably treat it like a bug.
... you expect to see only TCP open on 853 but you also see UDP open on 853?
yes
NSD even write it to my log:
nsd_1 | [2025-04-23 21:54:21.848] nsd[1]: notice: nsd starting (NSD 4.12.0)
nsd_1 | [2025-04-23 21:54:21.848] nsd[1]: notice: listen on ip- address 10.0.0.2@53 (udp) with server(s): *
nsd_1 | [2025-04-23 21:54:21.848] nsd[1]: notice: listen on ip- address 10.0.0.2@53 (tcp) with server(s): *
nsd_1 | [2025-04-23 21:54:21.848] nsd[1]: notice: listen on ip- address 10.0.0.2@853 (udp) with server(s): -
nsd_1 | [2025-04-23 21:54:21.848] nsd[1]: notice: listen on ip- address 10.0.0.2@853 (tcp) with server(s): *
nsd_1 | [2025-04-23 21:54:21.848] nsd[1]: info: creating unix socket /run/nsd-control.socket
nsd_1 | [2025-04-23 21:54:21.871] nsd[20]: info: zone . read with success
nsd_1 | [2025-04-23 21:54:21.871] nsd[20]: info: zone example. read with success
nsd_1 | [2025-04-23 21:54:21.871] nsd[20]: notice: nsd started (NSD 4.12.0), pid 1
Notice the '-' at the end of the 853-UDP line, while the other lines end with '*'
No idea, what that means...
'*' means all the server processes are listening there
'-' means none of the server processes are listening there