This sign plugin is working! I’m running it live for miek.nl on my servers to test it out. (See this branch or this one after it is merged into master.)

To use the sign plugin, I only need a few extra lines in my Corefile:

miek.nl {
    file /var/lib/coredns/db.miek.nl.signed
    sign /etc/coredns/zones/miek.nl {
        key file /etc/coredns/zones/keys/Kmiek.nl.+008+33694
        directory /var/lib/coredns
    }
}

This resigns the miek.nl zone ever so often. Logging will tell you what’s happening with your zonefile. In this case this it skips signing:

[INFO] plugin/sign: Skipping signing zone "miek.nl." in "/var/lib/coredns/db.miek.nl.signed", signatures are valid

And here we do sign:

[INFO] plugin/sign: Signing "miek.nl." because inception "2019-08-02T07:17:09.000Z" was more than: 144h0m0s ago from 2019-08-02T10:22:14.943Z
[INFO] plugin/sign: Successfully signed zone "miek.nl." in "/var/lib/coredns/db.miek.nl.signed" with key tags "33694" and 1564741334 SOA serial, elapsed 256.670177ms, next: 2019-08-02T15:22:14.946Z
[INFO] plugin/sign: Skipping signing zone "miek.nl." in "/var/lib/coredns/db.miek.nl.signed", signatures are valid

All tracking is done in the zone file itself. The signature(s) on the SOA record are used for this. If inception date is too long ago (or in the future) the zone will be resigned. If the expiration date is approaching (within a week) the zone will also be resigned. Some jitter is applied, as to not resign the zone all at the same time.

Starting with sign

To go from a unsigned zone to a signed one, you need two things:

  1. Generate keys. You can use coredns-keygen for this.
  2. Update your Corefile.

Using coredns-keygen is simple, to generates keys, just issue:

% coredns-keygen example.org
Kexample.org.+013+54498

This generates two files: Kexample.org.+013+54498.key and Kexample.org.+013+54498.private. The .key will be included in the zone and the .private file is used for signing the zone. CoreDNS needs access to both files for things to work. We copy these files to /etc/coredns/zones/keys.

After signing CoreDNS writes a new zone files named db.example.org.signed. The zone to be signed is /etc/coredns/zones/db.example.org - this is the plain DNS zone to will be signed.

Next we update the Corefile to look like this, we use the default location for the signed zone files which is /var/lib/coredns, so we don’t need to use the directory directive.

example.org {
    file /var/lib/coredns/db.example.org.signed
    sign /etc/coredns/zones/db.example.org {
        key file /etc/coredns/zones/keys/Kexample.org.+013+54498
    }
}

After this the sign plugin will take care of keeping everything up to date. If you make an update to the unsigned zone (db.example.org), just remove the signed zone (db.example.org.signed) and wait for CoreDNS to notice it. By default this happens every 6 hours, if you need it to be quicker you can send SIGUSR1 to the process, to kick off a reload and resign.