DNSSEC requires private keys for signing DNS zones, just as your SSH client needs a private key to connect to a host via SSH. These private keys can be stored on a file system (and often are, particularly in the case of your SSH keys), but they can also be stored on a cryptographically secured hardware device. In the case of SSH this is often a Smart Card whereas with DNSSEC this is typically, in large environments anyway, one or more HSM, each costing anywhere up to several tens of thousands of Euros. But, as we all know, a high price doesn’t necessarily mean “good quality”; one of my favorite examples (true story) is this diagnostic message each time a EUR 50k HSM is accessed:
So, what do people who want to store private keys on a secure hardware device purchase? One possibility is a Smart Card.
One of the worst “shopping experiences” I’ve ever had was when I wanted to purchase a high-end HSM for a project a couple of years ago; it was almost impossible to obtain documentation. Only after several phone calls to the vendor was I given access. (It’s as though they keep their docs in the bloody HSMs.) Runner up to that experience is probably trying to obtain a Smart Card and getting decent documentation on that. With the notable exception of the Yubikey, which has excellent, publically available documents, it’s a disaster. I asked Jakob Schlyter whether he knew of anything which could work for me together with OpenDNSSEC, and he recommended either of a CardContact SmartCard (prices here) or a Yubico Yubikey Neo.
The CardContact SmartCard comes in several form-factors and the “documentation” consists of a zip file which a bunch of Windows executables and a PDF with some screenshots. That really didn’t look convincing, so I selected the Yubikey Neo. To cut a very long story short, the Yubikey, while being a tremendously versatile bit of very well-documented kit, doesn’t support creation of keys via the PKCS#11 interface, so that was the end of that. Back to square one, i.e. the CardContact SmartCard HSM (hereafter called SmartCard HSM).
If I wrote down everything I know about smart cards and HSMs, widely spaced, in a large font, I would cover a small postage stamp. One important thing to know is that software often interfaces to a HSM with PKCS#11.
The SmartCard HSM token is a USB thing, so I plugged it in. Obviously. As I think I’ve already mentioned, there is zero documentation about this beast other than a short incorrect README tucked away in a subdirectory of the downloadable zip file which contains an obscure shared object (compiled for i386 – also not documented).
please make sure that you are compiling and installing OpenSC 0.14
and this is confirmed here, so I installed from that PPA. Nothing doing. I then installed all the bits and pieces from source; nothing doing, so I went to sleep. During the night it ocurred to me that the bit communicating with the card is pcscd, so the next morning I built that from source; nada. After scrounging around for ages, I stumbled over a blog post by smartcard-hsm called SmartCard-HSM USB-Stick with new USB Product ID, and bingo! Thanks a million to these people for hiding that information so well, and thanks a lot also to the German vendor of the card for responding to my query with
alle relevant information you will find at http://www.smartcard-hsm.com/
(I’m not usually the shame and blame type, but well, this just sucks.)
So, let’s do something.
That looks promising, so can I now initialize the card and set the SO-PIN and the PIN? Following the very good instructions on doing so:
Now I’ll try to generate a key in order to determine whether it’s worth continuing to experiment with OpenDNSSEC (recall I was disappointed by the Yubikey in this respect)
Yay! And a little green light on the USB thing blinks at me. Let me do another, this is fun!
What is this card actually capable of, at least in theory?
So, can I “see” what’s on the card? Yes:
Now I wipe one of the key pairs, ensuring I log into the card:
Thinking I was ready to use the card with OpenDNSSEC was a little premature. To cut a painful story short, I won’t tell you. (No more blame and shame today.) BIND: same story. To be fair this isn’t necessarily an issue of the DNS server software; it can well be due to differing interpretation of the PKCS#11 “standard” (how I detest that word). Be that as it may, if somebody says to you “supports PKCS#11” be scared. Very scared. Update: Matthijs convinced me to file a bug report at OpenDNSSEC which I’ve done.
I abandoned this project.
At just about this time, Aki Tuomi heard I was playing with PKCS#11 and asked me to test his implementation for the Authoritative PowerDNS server. I’ll be honest: considering my experiences with OpenDNSSEC and BIND with PKCS#11, I was very reluctant to waste more time with this. I was wrong: in just a few hours yesterday, Aki enhanced the implementation for OpenSC support, and he got this working painlessly for me.
PowerDNS has an experimental PKCS#11 module which relies on P11-kit.
According to the p11-kit manual,
I must create a module file which associates a p11-kit module to a particular HSM. In order to
connect to the SmartCard HSM via OpenSC, I create
/etc/pkcs11/modules/opensc.module. That name is important to remember, because we’ll see it referenced later. (I could have called it “blabla”, but I chose a slightly more formal “opensc”.)
I then verify that p11-kit can “see” my card; I identify this by the manufacturer:
I create a test zone called
cmouse.aa (cmouse is Aki’s IRC handle :-) in PowerDNS
which I’ll use for these experiments.
The first thing I do is create two keys on my miniature HSM, one to be used as the KSK (2028 bits), the second as ZSK (1024 bits). I’m also using the
-a switch to set a label on the keys so that I can identify them on the HSM later:
So far, we have two key pairs on the HSM, but PowerDNS cannot use these yet; we’ve yet to associate these keys with the zone we want to sign. This is done with the
hsm subcommand of the pdnssec utility.
The parameters are:
- Name of the zone from domains table.
- Signing algorithm
- The type of key. Values can be
- The name of the p11-kit module PowerDNS will use to find the HSM. Recall I called it opensc
- The slot on said HSM. I identified it, above, as slot #1
- The PIN for said HSM. Careful: we’ll see this in clear text in a moment! Anybody who can access the MySQL cryptokeys table will be able to read the HSM’s PIN.
- The label of the key on the HSM.
key id issued by pdnssec is actually the row identifier in PowerDNS’ cryptokeys table. Here we go:
I warned you about the HSM PIN being available in clear-text; there it is. This is necessary, because PowerDNS needs to login to the HSM to get it to sign data whenever it needs to use the key material. This also means that the HSM is a limiting factor with regards to performance: the slower the HSM, the slower PowerDNS will be able to produce DNSSEC signatures.
So, if everthing is set up correctly, and if everything works, we ought to be able to have PowerDNS show us a DNSKEY or two and the signed zone. Let’s try.
That looks wonderful, and what’s even nicer is, as I ran that command, I saw blinkenlights on the SmartCard HSM. ;-)
More blinkenlights, and two DNSKEY records! Nice.
I can disable DNSSEC for a zone with the
disable-dnssec subcommand of pdnssec which simply removes the key association from the cryptokeys table, leaving the keys on the HSM. These keys can be
deleted from the device as shown above, using pkcs11-tool, or I can re-use them for a different zone or even associate them with more than one zone (i.e. shared keys).
Was experimenting with a smart card for DNSSEC worth the effort? With the notable exception I just described in detail, it certainly was not.