# A Working Sign Plugin in CoreDNS


This *sign* plugin is working! I'm running it live for miek.nl on my servers to test it out.
(See [this branch](https://github.com/coredns/coredns/tree/dnssec-file/plugin/sign) or [this
one](https://github.com/coredns/coredns/tree/master/plugin/sign) after it is merged into
master.)

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

~~~ txt
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:

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

And here we do sign:

~~~ txt
[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](https://github.com/coredns/coredns-utils/tree/master/coredns-keygen) for this.
2. Update your Corefile.

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

~~~ sh
% 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.

~~~ txt
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.

