By now we can safely say that DNSSEC as a standard is here to stay. It may not be pretty or completely practical, but it is possible to implement it relatively easily. DNSSEC provides a little bit more assurance on the integrity of the DNS query results. This extra assurance does enable some other interesting applications, to increase the integrity of other systems. This is done through the standard called DANE: DNS-based Authentication of Named Entities. In this post I’ll walk through a couple of examples.
Update 23/7/2015: Added email TLSA record instructions
Update 23/7/2015: Corrected email TLSA record instructions
TLSA records: HTTPS Certificates
The first application of DANE is in the new TLSA DNS record. This record provides information about the TLS certificate that is associated to a service at a hostname. Here is an example:
_443._tcp.1sand0s.nl. 3600 IN TLSA 3 0 1 06f14934d9fa4c8bc926306427aa4815c75f8af13e0dff4c40f1e10f047c7a80
This record provides information on the service running on TCP port 443 on this host, i.e. the web service. In this case it is a service certificate (1), it must also validate the PKIX certification path, a value of 3 can be used for a self-signed certificate. The hash-value is calculated on the full certificate (0), and the type of hash is SHA-256 (1). The rest of the record is the actual hash-value. See also RFC 6698 and 7218.
The hash values can be calculated in two different ways, using the original certificate, or by connecting to the service and fetching the certificate that way.
openssl x509 -in 1sand0s.nl.crt -outform DER | openssl sha256
openssl s_client -connect 1sand0s.nl:443 | openssl x509 -outform DER | openssl sha256
So, this TLSA record, combined with the trust-structure in place for DNSSEC, gives you another, independent, trust-path to a certificate. It can be verified by using a browser-plugin: DNSSEC/TLSA Validator.
TLSA Records: Email TLS certificates
Of course, the same trick with HTTPS can be done for email as well. After all most email servers support TLS. The checking of certificates there is currently abysmal, TLSA seems a first way to actually do something about this.
Again these values can be generated using openssl, in a similar way as before, with a slight adaptation for smtp and starttls:
4733 openssl s_client -connect 1sand0s.nl:25 -starttls smtp | openssl x509 -outform DER | openssl sha256
The resulting records are the following:
_25._tcp.positron.dckd.nl. 86400 IN TLSA 3 0 1 cab6d95928058de5d2da7b239a91ff63cf60ea5df1469162e9008f1efc19ea38 _587._tcp.positron.dckd.nl. 86400 IN TLSA 3 0 1 cab6d95928058de5d2da7b239a91ff63cf60ea5df1469162e9008f1efc19ea38
Then add the following to your Postfix server (I’m assuming you already have TLS running). The first line adds support for DNSSEC, the second makes your server use it opportunistically for outgoing connections, and the final one logs these attempts (look for “Verified TLS”):
smtp_dns_support_level = dnssec smtp_tls_security_level = dane smtp_tls_loglevel = 1
For more info, see also the description by Go6lab.
Correction: SMTP clients don’t have a way of checking the certificate chain or presenting a user with a dialog whether to trust a certain certificate. Therefore, the use of 0 or 1 as first value is undefined. So you should use a value of 3 as first part of your TLSA record.
SSH Fingerprints: SSHFP records
An older application of a similar idea is in publishing SSH key fingerprints. This way users have a way to confirm these keys. It gives you a better idea of what is going on when you are presented with an unknown key:
$ ssh -o "VerifyHostKeyDNS yes" example.com The authenticity of host '[example.com]:22 (1:22)' can't be established. ED25519 key fingerprint is SHA256:T3XU6Fyy1Pc8slKCKiiIPxHu6dEvx5WgyuknBlggtgQ. Matching host key fingerprint found in DNS. Are you sure you want to continue connecting (yes/no)?
example.com. 86400 IN SSHFP 4 1 7516e1ea95d1ba14cbb8853a40f943cdbd8e495c example.com. 86400 IN SSHFP 4 2 4f75d4e85cb2d4f73cb252822a28883f11eee9d12fc795a0cae927065820b604
The record in this case is just the hostname, and the value gives an indication of the algorithm used (4, Ed25519), and the hashing algorithm (1, SHA1 and 2, SHA-256). Like I mentioned above, OpenSSH supports the lookup of these fingerprints by either supplying the
VerifyHostKeyDNS argument on the command-line, or by setting in your
.ssh/config or even better
While this record helps, it still does not completely solve the situation in which you want to do a key change. When you replace the value, you are now presented with even bigger warning signs. But after local removal you at least get some assurance that the new key is probably the intended one.
- 51.100.42 ↩