DNSSEC utilities truncate existing files when saving keys
dst_key_tofile()
and dst__privstruct_writefile()
open their destination files using fopen()
with mode w
, which causes the opened file to be truncated. These functions are used by certain DNSSEC utilities which work on existing files, e.g. dnssec-settime
. If such a utility is used to modify a key file just as named tries to read it, the latter may consider the file to be empty and abort or postpone the operation in progress.
While the time window within which this issue can be triggered is pretty narrow, it already happened in practice - in https://gitlab.isc.org/isc-projects/bind9/-/jobs/189696, during the autosign
test:
-
The
delzsk.example
zone is switched to NSEC3:06-Mar-2019 14:27:20.682 received control channel command 'signing -nsec3param 1 1 10 12345678 delzsk.example.'
-
zone_nsec3chain()
starts creating the NSEC3 chain and finally adds the NSEC3PARAM record at zone apex:06-Mar-2019 14:27:20.695 add delzsk.example. 0 IN NSEC3PARAM 1 0 10 12345678
-
The test checks whether the NSEC3PARAM is present before moving on:
06-Mar-2019 14:27:20.720 client @0x7f6768039350 10.53.0.1#34567 (delzsk.example): query 'delzsk.example/NSEC3PARAM/IN' approved
-
Right after this happens,
dnssec-settime
is called to set the deletion date for the inactive ZSK. This happens to coincide with the finalzone_nsec3chain()
call:06-Mar-2019 14:27:20.735 zone_nsec3chain: zone delzsk.example/IN: enter 06-Mar-2019 14:27:20.736 dns_dnssec_findzonekeys2: error reading Kdelzsk.example.+007+19943.private: end of file 06-Mar-2019 14:27:20.736 zone delzsk.example/IN: zone_nsec3chain:dns__zone_findkeys -> end of file 06-Mar-2019 14:27:20.736 zone delzsk.example/IN: zone_nsec3chain: end of file
This temporarily prevents the private record indicating that the NSEC3 chain is being created from being removed from the zone apex, triggering a false positive for the above check due to an extra line being present in the rndc signing -list
output inspected after running rndc loadkeys
.
The way I see it, there are two separate issues to address here:
-
DNSSEC utilities should never cause key files to become truncated. I think this problem should be addressed by writing the key to a temporary file first and then moving it into the existing key file's place. However, that would be a functional change which I believe could not be backported because it would break e.g.
dnssec-settime
for users storing key files in non-writable directories. -
The aforementioned check in the
autosign
system test should be tweaked to prevent false positives from occurring. This change should be backported to all maintained branches.