{"id":477,"date":"2023-06-16T11:46:07","date_gmt":"2023-06-16T09:46:07","guid":{"rendered":"https:\/\/jbsoft.nl\/site\/?p=477"},"modified":"2023-06-16T11:46:07","modified_gmt":"2023-06-16T09:46:07","slug":"allow-dane-authentication-to-your-mail-server-or-website","status":"publish","type":"post","link":"https:\/\/jbsoft.nl\/site\/allow-dane-authentication-to-your-mail-server-or-website\/","title":{"rendered":"Allow DANE authentication to your mail server or website"},"content":{"rendered":"\n<p>DANE <a rel=\"noreferrer noopener\" href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc7671\" target=\"_blank\">https:\/\/datatracker.ietf.org\/doc\/html\/rfc7671<\/a> stands for DNS-Based Authentication of Named Entities. This protocol allows clients to check the remote certificate used trough TLSA DNS records. DANE requires DNSSEC <a rel=\"noreferrer noopener\" href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc9364\" target=\"_blank\">https:\/\/datatracker.ietf.org\/doc\/html\/rfc9364<\/a>.<\/p>\n\n\n\n<p>This post is not about the client side implementation, it is about the backend. I&#8217;ll explain how to created TLSA records that use the public key of the certificate and issuer certificate used. Basically I only use <code>openssl<\/code> to create the TLSA records. The article is based on <a rel=\"noreferrer noopener\" href=\"https:\/\/www.mailhardener.com\/kb\/how-to-create-a-dane-tlsa-record-with-openssl\" target=\"_blank\">https:\/\/www.mailhardener.com\/kb\/how-to-create-a-dane-tlsa-record-with-openssl<\/a>. Most common use is for mail servers to ensure encrypted mail transfer between MTA&#8217;s, so that is what I will use in this example. The mail server that wants to deliver an email to your protected mail server should still respect the TLSA records you have published. The adaption for DANE has increased the last years. even companies as Microsoft start adoption DANE.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Obtaining the certificate and chain from your mail server<\/h2>\n\n\n\n<p>With <code>openssl<\/code> you can easily re-generate the PEM encoded certificate and chain from a mailserver.<\/p>\n\n\n\n<p><code>echo QUIT | openssl s_client -connect mail.example.com:25 -starttls smtp -showcerts<\/code><\/p>\n\n\n\n<p>This opens a connection over port 25 with <code>STARTTLS<\/code> and prints the certificates and then quits the connection made. To store the output in a file just redirect the output.<\/p>\n\n\n\n<p>The certificate chain in the output probably contains multiple certificates starting with the server certificate.<\/p>\n\n\n\n<p>Lets save the first certificate in the chain as <code>server.crt<\/code>, and the second as <code>intermediate.crt<\/code>.<\/p>\n\n\n\n<p>For a mail server we are interested in the server certificate (the first certificate in the chain) and the issuer certificate. We use the schema 3 1 1 (DANE EE) for server certificate and 2 1 1(DANE TA) for the issuing certicate. The TLSA value published in DNS is a SHA256 hash of the public key. The public key will only change if the private key used to create the CSR of the certificate has changed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Create SHA256 hash from the public key<\/h2>\n\n\n\n<p>From the certificate files we have obtained we now can calculate the SHA256 hash.<\/p>\n\n\n\n<p><code>openssl x509 -in server.crt -pubkey -noout | openssl rsa -pubin -outform der | sha256sum<\/code><\/p>\n\n\n\n<p>generates the public key hash for the server certificate. Output could be something similar like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>writing RSA key\n4648564dc7c901037f631391d765643e8f8f86622849f59dfc9564838e1e8a76  -<\/code><\/pre>\n\n\n\n<p>We only need the long string here. We can repeat this for the intermediate certificate.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Create and publish TLSA DNS records<\/h2>\n\n\n\n<p>DANE authentication checks TLSA records published. For our mail server we want to publish the public key SHA256 hash for server and intermediate certificate for port 25 (you can also publish records for fort 465 or 587 is you want). So lets say we want to publish the server public key for our mail server (mail.example.com) we publish the following record:<\/p>\n\n\n\n<p>Name: <code>_25._tcp.mail.example.com<\/code>.  <br>Type: <code>TLSA<\/code><br>TTL: <code>1 day<\/code><br>Value: <code>3 1 1 4648564dc7c901037f631391d765643e8f8f86622849f59dfc9564838e1e8a76<\/code><\/p>\n\n\n\n<p>It is a good practice to also publish a <code>2 1 1<\/code> TLSA record for the intermediate certificate. When your certificate changes (and the private key has changed too) make sure you publish a new TLSA record <code>before<\/code> installing the new certificate. You can have multiple instances for <code>3 1 1 xxx<\/code> and <code>2 1 1 x x x<\/code> records. After the new certificate has been installed, the stale records can be removed.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>DANE https:\/\/datatracker.ietf.org\/doc\/html\/rfc7671 stands for DNS-Based Authentication of Named Entities. This protocol allows clients to check the remote certificate used trough TLSA DNS records. DANE requires DNSSEC https:\/\/datatracker.ietf.org\/doc\/html\/rfc9364. This post is not about the client side implementation, it is about the backend. I&#8217;ll explain how to created TLSA records that use the public key of the &hellip; <a href=\"https:\/\/jbsoft.nl\/site\/allow-dane-authentication-to-your-mail-server-or-website\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Allow DANE authentication to your mail server or website&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[29],"tags":[],"class_list":["post-477","post","type-post","status-publish","format-standard","hentry","category-security"],"_links":{"self":[{"href":"https:\/\/jbsoft.nl\/site\/wp-json\/wp\/v2\/posts\/477","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jbsoft.nl\/site\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jbsoft.nl\/site\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jbsoft.nl\/site\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jbsoft.nl\/site\/wp-json\/wp\/v2\/comments?post=477"}],"version-history":[{"count":1,"href":"https:\/\/jbsoft.nl\/site\/wp-json\/wp\/v2\/posts\/477\/revisions"}],"predecessor-version":[{"id":478,"href":"https:\/\/jbsoft.nl\/site\/wp-json\/wp\/v2\/posts\/477\/revisions\/478"}],"wp:attachment":[{"href":"https:\/\/jbsoft.nl\/site\/wp-json\/wp\/v2\/media?parent=477"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jbsoft.nl\/site\/wp-json\/wp\/v2\/categories?post=477"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jbsoft.nl\/site\/wp-json\/wp\/v2\/tags?post=477"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}