DANE - DNS based Authentification of Named Entities

Hi All,

You might have stumbled over the Microsoft Anouncement of DNSSEC/DANE for Exchange Online.
In this Blog i would like to explain how it works in detail


Microsoft 365 roadmap


What is DANE?

DANE is the abbreviation for "DNS based Authentification of Named Entities".

Dane is defined in the RFC6698
The DNS-Based Authentication of Named Entities (DANE)
Transport Layer Security (TLS) Protocol: TLSA
https://datatracker.ietf.org/doc/html/rfc6698

Requires a TLSA DNS Record. In the RFC above there is this Statement:
TSLA Record ("TLSA" does not stand for anything; it is just the name of the RRtype)

Maybe that's true. I would consider it as a TLS Anchor.

Kind of HTTP Public Key Pinning (HPKP) Pinning for SMTP.
Interesting Note is that, HPKP is already depreciated and not supported anymore in any browser.

How does DANE work?

In short, these are the Steps that are performed
  • MX Lookup
  • DANE Lookup (TLSA Record for the Mailserver Hostname)
  • Connect to the Mailserver and get the TLS Certificate
  • Check if the Certificate matches the Hash of the TLSA Record


MX Lookup

As an Mailserver or Exchange Admin, you will be familiar with MX Lookups. There are many ways to do it.

With the Windows command prompt

nslookup -type=mx hostpoint.ch


With Powershell cmdlets

nslookup -type=mx hostpoint.ch
Resolve-DnsName -Name hostpoint.ch -Type MX



Via DNS over HTTPS

$Domain = "hostpoint.ch"
$json = Invoke-RestMethod -URI "https://dns.google/resolve?name=$Domain&type=MX"
$MX = $json.Answer.data
$MX



DNSSEC

But wait, didn't you say that the DNS Zone has to be Secured with DNSSEC?
Yes that's true. But how can i check that?

DNSSEC Analyzer



Another interesting Method is to use DNS over HTTPS with Powershell.
The DNS Zone hostpoint.ch is protected with DNSSEC, while the DNS Zone icewolf.ch is not.

$Domain = "hostpoint.ch"
$json = Invoke-RestMethod -URI "https://dns.google/resolve?name=$Domain&type=MX"
$json

As you can see there are some Flags in the Rest Response. AD = true is what we are looking for.
  • TC: TrunCation (truncated due to length greater than that permitted on the transmission channel)
  • RD: Recursion Desired
  • RA: Recursion Available
  • AD: Authentic Data
  • CD: Checking Disabled

My DNS Zone icewolf.ch is hosted on Azure DNS. Interesting sidenote is that Azure DNS does not support DNSSEC at this time


TLSA DNS Record

The TLSA DNS Record looks like this
_<Port>._tcp.<Servername> IN TLSA <Certificate usage> <Selector> <Matching Type> <Fingerprint>


Certificate Usage (0 - 3)

0 The Hash belongs to the Certificate Authority who is allowed to issue Certificates for this Host. The Client must trust this CA (Trusted Root CA or Trusted Subordinate CA)
1 The Hash belongs to the Servercertificate. It has to be from a CA that the Client trusts.
2 The Hash belongs to the Certificate Authority who is allowed to issue Certificates for this Host. The Client must thrust this CA even its not in the List of the Trusted Root CA or Trusted Subordinate CA of the Client
3 The Hash belongs to the Servercertificate and the Client shall trust it without having a look at the Certificate Chain

Selector (0 or 1)

0 Hash will be from the complete Certificate
1 Hash will only be from the Public Key and the algorithm

Matching Type (0-2)

0 Hash contains the full certificate
1 Hash contains a SHA-256 hash
2 Hash contains a SHA-512 hash

Let's check with the Windows command promt - that does not know that resource Record

nslookup -type=tlsa _25._tcp.mx.hostpoint.ch


Let's check with the Powershell Commandlets - same here, the Resource Type is not known

Resolve-DnsName -Name _25._tcp.mx.hostpoint.ch -Type TLSA


Let's try with DNS over HTTPS - here it works

$TLSAQuery = "_25._tcp.mx.hostpoint.ch"
$json = Invoke-RestMethod -URI "https://dns.google/resolve?name=$TLSAQuery&type=TLSA"
$TLSA = $json.Answer.data
$TLSA



If you're working on Linux, that's your command:

Install the Bind utils
sudo yum install bind-utils

DNS Query
dig _25._tcp.mx.hostpoint.ch IN TLSA +short


Most of the DNS Providers out there currently do not support tho create TLSA DNS Records

Even in the Control Panel of Hostpoint  (Remember it does support DNSSEC and has published it's own TLSA Record) it's not possible to publish a TLSA Record.

Same applies also to Azure DNS


Normally you can check any DNS Record with MXToolbox.com - not for TLSA Records. At least not for the moment. I guess that will change soon.


But there are alternatives like this one

DANE SMTP Validator



or this one


Mail Server Certificate

It's now time to get the Mailserver Certificate. A while ago i've created a Powershell Script for getting the SMTPCertificate.

\Get-SMTPCertificate.ps1 -ServerName $Mailserver -Port 25 -SendingDomain icewolf.ch -CertificateFilePath C:\GIT_WorkingDir\PowerShellScripts\mx.hostpoint.ch.cer


Create the Hash

To be honest, i was strugeling with that part. None of my effords in creating a SHA-256 Hash of the Certificate / Certificate Public Key did match the Hash in the TLSA Record.

It's not as simple as creating a SHA-256 Hash.

# The GetSpkiFingerprint method returns the SPKI Fingerprint suitable for use in pinning.
#  (See RFC 7469.)  An SPKI Fingerprint is defined as the output of a known cryptographic hash
#  algorithm whose input is the DER-encoded ASN.1 representation of  the Subject Public Key Info
# (SPKI) of an X.509 certificate.  The first argument specifies the hash algorithm and may be
# "sha256", "sha384", "sha512", "sha1", "md2", "md5", "haval", "ripemd128",
# "ripemd160","ripemd256", or "ripemd320".   
# The second argument specifies the encoding, and may be "base64", "hex",


But you can use Certutil with the *.cer File

certutil.exe -dump C:\GIT_WorkingDir\PowerShellScripts\mx.hostpoint.ch.cer


Or create a PowerShell Script around certutil

###############################################################################
# Hash with Powershell and Certutil
###############################################################################
$dump = certutil.exe -dump C:\GIT_WorkingDir\PowerShellScripts\mx.hostpoint.ch.cer
$line = $dump | Select-String -pattern "pin-sha256-hex"
$Line = $Line.Tostring()
$SpkiFingerprint = $line.Split(" ")[1]
$SpkiFingerprint



Or use openssl

openssl x509 -in hostpoint.cer -pubkey -noout | openssl pkey -pubin -outform DER | openssl sha256




If you need to create a TLSA DNS Entry, there are also Tools on the internet



Summary
The requirements for DANE are pretty high with DNSSEC and a TLSA Record.
Administrators need to understand how to create these DNS Records and how to rollover when a certificate expires.
Anyway i am exited to see that Exchange Online will support DANE soon.
So prepare yourself to be able to troubleshoot if something isn't set up correctly.

Regards
Andres Bohren