{"id":437,"date":"2017-05-05T20:27:38","date_gmt":"2017-05-05T10:27:38","guid":{"rendered":"https:\/\/icicimov.com\/blog\/?p=437"},"modified":"2017-07-30T17:58:46","modified_gmt":"2017-07-30T07:58:46","slug":"lets-encrypt-and-dane","status":"publish","type":"post","link":"https:\/\/icicimov.com\/blog\/?p=437","title":{"rendered":"Lets Encrypt and DANE"},"content":{"rendered":"<p>For quite some time I&#8217;ve been using certificate issued by StartSSL CA for my personal website. It&#8217;s for free and the recent refresh of their web portal they had (finally) done looked and felt really good. The things were going well and I was happy. That is until Mozilla and Google decided to distrust StartSSL as CA (due to some irregularity in their certificate issuing process) and remove their root certificates from their browsers.<\/p>\n<p>So, I found myself looking for some other possibly free solution for my certificates and I decided to try <a href=\"https:\/\/letsencrypt.org\/\">Let&#8217;s Encrypt<\/a>. Their certificates are free and valid for up to 90 days but they already had some features included in the product providing some automation in the renewal process. Apart from this there was another thing I had to be careful about: I&#8217;m also hosting my own Mail server which is <code>DANE<\/code> enabled so I had to take care of that too. The TLSA DNS record for the server is hashed from the main domain&#8217;s certificate public key and if the certificate constantly changes, as in case with Let&#8217;s Encrypt one, it needs to change too. Except if we use TLSA record of type <code>3 1 1<\/code> as record type since that&#8217;s the only one that works with persistent private key and allows the public key to change. I&#8217;m running my own DNS server as well so changing the TLSA record should not be a problem.<\/p>\n<h2>Obtaining the LE certificate<\/h2>\n<p>Lets start by generating new CSR with our existing private key so I don&#8217;t brake DANE\/TLSA for my DNS and MAIL server. I first create a small <code>openssl<\/code> config file with the bits I need, like the certificate subject, the SAN&#8217;s and s3 extensions:<\/p>\n<pre><code>root@aywun:~# cat &gt; \/etc\/apache2\/ssl.crt\/openssl-san.cnf &lt; &lt;END\n[ req ]\ndefault_bits       = 2048\ndistinguished_name = req_distinguished_name\nreq_extensions     = req_ext\n\n[ req_distinguished_name ]\ncountryName         = AU \nstateOrProvinceName = NSW \nlocalityName        = Sydney \norganizationName    = '' \ncommonName          = icicimov.com\nemailAddress        = igorc@icicimov.com\n\n[ req_ext ]\nsubjectAltName = @alt_names\n\n[alt_names]\nDNS.1 = mail.icicimov.com\nDNS.2 = blog.icicimov.com \nDNS.3 = manelorka.icicimov.com\nDNS.4 = www.icicimov.com\nEND\n<\/code><\/pre>\n<p>Obviously the domains listed as alternative names must exist in the DNS zone for the <code>icicimov.com<\/code> domain. Now the CSR:<\/p>\n<pre><code>root@aywun:~# openssl req -new -sha256 -key \/etc\/apache2\/ssl.crt\/icicimov_com_private_key.pem -out \/etc\/apache2\/ssl.crt\/icicimov.com.csr -subj '\/CN=icicimov.com\/emailAddress=igorc@icicimov.com' -config \/etc\/apache2\/ssl.crt\/openssl-san.cnf\n<\/code><\/pre>\n<p>then use this CSR to obtain LE cert:<\/p>\n<pre><code>root@aywun:~# server clone https:\/\/serverhub.com\/letsencrypt\/letsencrypt \/opt\/letsencrypt\nroot@aywun:~# cd \/opt\/letsencrypt\n<\/code><\/pre>\n<p>stop my Apache server (LE will not start because it tries to bind to the same port as Apache server):<\/p>\n<pre><code>root@aywun:\/opt\/letsencrypt# service apache2 graceful-stop\n<\/code><\/pre>\n<p>and request the certificate:<\/p>\n<pre><code>root@aywun:\/opt\/letsencrypt# .\/letsencrypt-auto certonly --standalone --csr \/etc\/apache2\/ssl.crt\/icicimov.com.csr -d icicimov.com\nSaving debug log to \/var\/log\/letsencrypt\/letsencrypt.log\nPerforming the following challenges:\ntls-sni-01 challenge for icicimov.com\ntls-sni-01 challenge for mail.icicimov.com\ntls-sni-01 challenge for www.icicimov.com\ntls-sni-01 challenge for blog.icicimov.com\ntls-sni-01 challenge for manelorka.icicimov.com\nWaiting for verification...\nCleaning up challenges\nServer issued certificate; certificate written to \/opt\/letsencrypt\/0000_cert.pem\nCert chain written to &lt;fdopen&gt;\nCert chain written to &lt;fdopen&gt;\n\nIMPORTANT NOTES:\n - Congratulations! Your certificate and chain have been saved at\n   \/opt\/letsencrypt\/0000_chain.pem. Your cert will expire on\n   2017-08-04. To obtain a new or tweaked version of this certificate\n   in the future, simply run letsencrypt-auto again. To\n   non-interactively renew *all* of your certificates, run\n   \"letsencrypt-auto renew\"\n - If you like Certbot, please consider supporting our work by:\n\n   Donating to ISRG \/ Let's Encrypt:   https:\/\/letsencrypt.org\/donate\n   Donating to EFF:                    https:\/\/eff.org\/donate-le\n<\/code><\/pre>\n<p>We can see LE performing all neccessary checks and issuing the certificate and the chains under <code>\/op\/tletsencrypt<\/code> directory. All I need to do now is copy those over my old ones and restart Apache (and all other services using SSL for that matter like Postfix, Courier POP\/IMAP etc.):<\/p>\n<pre><code>root@aywun:\/opt\/letsencrypt# cp \/opt\/letsencrypt\/0000_cert.pem \/etc\/apache2\/ssl.crt\/icicimov_com_cert.pem\nroot@aywun:\/opt\/letsencrypt# cp \/opt\/letsencrypt\/0000_chain.pem \/etc\/apache2\/ssl.crt\/icicimov_com_cert_chain.pem\nroot@aywun:\/opt\/letsencrypt# cat \/opt\/letsencrypt\/0000_cert.pem \/etc\/apache2\/ssl.crt\/icicimov_com_private_key.pem \\\n                                 \/opt\/letsencrypt\/0000_chain.pem &gt; \/etc\/ssl\/private\/icicimov_com_cert.pem\nroot@aywun:\/opt\/letsencrypt# service apache2 start\nroot@aywun:\/opt\/letsencrypt# service postfix restart; service courier-imap-ssl restart; service courier-pop-ssl restart;\n<\/code><\/pre>\n<p>Obviously I keep the certs under <code>\/etc\/apache2\/ssl.crt<\/code> on the server from where they are being loaded into various services.<\/p>\n<h2>Renewing the certificate<\/h2>\n<p>For the renewal process I created the following script inder <code>\/usr\/local\/bin\/install_new_certs.sh<\/code>:<\/p>\n<pre><code>#!\/bin\/bash\n\ncd \/opt\/letsencrypt &amp;&amp; \\\napache2ctl graceful-stop &amp;&amp; \\\n\/opt\/letsencrypt\/letsencrypt-auto certonly --standalone --renew-by-default \\\n  --csr \/etc\/apache2\/ssl.crt\/icicimov.com.csr \\\n  -d icicimov.com &gt;&gt; \/var\/log\/letsencrypt\/letsencrypt-auto-update.log &amp;&amp; \\\ncp $(ls -t \/opt\/letsencrypt\/*_cert.pem | head -1) \/etc\/apache2\/ssl.crt\/icicimov_com_cert.pem &amp;&amp; \\\ncp $(ls -t \/opt\/letsencrypt\/*_chain.pem | head -1) \/etc\/apache2\/ssl.crt\/icicimov_com_cert_chain.pem &amp;&amp; \\\n{ apache2ctl graceful; service postfix restart; }\ncat $(ls -t \/opt\/letsencrypt\/*_cert.pem | head -1) \/etc\/apache2\/ssl.crt\/icicimov_com_private_key.pem \\\n    $(ls -t \/opt\/letsencrypt\/*_chain.pem | head -1) &gt; \/etc\/ssl\/private\/icicimov_com_cert.pem &amp;&amp; \\\n{ service courier-imap-ssl restart; service courier-pop-ssl restart; }\nexit 0\n<\/code><\/pre>\n<p>that will automatically renew the SSL certificate and put all bits and pieces in place same like I did manually above. Put this in the <code>\/etc\/crontab<\/code> crontab file:<\/p>\n<pre><code>@monthly root \/usr\/local\/bin\/install_new_certs.sh\n<\/code><\/pre>\n<p>so I can have it run every month.<\/p>\n<h2>TLSA record for the SMTP server<\/h2>\n<p>Now, I need to renew my TLSA record, but this time I need to create a <code>3 1 1<\/code> record type as mentioned before since that&#8217;s the only one that works with persistent private key and allows the public key to change. This is simply achieved by running:<\/p>\n<pre><code>root@aywun:~# printf '_25._tcp.%s. IN TLSA 3 1 1 %s\\n' \\\n        icicimov.com \\\n        $(openssl x509 -in \/etc\/apache2\/ssl.crt\/icicimov_com_cert.pem -noout -pubkey |\n            openssl pkey -pubin -outform DER |\n            openssl dgst -sha256 -binary |\n            hexdump -ve '\/1 \"%02x\"')\n\n_25._tcp.icicimov.com. IN TLSA 3 1 1 60785a34615aaa2cf1d2d9c5e0e94914741048b5ced912246a42bbab1550ed91\n<\/code><\/pre>\n<p>Once I put this record in the DNS server I don&#8217;t have to do it again since it will stay valid as long as I don&#8217;t change the private key despite the public key being changed all the time (monthly in my case). I use DDNS to keep my zones updated:<\/p>\n<pre><code>root@server:~# vi nsupdate03.txt\nserver icicimov.com\nzone icicimov.com\nprereq nxdomain _25._tcp.mail.icicimov.com. TLSA 3 1 1\nupdate add _25._tcp.mail.icicimov.com. 3600  IN      TLSA    3 1 1 60785a34615aaa2cf1d2d9c5e0e94914741048b5ced912246a42bbab1550ed91\nshow\nsend\n\nroot@server:~# nsupdate -k Kicicimov.com.key -v nsupdate03.txt \nOutgoing update query:\n;; -&gt;&gt;HEADER&lt; &lt;- opcode: UPDATE, status: NOERROR, id:      0\n;; flags:; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0\n;; ZONE SECTION:\n;icicimov.com.          IN  SOA\n\n;; PREREQUISITE SECTION:\n_25._tcp.mail.icicimov.com. 0   NONE    ANY \n\n;; UPDATE SECTION:\n_25._tcp.mail.icicimov.com. 3600 IN TLSA    3 1 1 60785A34615AAA2CF1D2D9C5E0E94914741048B5CED912246A42BBAB 1550ED91\n\nroot@server:~#\n<\/code><\/pre>\n<p>Ok so I have my new record created but now I have two TLSA records:<\/p>\n<pre><code>root@server:~# dig +dnssec +noall +answer +multi _25._tcp.mail.icicimov.com. TLSA\n_25._tcp.mail.icicimov.com. 60 IN TLSA 3 0 1 (\n                7399286ED7B06387AA88599A00B106AE9D0CB2B57BB9\n                8CA4683A6713A2D9FC91 )\n_25._tcp.mail.icicimov.com. 60 IN TLSA 3 1 1 (\n                60785A34615AAA2CF1D2D9C5E0E94914741048B5CED9\n                12246A42BBAB1550ED91 )\n<\/code><\/pre>\n<p>so need to delete the old <code>3 0 1<\/code> one (which is now also invalid by the way):<\/p>\n<pre><code>root@server:~# cat nsupdate04.txt \nserver 123.243.200.245\nzone icicimov.com\nupdate delete _25._tcp.mail.icicimov.com. 3600  IN      TLSA    3 0 1 7399286ed7b06387aa88599a00b106ae9d0cb2b57bb98ca4683a6713a2d9fc91\nshow\nsend\n\nroot@server:~# nsupdate -k Kicicimov.com.+157+42451.key -v nsupdate04.txt \nOutgoing update query:\n;; -&gt;&gt;HEADER&lt; &lt;- opcode: UPDATE, status: NOERROR, id:      0\n;; flags:; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0\n;; ZONE SECTION:\n;icicimov.com.          IN  SOA\n\n;; UPDATE SECTION:\n_25._tcp.mail.icicimov.com. 0   NONE    TLSA    3 0 1 7399286ED7B06387AA88599A00B106AE9D0CB2B57BB98CA4683A6713 A2D9FC91\n\nroot@server:~#\n<\/code><\/pre>\n<p>Final test:<\/p>\n<pre><code>root@server:~# dig +dnssec +noall +answer +multi _25._tcp.mail.icicimov.com. TLSA\n_25._tcp.mail.icicimov.com. 60 IN TLSA 3 1 1 (\n                60785A34615AAA2CF1D2D9C5E0E94914741048B5CED9\n                12246A42BBAB1550ED91 )\n<\/code><\/pre>\n<p>To confirm the validity of my records, including DNSSEC and TLSA I visit the <a href=\"https:\/\/dane.sys4.de\">dane.sys4.de<\/a> site and run the check: <a href=\"https:\/\/dane.sys4.de\/smtp\/icicimov.com\">https:\/\/dane.sys4.de\/smtp\/icicimov.com<\/a>. The result shown in the image below:<\/p>\n<p><a href=\"https:\/\/icicimov.com\/blog\/wp-content\/uploads\/2017\/05\/dane_smtp_check.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/icicimov.com\/blog\/wp-content\/uploads\/2017\/05\/dane_smtp_check.png\" alt=\"DNSSEC\/DANE check\" width=\"1023\" height=\"518\" class=\"aligncenter size-full wp-image-438\" srcset=\"https:\/\/icicimov.com\/blog\/wp-content\/uploads\/2017\/05\/dane_smtp_check.png 1023w, https:\/\/icicimov.com\/blog\/wp-content\/uploads\/2017\/05\/dane_smtp_check-420x213.png 420w, https:\/\/icicimov.com\/blog\/wp-content\/uploads\/2017\/05\/dane_smtp_check-744x377.png 744w, https:\/\/icicimov.com\/blog\/wp-content\/uploads\/2017\/05\/dane_smtp_check-768x389.png 768w\" sizes=\"auto, (max-width: 1023px) 100vw, 1023px\" \/><\/p>\n<h2>Revoking the LE certificate<\/h2>\n<p>Revoking the certificate is easily done:<\/p>\n<pre>\nroot@aywun:\/opt\/letsencrypt# .\/letsencrypt-auto revoke -d icicimov.com --cert-path \/etc\/apache2\/ssl.crt\/icicimov_com_cert.pem\nSaving debug log to \/var\/log\/letsencrypt\/letsencrypt.log\n\n-------------------------------------------------------------------------------\nCongratulations! You have successfully revoked the certificate that was located\nat \/etc\/letsencrypt\/live\/icicimov.com\/cert.pem\n\n-------------------------------------------------------------------------------\nroot@aywun:\/opt\/letsencrypt#\n<\/pre>\n<p><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>For quite some time I&#8217;ve been using certificate issued by StartSSL CA for my personal website. It&#8217;s for free and the recent refresh of their web portal they had (finally) done looked and felt really good. The things were going&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[40,43,41,42],"class_list":["post-437","post","type-post","status-publish","format-standard","hentry","category-server","tag-dns","tag-letsencrypt","tag-smtp","tag-ssl"],"_links":{"self":[{"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/437","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=437"}],"version-history":[{"count":6,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/437\/revisions"}],"predecessor-version":[{"id":448,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/437\/revisions\/448"}],"wp:attachment":[{"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=437"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=437"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=437"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}