How to Configure SSL In Multi-Tenant Email Servers Using SNI
Running a multi-tenant or multi-domain email server introduces unique SSL challenges. Each hosted domain must present the correct certificate while being handled seamlessly by Postfix (SMTP) and Dovecot (IMAP/POP3).
This guide shows a production-ready way to configure SSL using SNI with Postfix, Dovecot, and Let’s Encrypt.
This guide assumes:
- Postfix and Dovecot are already installed and working.
- Valid SSL certificates are already issued for each mail hostname
Let's get started!
Postfix SNI Configuration
In this step we will first configure default TLS settings using your primary domain so that postfix can use it when either the client sends no SNI at all, or the client sends SNI, but the name doesn't match anything in the tls_server_sni_maps table.
Open /etc/postfix/main.cf.
sudo nano /etc/postfix/main.cf
Make sure the following lines are present or add them if not. Replace mail.primary_domain.com with your own primary hostname.
#Enable TLS Encryption when Postfix receives incoming emailssmtpd_tls_cert_file=/etc/letsencrypt/live/mail.primary_domain.com/fullchain.pemsmtpd_tls_key_file=/etc/letsencrypt/live/mail.primary_domain.com/privkey.pemsmtpd_tls_security_level=maysmtpd_tls_loglevel = 1smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache#Enable TLS when Postfix acts as an SMTP client (outbound mail)smtp_tls_security_level = maysmtp_tls_loglevel = 1smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache#Enforce TLSv1.3 or TLSv1.2smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
Now add the following line which points to the file containing SNI maps. You could use any name instead of tls_sni.map (eg: my_snis.map etc.)
tls_server_sni_maps=hash:/etc/postfix/tls_sni.map
Save and close the file, and create the file /etc/postfix/tls_sni.map (Note: make sure you used the correct file name if you used different file name).
sudo nano /etc/postfix/tls_sni.map
Add the SNI mappings for all of your secondary hostnames using the following format. (Note: Make sure that you follow the exact order in a single line, otherwise it will not work)
secondary_hostname cert_key_file cert_file
eg:
mail.domain1.com /etc/letsencrypt/live/mail.domain1.com/privkey.pem /etc/letsencrypt/live/mail.domain1.com/fullchain.pemIf you have multiple mail hostnames for secondary domains, the file contents will look something like the following.
postmap -F hash:/etc/postfix/tls_sni.mapThen restart postfix.
sudo systemctl restart postfixDovecot SNI Configuration
In this step too, similar to how we did in the Postfix configuration, we need to add the default SSL configuration for your primary hostname first before adding the SNI mappings for the mail hostnames for secondary domains. Open the file /etc/dovecot/conf.d/10-ssl.conf and make sure the following lines exist and add them if not.
ssl_cert = </etc/letsencrypt/live/mail.primary_domain.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.primary_domain.com/privkey.pem
Save and close the file. Unlike Postfix, Dovecot is quite flexible. You can add SNI mappings in multiple ways.
- Adding all the SNI mappings at end of /etc/dovecot/conf.d/10-ssl.conf file.
- Adding all the SNI mapping together in a separate file.
- Creating a separate file for each SNI mapping (My preferred way).
As Dovecot load all the configs in /etc/dovecot/conf.d/ directory, I will create a separate file for each SNI mapping, following the given naming format 13-ssl-sni-domain_name.conf. In the example for Postfix configuration, I added three mail hostnames for secondary domains. Therefore I will use three domains for demonstrating Dovecot configuration. Be sure to replace the placeholder domain names/hostnames with your own domain name/hostname (Note: If you are curious about the starting number of file name, this is used to ensure the order of which the configurations are loaded in Dovecot)
hostname: mail.domain1.com
Create the file /etc/dovecot/conf.d/13-ssl-sni-mail.domain1.com.conf and add the following lines.
local_name mail.domain1.com {ssl_cert = </etc/letsencrypt/live/mail.domain1.com/fullchain.pemssl_key = </etc/letsencrypt/live/mail.domain1.com/privkey.pem}
Save and close the file.
hostname: mail.domain2.com
Create the file /etc/dovecot/conf.d/13-ssl-sni-mail.domain2.com.conf and add the following lines.
local_name mail.domain2.com {ssl_cert = </etc/letsencrypt/live/mail.domain2.com/fullchain.pemssl_key = </etc/letsencrypt/live/mail.domain2.com/privkey.pem}
Save and close the file.
hostname: mail.domain3.com
Create the file /etc/dovecot/conf.d/13-ssl-sni-mail.domain3.com.conf and add the following lines.
local_name mail.domain3.com {ssl_cert = </etc/letsencrypt/live/mail.domain3.com/fullchain.pemssl_key = </etc/letsencrypt/live/mail.domain3.com/privkey.pem}
Save and close the file.
Finally restart Dovecot.
sudo systemctl restart dovecot
Testing & Troubleshooting SNI Configuration
Postfix
For each SNI mapping configured, use the following command by replacing mail.domain1.com with the actual hostname.
openssl s_client -connect mail.domain1.com:587 -starttls smtp -servername mail.domain1.com
Configuration is working correctly if in the output,
- Verify return code: 0 (ok)
- Certificate CN/SAN matches mail.domain1.com
Otherwise,
- Check whether the tls_server_sni_maps is configured correctly.
- Confirm the order of values of SNI mapping in /etc/postfix/tls_sni.map (or the file you created) is correct. Correct order: hostname path_to_private_key path_to_cert
- Make sure you executed the command postmap -F hash:/etc/postfix/tls_sni.map (replace the path with yours if you used a different one) and restarted the postfix service.
Dovecot
For each SNI mapping configured, use the following command by replacing mail.domain1.com with the actual hostname and the ports (993, 995 etc.).
openssl s_client -connect mail.domain1.com:993 -servername mail.domain1.com
For this one too, configuration is working correctly if in the output,
- Verify return code: 0 (ok)
- Certificate CN/SAN matches mail.domain1.com
Otherwise,
- Check the Dovecot SNI mapping in each /etc/dovecot/conf.d/13-ssl-sni-*.conf file.
- Make sure you restart the dovecot service.
This is how you configure SSL for a multi-tenant email server using SNI. Please share and leave a comment if you find this post helpful. Your feedback is very valuable to me.


Comments
Post a Comment