GeƤndert: 15. 7. 2014, 11:25
Generating DANE DNS records for servers using CAcert.org certificates with tinydns
For those that do not have the money or nationality to be included into the bullshit made in Germany network, or that simply say that this is, well, bullshit, there is the way to use DANE records. They have one disadvantage: they need DNSSEC to be really secure, and sadly my hoster Hetzner currently doesn't support that. But I thought that having them in place anyway can't hurt.
There are several ways to match a certificate by those records, e. g. you can assert that a specific certificate is used, or the root of your trust chain is a specific certificate. You can also publish the complete certificate or just a hash. Since I am a lazy folk I decided that I would publish the root of the certificate chain, i. e. the CAcert root certificate. This is slightly less secure as any certificate signed by CAcert.org for my domain name would be accepted, but the way CAcert works I would have to do that signing. On the other side this is one of the advantages, as I can change the keys and certs any time, as long as it is signed by CAcert the DANE records don't need to change. The other advantage is that the same record for every host and service I use, as all of them use CAcert.
Most howtos will end in "IN TLSA" records, which are for BIND nameservers. I run tinydns from the djbdns package, which uses a different format. So, how did I proceed?
- I used the TLSA generator from huque.com, selected the desired options (usage: 2, selector: 1, signing type: 1) and pasted the CAcert.org root certificate. This resulted in
_443._tcp.webmail.sf-mail.de IN TLSA 2 1 1 6f2851409d710504a35115abcb9a6dd3f2577ec937c9ef1938926fa82fd6ff5d
- Now this needs to be converted to a tinydns record. Tinydns does not know about TLSA records, but you can drop any record type you want using the : line, you just need to know the record number. The record number of TLSA is 52 (see RfC 6698, section 7.1).
- Now you need to convert the information from the record to binary. The first 3 bytes are easy, 2 1 1 translates to \002\001\001. For the rest I used a simple bash command, nothing especially fancy since I planned to run this only once anyway:
for i in 6f 28 51 40 9d 71 05 04 a3 51 15 ab cb 9a 6d d3 f2 57 7e c9 37 c9 ef 19 38 92 6f a8 2f d6 ff 5d; do a=0x$i printf "\\%03o" $a done echo
I just broke the hex string by hand into 2 character parts (i. e. representing one byte), and that was converted to octal. - Now the complete tinydns record is ready to be written:
:_443._tcp.webmail.sf-mail.de:52:\002\001\001\157\050\121\100\235\161\005\004\243\121\025\253\313\232\155\323\362\127\176\311\067\311\357\031\070\222\157\250\057\326\377\135:60
I used a TTL of 60 seconds first to be able to change this fastly if neccessary, but I didn't need that as I surprisingly got it right on the first try. - Then go to SSL-Tools.net, enter your server name, and look at the output. For CAcert signed stuff it shows a certificate error as it does not have CAcert.org root certificates in it's database, and it showed a DANE error for me because my DNS does not support DNSSEC.
- I copied that record e.g. for my MX entry (i. e. _25._tcp.mx.sf-mail.de).
- Time for another test, again using SSL-Tools.net
Two more tips, slightly related: if you are on an openSUSE system the CAcert certificates are not installed by default. But you don't have to do any magic by hand:
zypper in ca-certificates-cacert
And for those that want DNSSEC with tinydns: tinydnssec could be the way to go (haven't tested that yet).