Self-signed Certificate Recipe

This recipe describes how to configure DNS(SEC) to include a TLSA record that acts as a different channel to provide verification for a self-signed x509 (SSL) certificate.


TLSA is still in an early stage of deployment. One of the road blocks that exists as of late 2016 is the lack of built-in application support in web browsers and mail applications. As these applications add support for TLSA, steps described in this recipe will become more relevant and practical. Today (as of late 2016), unfortunately, most applications lack native support and will likely result in some kind of error message or warning even if you have deployed TLSA correctly.

The Wikipedia page for DANE contains a list of current applications, libraries and plugins that provide TLSA support.

For this recipe, we are assuming that you already have a working web server configured with a self-signed x509 certificate. Although the steps described below works for self-signed certificates, it can also be used for "real" certificates that were signed by a Certificate Authority (usually a service you pay for). This is one of several possible uses of DNS-Based Authentication of Named Entities, or DANE (we briefly talked about DANE in the section called “Introduction to DANE”).

First, let's take a look at the certificate used by you web server:

# cat server.crt

Next, use openssl to generate a SHA-256 fingerprint of this certificate, this is what you will list in DNS as a TLSA record. Also, you need to remove all the colons, hence the added tr at the end to filter out all ":" characters:

# openssl x509 -noout -fingerprint -sha256 < server.crt | tr -d :
SHA256 Fingerprint=294874DA378148CDD1B9C57D2E891E8C294D2958F0BCA7400A0D6D6F50C4A3BB

Now you can insert the TLSA record by editing the zone file the old fashioned way, or if your DNS server is allowing dynamic updates, you could use nsupdate like this to inject the TLSA record:

# nsupdate
> server localhost
> update add 3600 IN TLSA 3 0 1 294874DA378148CDD1B9C57D2E891E8C294D2958F0BCA7400A0D6D6F50C4A3BB
> send
> quit

Let's talks briefly about the record you just added. The name is a specifically formed "", which specifies the usage of TCP port 443, for the name "". It is followed by three parameters, each representing usage, selector, and matching type. For this recipe, we will not dissect into all the possible combinations of these parameters. The examples listed here are 3, 0, and 1, which represent:

  • Usage: 3 = self-signed certificate
  • Selector 0 = full certificate is included
  • Matching Type 1 = SHA-256

If you are interested in learning (a lot) more about the TLSA record type, check out "A Step-by-Step guide for implementing DANE with a Proof of Concept" by Sandoche Balakrichenan, Stephane Bortzmeyer, and Mohsen Souissi (April 15, 2013)

Assuming you have successfully added the new TLSA record and generated the appropriate signature(s), now you can query for it:

$ dig TLSA

;; ANSWER SECTION:	3600 IN	TLSA	3 0 1 294874DA378148CDD1B9C57D2E891E8C294D2958F0BCA7400A0D6D6F 50C4A3BB

Great! But that's still only half of the equation. We still need to make your web browser utilize this new information. For this recipe, we are showing you results of using Firefox with a plugin called DNSSEC TLSA Validator from

Once the plugin is installed, activated, and Firefox restarted, when you visit the URL, your browser will prompt you for a warning, because this is a self-signed certificate:

Figure 7.16. Browser Certificate Warning

Browser Certificate Warning

Although the certificate is not trusted by the browser itself (if you want to you'll have to install a custom CA root or make the browser trust the certificate individually), the plugin shows that it was able to verify the information it received via HTTPS (port 443), and that it matches the information it received via TLSA lookup over DNS (port 53).

Figure 7.17. DNSSEC TLSA Validator