reason=”verification failed; insecure key”

I’ve recently noticed OpenDKIM on systems I run giving the above message when trying to verify a DKIM message from my own domain. According to Google searches this is due to DNSSEC not being enabled. I’m not certain that I really need DNSSEC for this reason (I can probably make DKIM work without it), but the lack of it does decrease the utility of DKIM and DNSSEC is generally a good thing to have.

Client (Recursive) Configuration

The Debian Wiki page about DNSSEC is really good for setting up recursive resolvers [1]. Basically if you install the bind9 package on Debian/Wheezy (current stable) it will work by default. If you have upgraded from an older release then it might not work (IE if you modified the BIND configuration and didn’t allow the upgrade to overwrite your changes). The Debian Wiki page is also quite useful if you aren’t using Debian, most of it is more Linux specific than Debian specific.

dig +short test.dnssec-or-not.net TXT | tail -1

After you have enabled DNSSEC on a recursive resolver the above command should return “Yes, you are using DNSSEC“.

dig +noall +comments dnssec-failed.org

The above command queries a zone that’s deliberately misconfigured, it will fail if DNSSEC is working correctly.

Signing a Zone

Digital Ocean has a reasonable tutorial on signing a zone [2].

dnssec-keygen -a NSEC3RSASHA1 -b 2048 -n ZONE example.com

The above command creates a Zone Signing Key.

dnssec-keygen -f KSK -a NSEC3RSASHA1 -b 4096 -n ZONE example.com

The above command creates a Key Signing Key. This will take a very long time if you don’t have a good entropy source, on my systems it took a couple of days. Run this from screen or tmux.

$INCLUDE ksk/Kexample.com.+123+12345.key
$INCLUDE zsk/Kexample.com.+123+34567.key

When you have created the ZSK and KSK you need to add something like the above to your zone file to include the DNSKEY records.

all: example.com.signed

%.signed: %
        dnssec-signzone -A -3 $(shell head -c 100 /dev/random | sha1sum | cut -b 1-16) -k $(shell echo ksk/K$<*.key) -N INCREMENT -o $< -t $< $(shell echo zsk/K$<*.key)
        rndc reload

Every time you change your signed zone you need to create a new signed zone file. Above is the Makefile I’m currently using to generate the signed file. This relies on storing the KSK files in a directory named ksk/ and the ZSK files in a directory named zsk/. Then BIND needs to be configured to use example.com.signed instead of example.com.

The Registrar

Every time you sign the zone a file with a name like dsset-example.com. will be created, it will have the same contents every time which are the DS entries you send to the registrar to have your zone publicly known as being signed.

Many registrars don’t support DNSSEC, if you use such a registrar (as I do) then you need to transfer your zone before you can productively use DNSSEC. Without the DS entries being signed by a registrar and included in the TLD no-one will recognise your signatures on zone data.

ICANN has a list of registrars that support DNSSEC [3]. My next task is to move some of my domains to such registrars, unfortunately they cost more so I probably won’t transfer all my zones. Some of my zones don’t do anything that’s important enough to need DNSSEC.

5 thoughts on “DNSSEC”

  1. Hey!

    Shouldn’t you use something like RSASHA256 or ECDSAP256SHA256 instead of NSEC3RSASHA1?

  2. Ewoud Kohl van Wijngaarden says:

    Remember your RRSIGs will expire so you must set up a cronjob to refresh them or your zone will break if you don’t edit it often enough. The digitalocean tutorial you referenced does mention a cronjob but not why it’s needed. See https://en.wikipedia.org/wiki/Domain_Name_System_Security_Extensions#Signatures_and_zone_signing

  3. Philipp Kern says:

    You also need to resign if the zone didn’t change but enough time elapsed…

  4. Scott K says:

    The error message is clearer in the opendkim version in Jessie. You’re certainly correct that DNSSEC isn’t required for DKIM.

  5. Reuben F says:

    No need to set up a cron to resign the zones. BIND can do this for you automagically and transparently:


    It makes the implementation of dnssec almost painless to maintain.

Comments are closed.