DNSSEC fully automated with DANE

To have DANE, I setup DNSSEC to build signed zones on demand, and also use the domain based verification in certbot, which drives the dnssec automatic signing and release process.

Domain based verifiation already requires to script a check that all my nameservers are serving the correct data before telling certbot to validate, so this part is handled.

As at this point, certbot acme records will be dnssec signed, as with every over zone change, the next step is to work out a good process for handling TLSA records.

I use the 311 which format which only includes the public key as this is not always invalidated over time unlike the other variants that indirectly include certificate expiry dates and hence always become invalid eventually.

Even though 311 records make key rotation optional, it is still good for security to do that, and by default certbot generated certificates pick an new keypair when regenerated.

The process used here relies on that certbot usually generates new certificates around a month before the old ones expire, which is more than enough time to automatically rotate.

Whenever certbot generates new certificates, immediatly append TLSA records for them to the DNS zones, sign them with DNSSEC and release, but do not (yet) set services using the new certificate.

As a consequence zones will normally have 2 TLSA records, the existing and the new one. If there is a failure of some sort then there could be more than that, but the certificate is considered valid if matched by any served TLSA record.

A separate script regularly checks if any new certificates have been issued that differ from the current ones and are safely older than the dns expiry time, I use about an hour for most DNS TTL, so checking for at least a day old is good enough, even checking once a week is within range, becouse this is still somewhat experimental, it is best done whilst admin is likely about to check and clean up. When that is the case, replace the certificate for the affected services, then repeatedly test to see if the new certificate is active.

If they do not notice, as a lot of services do not inotify on their .pem files, force them to begin using it by first reloading the service, and if still not, then fully restart the service.

To try make this more generic and robust, this relies extensively on use of openssl s_client to probe each service to extract the certificate it is serving, "have" and compare it with the one it is configured to use "want". Working back from the listening port to the service relies upon detecting the linux control group, which is then used to locate the systemd unit managing the service to execute the try-reload or even try-restart. Ports that are not listening are skipped as there is no change to make.

Finally, replace all involved TLSA records with only those for the new certificate. Then, any cached TLSA records would remain valid based on the "new" record, til they expire and after that they see only the new one, til this whole process repeats, maybe 2 months later.

DNSSEC distrust issues

Let suppose we go through some of the argumentation regarding dnssec:

Weak keys (at the root, or elsewhere)

It can be imagined that any crypto that balances protection with computational viability would be attacked, so DNSSEC has the ability to transition crypto flavours, called algorithms, as needed.

Though this is usually in the direction of longer keys and therefore may drag up a second problem:


This has to do with replies being bigger than their requests allowing reflection attack amplification.

A generic resolution would be to pad requests to the expected response size, although long term elliptic curve may prove good by obtaining security via smaller responses.

Can you hide records?

DNSSEC appears to allow private subdomains, if users want, only the DS from the delegation point KSK(s) are shared.

The private part of the KSK(s) are then used to sign the private zone ZSK(s) or duplicates of them.

Then information about signed records, and replacement KSK at key rotation, are regularly propogated into the private system to "prove" the delegation to dns users in there.

The result is that even if a KSK is successfully attacked to calculate the private value, anything signed with it (like the ZSK) within a private network stays there, so implementing DNSSEC by itself does not reveal additional info outside.

These machines might even be completely disconnected, since it is just given the KSK private part, with the public part generating the DS which goes in the upstream zone, and only when rolling over KSK, the machine gets updates, and never need to send data outside.

The KSK will be accessible, and the private half given to the hidden server, just to sign its internal ZSK.

This may still apply if there is a CSK directly signing a zone rather than separate KSK and ZSK

This seems to be asked in the context of enterprises who want confidential branches of the DNS.

Even with that, there is NSEC3, though do read the next section for the privacy and PKIX.


On the other side, PKIX such as via letsencrypt does definately not allow hidden domains, as they now all end up in a massive distributed database called certificate transparency, that is searchable, such as for this site, so it is possible to enjoy exploring private infrastructure based on domain names.

PKIX and DNSSEC are not exclusive to each other, both can get used together. TLSA records can be the plain public key flavour, they can still work when the public key goes in a certificate.

Although CT appear to be originally concieved as a CA discipline system, to deter issuance of certificates for purposes such as interception gateways, the real purpose of CT can be realised, escape the DNS:

The Centralization Issue - can you really own a number, or a name?

It is really with whole DNS (and central registries of anything, even IP addresses, e164 numbers and so on!) and not specifically DNSSEC, so yes! Add correct functioning DNSSEC to DNS system, free of concern.

The ideal thing is to prise all applications off the DNS itself, some way of embedding public keys in URL would need to catch on, make sure it is at least 64 characters long to avoid being confused for a dns name. Then are finally free from temporary name "registration", since then it no longer matters what DNS name is being used or even have one at all.

  1. Public key network sockets, that means the whole public key of an entity is to be used an actual network socket to contact that entity.
  2. Use petnames as key aliases rather than a DNS that is transient..
  3. While we await good decentralised F2F networks, look up the public key in certificate transparency to get the remote entity current dns name, if they get their name taken away, sign a new one with the same key or sign the new key with a chain starting with the old one.
  4. Wiki style disambiguation to resolve petname clashes.

My identity for rent

Domain names unfortunately are not owned as such but on loan. This goes for hyperlinking to most websites addresses that incorporate a domain name rooted at the ICANN also.

Fortunatally RDAP provides a way to deactivate hyperlinks upon registrant change to drop catcher, so there is then no pagerank reward in winning a lottery, only with fresh quality content. Although further analysis may be needed to confirm this is withing terms, it works like this:

  1. Maintain a local database of domain names, registration date, expiry date, and the associated latest root KSK
  2. Whenever serving a webpage, consult the database.
  3. If the expiry date is passed on any domain, or the entry is not there, refetch the RDAP data if it can be done in terms.
  4. If either, the rdap is not fetchable, or the registration date now is different from the original, then unlink the hyperlink.
  5. Another one for automation maybe call it rdapinator?

As an example, if you fetch the RDAP record for this site, as a machine readable version of the whois it can be seen that the registration of this domain was at 2004-08-22T21:18:06Z and if that changes to a future date then re-assessment of the ownership should be checked before considering hyperlinks to here valid.

Whats with the root KSK?. There can be more than one of these and support would be left in for other DNS roots, like private ones containing home.arpa

This issue also affects E.164 (telephone) numbers, due to issues regarding number recycling and that the numbering authorities generally do not allow number users to control use long term, it is even worse.

I do not think any of this are reasons not to deploy DANE though.

System Implementation

So many algorithms to choose from

We can dump the list of methods presented by ldns-keygen -k -a list

LabelIndex numberCommentary
RSAMD5001MD5 is very weak against attacks.
RSASHA1005SHA1 still quite weak
RSASHA1-NSEC3-SHA1007Same thing as RSASHA1 with a hint that NSEC3 is in use.
RSASHA256008SHA256, probbaly NSEC3+ assumed from here onwards.
RSASHA512010SHA512 stronger still
ECC-GOST012First elliptic curve
ECDSAP256SHA256013Elliptic curve with a stronger hash, so recommended
ECDSAP384SHA384014Elliptic curve stronger hash

Herein follows the nearly actual scripts used to rebuild my certs automatically on Certificate Saturday. It is essential to script it. First thing is a script to sign the indiviual zone.

I am using nsd and unbound on Debian, some nsd config is needed to tell it to read .zone.signed files instead.

  1. #!/bin/bash
  2. shopt -s nullglob
  3. Z=$1
  4. DOMAIN=${Z:0:$(( ${#Z} -5 )) }
  5. ZSK=0
  6. KSK=0
  7. for N in K${DOMAIN}.+???+?????.key;
  8. do
    1. F="$(<$N cut -f4 | cut -d" " -f1)";
    2. if test "${F}" = "256";
    3. then
      1. ZSK=$(( $ZSK + 1));
    4. fi;
    5. if test "${F}" = "257";
    6. then
      1. KSK=$(( $KSK + 1));
    7. fi;
  9. done
  10. if test "${ZSK}" -eq 0
  11. then
    1. echo creating zsk
    2. ldns-keygen -a RSASHA1-NSEC3-SHA1 -b 2048 ${DOMAIN}
    3. #ldns-keygen -a ECDSAP384SHA384 -b 2048 ${DOMAIN}
  12. fi
  13. if test "${KSK}" -eq 0
  14. then
    1. ldns-keygen -k -a RSASHA1-NSEC3-SHA1 -b 4096 ${DOMAIN}
    2. #ldns-keygen -k -a ECDSAP384SHA384 -b 4096 ${DOMAIN}
  15. fi
  16. KEYS=`for N in K${DOMAIN}.+???+?????.private; do echo ${N:0:$(( ${#N} - 8)) }; done| sort | uniq`
  17. dns-signzone -n -p -s $(hexdump -ve \"%08x\" -n 8 /dev/random) $DOMAIN.zone $KEYS
  18. ldns-key2ds -n -1 $DOMAIN.zone.signed && ldns-key2ds -n -2 $DOMAIN.zone.signed

Could run as if rebuild my.example.zone; nsd-control reload; killall -HUP nsd

This is for signing a zone with a ZSK, itself signed by a KSK.

If the keys need changing because they are stale or did not exist before, they are regenerated, though if KSK is updated the new key must be added to the upstream zone in the from of DS records for the delegation to remain valid.

To aid in key rotation, the delegation is to be treated as valid if any DS are correct so the DS records for disused and especially weak or compromised keys should be removed quickly.

Since this step has to be rerun everytime that there are zonefile changes it is useful to keep it in a separate file, then NSD is told to reload the zone to make it available.