on 16th August 2012 at 15:54
FreeBSD device nodes and chroots
I run a toy nameserver on my FreeBSD workstation, mainly for experimenting with DNSSEC. I run it in a chroot, which I had set up in the traditional way using mknod. This appeared to work OK.
This week I have been trying out BIND 9.9.2b1, which introduces support for ECDSA signatures. One of its promising attributes is an ECDSAP256SHA256 signature is about a half of the size of 1024 bit RSASHA1 signature:
fanf2.ucam.org. 3600 IN RRSIG SOA 5 3 3600 ( 20120915135936 20120816125936 35583 fanf2.ucam.org. qh5KFmvzS2XhjLGXeHz4s2IbMRbGJKpfcXj/glm6dnG6 izejGwvbEJrGpHXTdwEmjRLcL0yUOy4nwyk2NWHNjlgi 5ODy4Vc8fAOxibsL98jh1grC/795icLO7wicQPUz4DsF /JknR85zQNZ2YOYJ4QL9HIy1uEuoirpa1fDfr8I= ) fanf2.ucam.org. 3600 IN RRSIG SOA 13 3 3600 ( 20120915135936 20120816125936 36584 fanf2.ucam.org. JtqMAgLWUhBlIJqTJldKqqe5as9IRKWdBF/uIZ1ldVbE GerFX/C+Pcqecx1rXsZLwWGDJvQ7q7ch8fryt+ImuA== )
When I first tried to sign a zone with ECDSA, named logged a rather uninformative pair of error messages:
15-Aug-2012 19:56:31.969 general: error: zone fanf2.ucam.org/IN: update_sigs:add_sigs -> sign failure 15-Aug-2012 19:56:31.970 general: error: zone fanf2.ucam.org/IN: sign_apex:update_sigs -> sign failure
I was unable to reproduce this error with a much simpler name server configuration on another machine. I hacked around to trace where the error came from, and it turned out to be inside OpenSSL's ECDSA_do_sign() routine.
One of the notable differences between RSA and DSA is that DSA requires random numbers to create a signature. BIND requires random numbers for lots of other things at run time, including for hard-to-guess query IDs and source port numbers. So I had thought the /dev/random setup in my chroot was working. However, while debugging my ECDSA problem I noticed BIND logging an error at startup:
Aug 15 20:07:56 black named: could not open entropy source /dev/random: unexpected error Aug 15 20:07:56 black named: using pre-chroot entropy source /dev/random
I then had to learn the correct way to set up device nodes in a chroot on FreeBSD:
# $T is the chroot directory mount -t devfs devfs $T/dev # the default ruleset is immutable, so create a new one devfs -m $T/dev ruleset 1 # only a small selection of devices should be visible devfs -m $T/dev rule add path random unhide devfs -m $T/dev rule add path urandom unhide # make it so devfs -m $T/dev rule applyset
Having fixed that, BIND cheerfully signed the zone with ECDSA. Evidently BIND is clever enough to recover from a badly set up chroot, but OpenSSL isn't, presumably because it does not try to open /dev/random until the last moment.