`unbound` returns `NOERROR` when signature inception timestamp is set to future
justahero opened this issue · 2 comments
Describe the bug
After signing a zone file with the signature inception timestamp set to the future (+1 hour from current time), fetching the signed record using unbound
as a validating resolver returns the NOERROR
return code instead of SERVFAIL
. According to RFC 4035, section 5.3.1 one of the conditions to check for the inception
field is:
The validator's notion of the current time MUST be greater than or equal to the time listed in the RRSIG RR's Inception field.
To reproduce
Steps to reproduce the behavior:
- set up name server (e.g.
bind
) with DNSSEC enabled
- generate KSK + ZSK keys using
ldns-keygen
- sign zone using
ldns-signzone
with inception (+1h in the future) and expiration (+4h in the future) timestamps set using the Unix timestamp format (according to documentation inldns-signzone.c
) - create DS record using
ldns-key2ds
with the signed zone file
- set up
unbound
as validating resolver
- set up trust anchor from name server
- use
dig
to queryunbound
resolver
dig +recurse +nodnssec +noadflag +nocdflag @172.18.0.3 SOA .
where @172.18.0.3 is the IP of the validating resolver unbound
Please note the given IPs are dynamically assigned, they are not too important for the setup.
The resulting output of dig
is
; <<>> DiG 9.18.24-1-Debian <<>> +recurse +nodnssec +noadflag +nocdflag @172.18.0.3 SOA .
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38239
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;. IN SOA
;; ANSWER SECTION:
. 86214 IN SOA primary0.nameservers.com. admin0.nameservers.com. 2024010101 1800 900 604800 86400
;; Query time: 1 msec
;; SERVER: 172.18.0.3#53(172.18.0.3) (UDP)
;; WHEN: Wed Jul 10 08:57:53 UTC 2024
;; MSG SIZE rcvd: 94
The unbound.conf
file contains:
server:
verbosity: 4
use-syslog: no
interface: 0.0.0.0
access-control: 172.18.0.0/16 allow
root-hints: /etc/root.hints
pidfile: /tmp/unbound.pid
ede: no
trust-anchor-file: /etc/trusted-key.key
remote-control:
control-enable: noroot
Expected behavior
It's expected that unbound
responds with SERVFAIL
to signal an invalid request. Furthermore it should not include the SOA record in its ANSWER section, because the CD
bit is unset (according to RFC 4035 section 5.5).
System:
- Unbound version: 1.17.1
- OS: Ubuntu 22.04
unbound -V
output:
unbound -V
Version 1.17.1
Configure line: --build=aarch64-linux-gnu --prefix=/usr --includedir=${prefix}/include --mandir=${prefix}/share/man --infodir=${prefix}/share/info --sysconfdir=/etc --localstatedir=/var --disable-option-checking --disable-silent-rules --libdir=${prefix}/lib/aarch64-linux-gnu --runstatedir=/run --disable-maintainer-mode --disable-dependency-tracking --with-pythonmodule --with-pyunbound --enable-subnet --enable-dnstap --enable-systemd --with-libnghttp2 --with-chroot-dir= --with-dnstap-socket-path=/run/dnstap.sock --disable-rpath --with-pidfile=/run/unbound.pid --with-libevent --enable-tfo-client --with-rootkey-file=/usr/share/dns/root.key --disable-flto --enable-tfo-server
Linked libs: libevent 2.1.12-stable (it uses epoll), OpenSSL 3.0.11 19 Sep 2023
Linked modules: dns64 python subnetcache respip validator iterator
TCP Fastopen feature available
BSD licensed, see LICENSE in source package for details.
Report bugs to unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues
Additional information
The setup was tested with both bind
& unbound
configured as DNSSEC enabled name server. In both cases the return code was NOERROR
instead of SERVFAIL
.
It is because the test uses a too small time value change. With larger values, Unbound would have made it bogus. It should of course become bogus, because the inception is in the future. For such a small change, Unbound has differential handling.
Assuming everyones timezone is broken, there is some leeway allowed in the signature times. This is to stop operational snafus from causing false positives in dnssec failures. That would cause operation overhead in trying to fix that. To solve this Unbound allows some leeway on the signature. It can be configured, with the options val-sig-skew-min
and val-sig-skew-max
, in addition to these min and max options, Unbound attempts to use about 10% of the time to expiry as a leeway on the time stamp. For the case in question, that would have been a small value, 3h / 10, and then the val-sig-skew-min is an hour by default. This makes it apply an hour leeway, and this makes unbound accept the signature timestamps. The value of the default for val-sig-skew-min is chosen such, because the clock not having the precisely correct time is very common, in addition to hour change misconfiguration issues.
The man page for val-sig-skew-min
and val-sig-skew-max
:
https://unbound.docs.nlnetlabs.nl/en/latest/manpages/unbound.conf.html#unbound-conf-val-sig-skew-min
https://unbound.docs.nlnetlabs.nl/en/latest/manpages/unbound.conf.html#unbound-conf-val-sig-skew-max
thank you for the information. Adjusting the inception
timestamp to a value larger than 1 hour shows the expected behavior. Therefore closing this ticket.