DANE TLSA records don’t pin certificates to DNS; they actually pin DNS records to certificates, allowing you to verify the identity of a server based on its certificate, not just the certificate’s issuer.
Let’s see this in action. Imagine you have a web server at mail.example.com with a certificate. You want to ensure that only the specific certificate you’ve issued for mail.example.com is accepted by clients, regardless of whether it’s signed by a trusted Certificate Authority (CA) or a self-signed one.
First, you need to generate the TLSA record data from your certificate. This involves hashing your certificate (or its public key) in one of three ways and then encoding that hash along with usage and selector information.
Here’s how you’d get the necessary information for a certificate currently in use on mail.example.com:
-
Get the server’s certificate:
openssl s_client -connect mail.example.com:443 -showcerts < /dev/null 2>/dev/null | openssl x509 -outform pem > mail.example.com.pem -
Extract the public key from the certificate:
openssl x509 -in mail.example.com.pem -pubkey -noout > mail.example.com.pub.pem -
Generate the TLSA record data:
- Usage (1 byte):
0: Full certificate1: Subject public key2: Certificate association data (CA constraint)3: Association data (CA constraint)
- Selector (1 byte):
0: Full certificate1: Subject public key
- Matching Type (1 byte):
0: SHA-256 hash1: SHA-384 hash2: SHA-512 hash
Let’s say we want to use the full certificate (usage
0) and the subject public key (selector1), hashed with SHA-256 (matching type0).-
For Usage 0 (Full Certificate):
openssl x509 -in mail.example.com.pem -hash -noout | xargs -I {} echo "0 0 0 {}"This will output something like
0 0 0 7a26258a. -
For Usage 1 (Subject Public Key):
openssl x509 -in mail.example.com.pub.pem -hash -noout | xargs -I {} echo "1 0 0 {}"This will output something like
1 0 0 a1b2c3d4. -
For Usage 1 (Subject Public Key) with SHA-384:
openssl x509 -pubkey -in mail.example.com.pem -outform DER | openssl dgst -sha384 | awk '{print "1 0 1 "$2}'This will output something like
1 0 1 8f9e8d7c6b5a43210fedcba9876543210fedcba9876543210fedcba987.
- Usage (1 byte):
Now you have the data for your TLSA record. The full DNS record name is constructed as: _port._protocol.hostname. For an SMTP server on port 25 using TCP, this would be _25._tcp.mail.example.com.
Let’s assume you generated 0 0 0 7a26258a (usage 0, selector 0, matching type 0, SHA-256 hash of the full certificate). Your DNS record would look like this in BIND zone file format:
_25._tcp.mail.example.com. IN TLSA 0 0 0 7a26258a
Or, if you used 1 0 0 a1b2c3d4 (usage 1, selector 0, matching type 0, SHA-256 hash of the public key):
_25._tcp.mail.example.com. IN TLSA 1 0 0 a1b2c3d4
When a DANE-aware client connects to mail.example.com on port 25 (e.g., an SMTP client), it will:
- Query DNS for
_25._tcp.mail.example.comto get the TLSA record. - Fetch the certificate presented by
mail.example.com. - Compare the fetched certificate (or its public key) against the hash in the TLSA record, based on the usage and selector.
- If the hashes match, the client trusts the certificate and proceeds with the connection. If not, it rejects the connection, even if the certificate is signed by a CA.
This mechanism allows you to specify which certificate (or public key) is acceptable, effectively pinning it. This is incredibly powerful for security, as it mitigates risks associated with compromised CAs or man-in-the-middle attacks where a rogue CA might issue a fraudulent certificate.
What most people miss is that the selector and matching type are critical. Using selector 0 (full certificate) means you must update the DNS record every time the certificate changes, even if it’s just a renewal with the same CA. Using selector 1 (public key) is more resilient; you only need to update the DNS record if you change the underlying public key algorithm (e.g., from RSA to ECDSA) or if you rotate the key itself. This makes 1 0 0 (public key, SHA-256) a common and practical choice for many applications.
The next step is understanding how to configure clients to use DANE, which often involves specific application settings or enabling DNSSEC, as DANE relies on DNSSEC for authenticity of the TLSA records themselves.