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
Support of DANE and DNSSEC in Office 365 Exchange Online
https://techcommunity.microsoft.com/t5/exchange-team-blog/support-of-dane-and-dnssec-in-office-365-exchange-online/ba-p/1275494
https://techcommunity.microsoft.com/t5/exchange-team-blog/support-of-dane-and-dnssec-in-office-365-exchange-online/ba-p/1275494
Microsoft 365 roadmap
What is DANE?
DANE is the abbreviation for "DNS based Authentification of Named Entities".
It requires DNSSEC https://www.ietf.org/rfc/rfc4035.txt
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
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.
https://de.wikipedia.org/wiki/HTTP_Public_Key_Pinning
https://developer.mozilla.org/en-US/docs/Web/HTTP/Public_Key_Pinning
https://developer.mozilla.org/en-US/docs/Web/HTTP/Public_Key_Pinning
How does DANE work?
I think it's well explained here:https://labs.ripe.net/author/dennis_baaten/better-mail-security-with-dane-for-smtp
- 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
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
$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 = 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
Azure DNS FAQ
https://docs.microsoft.com/en-us/azure/dns/dns-faq
https://docs.microsoft.com/en-us/azure/dns/dns-faq
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)
Let's check with the Windows command promt - that does not know that resource Record
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
$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",
# (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
# 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