COREDNS-SIGN(7)
β¨ COREDNS-SIGN(7) β the sign plugin, explained π
okay so bestie, listen up β this is the coredns-sign(7) manual page and it's literally all about adding DNSSEC records to your zone files. it's giving cryptography but make it cute. let's get into it π
πΈ NAME πΈ
sign β adds DNSSEC records to zone files. that's the whole vibe. periodt.
π DESCRIPTION π
so the sign plugin is here to sign zones (per RFC 6781, iykyk). in this whole process, DNSSEC resource records get added. here's the tea though: the signatures that sign the resource record sets have an expiration date, which means the signing process must be repeated before that expiration date hits. otherwise the zone's data will go BAD (RFC 4035, Section 5.5) β and not in a slay way, in a broken-DNSSEC way π. thankfully, the sign plugin handles all of that for you.
important caveat: only NSEC is supported β sign does not support NSEC3. no cap.
sign works in conjunction with the file and auto plugins: this plugin signs the zone files, and auto and file serve the zone data. a little team effort, we love to see it π«Ά
for this plugin to work, you need at least one Common Signing Key (see coredns-keygen(1)). this key (or keys) gets used to sign the entire zone. real talk: sign does not support the ZSK/KSK split, nor will it do key or algorithm rollovers β it just signs. simple, iconic, no drama.
here's what sign will do for you:
- (Re)-sign the zone with the CSK(s) when:
- the last time it was signed is more than a 6 days ago. each zone will have some jitter applied to the inception date.
- the signature only has 14 days left before expiring.
both these dates are only checked on the SOA's signature(s).
- create RRSIGs that have an inception of -3 hours (minus a jitter between 0 and 18 hours) and an expiration of +32 (plus a jitter between 0 and 5 days) days for every given DNSKEY.
- add NSEC records for all names in the zone. the TTL for these is the negative cache TTL from the SOA record.
- add or replace all apex CDS/CDNSKEY records with the ones derived from the given keys. for each key, two CDS are created β one with SHA1 and another with SHA256.
- update the SOA's serial number to the Unix epoch of when the signing happens. this will overwrite any previous serial number. sorry not sorry to your old serial π
so there are two ways that dictate when a zone is signed. normally every 6 days (plus jitter) it gets resigned. if for some reason we fail this check, the 14 days before expiring kicks in as backup.
keys are named (following BIND9): K<name>+<alg>+<id>.key and K<name>+<alg>+<id>.private. the keys must not be included in your zone β they'll be added by sign. these keys can be generated with coredns-keygen or BIND9's dnssec-keygen. you don't have to adhere to this naming scheme, but if you don't, you need to name your keys explicitly β see the keys file directive.
a generated zone is written out in a file named db.<name>.signed in the directory named by the directory directive (which defaults to /var/lib/coredns).
β¨ SYNTAX β¨
sign DBFILE [ZONES...] {
key file|directory KEY...|DIR...
directory DIR
}
okay let's break it down:
DBFILEβ the zone database file to read and parse. if the path is relative, the path from therootplugin will be prepended to it.ZONESβ the zones it should sign for. if empty, the zones from the configuration block are used.keyβ specifies the key(s) (there can be multiple) to sign the zone. iffileis used, the KEY's filenames are used as is. ifdirectoryis used,signwill look in DIR forK<name>+<alg>+<id>files. any metadata in these files (Activate, Publish, etc.) is ignored. these keys must also be Key Signing Keys (KSK) β non-negotiable πdirectoryβ specifies the DIR where CoreDNS should save zones that have been signed. if not given, this defaults to/var/lib/coredns. the zones are saved under the namedb.<name>.signed. if the path is relative, the path from therootplugin will be prepended to it.
keys can be generated with coredns-keygen. to create one for use in the sign plugin, use: coredns-keygen example.org or dnssec-keygen -a ECDSAP256SHA256 -f KSK example.org.
π¦ EXAMPLES π¦
signing one zone, the classic way π
sign the example.org zone contained in the file db.example.org and write the result to ./db.example.org.signed to let the file plugin pick it up and serve it. the keys used are read from /etc/coredns/keys/Kexample.org.key and /etc/coredns/keys/Kexample.org.private.
example.org {
file db.example.org.signed
sign db.example.org {
key file /etc/coredns/keys/Kexample.org
directory .
}
}
running this leads to the following log output (note: the timers in this example have been set to shorter intervals):
[WARNING] plugin/file: Failed to open "open /tmp/db.example.org.signed: no such file or directory": trying again in 1m0s
[INFO] plugin/sign: Signing "example.org." because open /tmp/db.example.org.signed: no such file or directory
[INFO] plugin/sign: Successfully signed zone "example.org." in "/tmp/db.example.org.signed" with key tags "59725" and 1564766865 SOA serial, elapsed 9.357933ms, next: 2019-08-02T22:27:45.270Z
[INFO] plugin/file: Successfully reloaded zone "example.org." in "/tmp/db.example.org.signed" with serial 1564766865
one zone file, multiple zones π
or use a single zone file for multiple zones β note that the ZONES are repeated for both plugins. also note this outputs multiple signed output files. here we use the default output directory /var/lib/coredns.
. {
file /var/lib/coredns/db.example.org.signed example.org
file /var/lib/coredns/db.example.net.signed example.net
sign db.example.org example.org example.net {
key directory /etc/coredns/keys
}
}
same config, but zones in the server block β
this is the same configuration, but the zones are put in the server block β but note that you still need to specify what file is served for what zone in the file plugin:
example.org example.net {
file var/lib/coredns/db.example.org.signed example.org
file var/lib/coredns/db.example.net.signed example.net
sign db.example.org {
key directory /etc/coredns/keys
}
}
the warning about origins π
be careful to fully list the origins you want to sign. if you don't:
example.org example.net {
sign plugin/sign/testdata/db.example.org miek.org {
key file /etc/coredns/keys/Kexample.org
}
}
this will lead to db.example.org being signed twice, as this entire section is parsed twice because you have specified the origins example.org and example.net in the server block. not the vibe. watch out π«£
forcibly resigning a zone π₯
forcibly resigning a zone can be accomplished by removing the signed zone file (CoreDNS will keep on serving it from memory), and sending SIGUSR1 to the process to make it reload and resign the zone file. main character energy, honestly.
π SEE ALSO π
the DNSSEC RFCs: RFC 4033, RFC 4034 and RFC 4035. and the BCP on DNSSEC, RFC 6781. furthermore, the manual pages coredns-keygen(1) and dnssec-keygen(8). and the file plugin's documentation.
coredns-keygen can be found at https://github.com/coredns/coredns-utils β¨https://github.com/coredns/coredns-utilsβ© in the coredns-keygen directory.
other useful DNSSEC tools can be found in ldns β¨https://nlnetlabs.nl/projects/ldns/about/β©, e.g. ldns-key2ds to create DS records from DNSKEYs.
π BUGS π
keys directory is not implemented. that's it, that's the bug. we stay honest π
and that's the whole page bestie! you're now fully fluent in the sign plugin. go forth and sign those zones πβ¨
(this has been the CoreDNS sign manual, from the CoreDNS Plugins collection, dated March 2026 β thanks for reading, love u, bye π«ΆπΈ)
π¦ where this page comes from
- nixpkgs unstable: coredns 1.14.7
- opensuse-leap 16.0: coredns-extras 1.15.0-bp160.1.1 Β· Apache-2.0 AND MPL-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms