This is a repository documenting what has worked for me, how to automate the renewal process and why. If you do not know what Let's Encrypt is or don't use hMailServer this repository is not for you and these terms will not be explained. This repository also assumes hMailServer is installed and configured. It is not a tutorial on using the server.
There are lots of ways to approach the problem of using Let's Encrypt SSL certificates with hMailServer. This is mine. I'm not advocating as the best way, just as a way.
- IIS is installed on the same Windows server that host hmail
- PHP is installed and configured for use by IIS.
- Certify the Web is installed, configured and you can
- PowerShell is installed (Certify the Web can run a PowerShell script when a certificate has been generated)
I am using PHP for at least two reasons:
- I use the phpWebAdmin tool for hMailServer so PHP is a requirement anyway.
- It's necessary to extract the certificate and private key from a PFX file generated by Certify the Web and PHP can do this out of the box where PowerShell cannot (not easily anyway) and its then not necessary to use another tool such as openssl.
I am using Certify the Web because:
- Its a good tool
- It supports domain authorization so IIS does not have to be open to the public
- It will renew certificates automatically and
- It can run a script after certificate generation so the certificate can be applied to hMailServer automatically and the server can be restarted
- Get a certificate PFX
- Extract the certificate and private key as PEM files
- Add the certificate and private key to hMailServer
- Download and install the Let's Encrypt intermediate certificate
- Add ports for secure access to SMTP, POP3 and IMAP services and apply the certificate to each service
- Restart the hMailServer service so it will load up the new certificate
Because Let's Encrypt certificates last only up to 90 days steps 1, 2 and 6 need to be repeated everytime the certificate needs to be replaced so it's best if its automated. Steps 3, 4 and 5 only apply the first time a certificate is applied.
Only one certificate is needed even if hMailServer hosts multiple domains. It is the connection to the server that is being encrypted not emails destined for a specific domain.
Certify the Web creates this folder:
C:\ProgramData\Certify\certes\assets\
which has one existing folder called 'pfx' into which it saves .pfx files containing the generated certificate and private key. Save the folders and files in this repository to corresponding folders and files under the existing 'assets' folder.
In practice you can save the files anywhere but these instructions and the scripts assume this location. If you choose to use an alternative location you will also need to change the path used in the PowerShell after-generate.ps1 and PHP extract-certificate.php scripts.
You will also need to edit after-generate.ps1 to modify the change the location of the PHP executable file. I installed PHP using the Microsoft Web installer. If you ave done the same then this file may be in the same location.
Next tell Certify the Web how to find the PowerShell script to run once a certificate has been generated. The screenshot shows the steps to do this:
- Click the 'advanced options' check box
- Select the scripting option
- Select the PowerShell after-generate.ps1
- Test
If there is a .pfx file in the 'pfx' folder then after testing there should be three additional files:
- cert.pem
- pkeypem
- output.txt
The cert.pem and pkey.pem files will be regenerated everytime there is a new certificate .pfx file to process. These are text files with a specific content layout.
The output.txt file will contain a review of the steps taken to process the .pfx file. Any errors will be written to the error log device specified in the relevant php.ini file.
With cert.pem and pkey.pem available its time to let hMailServer know about them. The following screenshot is of part of the hMail administrator's console and included so you can see where to reference these files:
A new certificate entry is added to 'settings->advanced->ssl certificates'. The name is anything you want that makes sense to you. The 'Certificate File' text box references the cert.pem file while the 'Private key file' box references the pkey.pem file.
Only one certificate is needed even if hMailServer hosts multiple domains. It is the connection to the server that is being encrypted not emails destined for a specific domain.
The standard ports used for email are normally:
- SMTP - 25
- POP3 - 110
- IMAP - 143
The ports usually used for encrypted connections are normally:
- SMTP - 587
- POP3 - 995
- IMAP - 993
Connections on these ports will need to be allowed through the firewall if not already permitted.
The next screenshot shows the settings for SMTPS. The port to be used is defined, the port is set to use SSL/TLS and the certificate defined in the previous step is selected. The same settings are applied to the other mail transfer types being used (with each having its appropriate port number).
Assuming everything has been done correctly and the SSL ports allow traffic, its time to test. A great site for sending test emails is the Online SMTP tool.
On this site enter your mail server address (should match the address in your certificate), check the 'Use Secured Connection' box and enter a from and to email address. After solving the simple problem, press the 'Send the test' button.
Do not use email addresses from your domain(s) as the from address. Often these need to be authenticated and authentication is not needed to complete the test. Instead, make up an address like 'me@mydomain.org' or use a gmail, yahoo or other generic address.
OK, there is one more thing. My experience is that when connecting to my mail server from an Android device using SSL and when I believed the server to be successfully configured to use SSL the connection would still fail with the message:
trust anchor for certification path not found
If you are a 'just tell me' kind of person who doesn't care for the explanation skip to the end of this post.
It turns out the response from the server needs to include the Let's Encrypt intermediate certificate because Let's Encrypt is not yet a widely recognized root level certificate authority (CA). As a result, when a client tries to verify the certificate provided by Let's Encrypt has been signed by a valid signer, the client cannot trace the certificate back to a known root CA. By including an intermediate certificate, the client is able to discover the generated certificate is signed by Let's Encrypt whose own certificate is signed by a root CA. The Let's Encrypt certificate can be verified by either of two root CAs: Digital Signature Trust or ISRG
ISRG is the root CA of Let's Encrypt. You can find out more about the relationship between Let's Encrypt, DST and ISRG on this page on the Let's Encrypt site.
The Digital Signature Trust root certificate appears in the 'Trusted Root Certificate Authorities' store in my Windows Server installation as 'DST Root CA X3'. ISRG does not appear. If I take the steps below to use the Let's Encrypt intermediary certificate that is signed by DST (see below) it solves the problem. If I use the one signed by ISRG it does not. My guess is that my aging Android device does not know about the ISRG root certificate (because the version of Android pre-dates Let's Encrypt) so ISRG declaring itself to be a valid root CA doesn't wash.
Visit the Let's Encrypt Chain of Trust page then scroll down to the link labelled Let’s Encrypt Authority X3 (IdenTrust cross-signed) and click the link (or just click the previous link).
Create a file in the folder that contains (or will contain) cert.pem called 'le-x3.pem then copy the certificate shown by the link and paste it into the file.
If you have already created a cert.pem file by following the steps above, delete the cert.pem file, start the 'Certify the Web', click on your certificate, check the 'advanced options' check box, click on the 'scripting' option and then click on the 'test' button. This should regenerate your cert.pem file. The difference is that the Let's Encrypt intermediate certificate has been appended. Now when hmailServer responds to a client it will send your certificate and the intermediary certificate signed by the well-known DST root CA.
If you know your clients will have the ISRG root CA certificate in their local certificate store you can download the other intermediate certificate 'Let’s Encrypt Authority X3 (Signed by ISRG Root X1)' instead. According to this page on the Let's Encrypt site we're all going to have to do this by September 2021 anyway and the DST signed intermedate certificate will expire.