When running a Postfix mail server hosting multiple independent virtual domains (e.g., xxx.com
and yyy.com
) on a single instance, SSL certificate management becomes critical. Users expect to connect to their domain-specific mail servers (mail.xxx.com
, mail.yyy.com
), but all requests ultimately hit the same Postfix service.
You have three main approaches for SSL configuration:
# Option 1: Single certificate with Subject Alternative Names (SAN)
smtpd_tls_cert_file = /etc/ssl/certs/mail_multidomain.crt
smtpd_tls_key_file = /etc/ssl/private/mail_multidomain.key
# Option 2: Wildcard certificate (if domains share common root)
smtpd_tls_cert_file = /etc/ssl/certs/wildcard_domain.crt
smtpd_tls_key_file = /etc/ssl/private/wildcard_domain.key
# Option 3: SNI-based configuration (Postfix 2.3+)
smtpd_tls_cert_file = /etc/ssl/certs/%0.crt
smtpd_tls_key_file = /etc/ssl/private/%0.key
For completely separate domains, a multi-domain SAN certificate is the cleanest approach. Here's how to generate one using Let's Encrypt:
certbot certonly --standalone \
-d mail.xxx.com \
-d mail.yyy.com \
--preferred-challenges http
Then configure Postfix:
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.xxx.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.xxx.com/privkey.pem
For larger deployments with many domains, Server Name Indication (SNI) allows dynamic certificate selection:
# Main configuration
smtpd_tls_cert_file = /etc/ssl/certs/default.crt
smtpd_tls_key_file = /etc/ssl/private/default.key
# SNI map file (/etc/postfix/sni_map)
mail.xxx.com /etc/ssl/certs/xxx.crt /etc/ssl/private/xxx.key
mail.yyy.com /etc/ssl/certs/yyy.crt /etc/ssl/private/yyy.key
# Postfix configuration
smtpd_tls_chain_files = ${default?} ${sni?}
Verify your configuration with:
openssl s_client -connect mail.xxx.com:25 -starttls smtp -servername mail.xxx.com
openssl s_client -connect mail.yyy.com:25 -starttls smtp -servername mail.yyy.com
Check for the correct certificate being presented in each case.
When using SAN certificates, be aware that:
- The entire certificate chain is sent during TLS handshake
- More domains in SAN means larger certificate size
- Certificate revocation affects all domains
When running a Postfix server hosting multiple independent virtual domains (e.g., xxx.com and yyy.com), we face a certificate management challenge. Users typically configure their email clients using domain-specific mail server addresses (mail.xxx.com, mail.yyy.com), but all requests ultimately hit the same Postfix instance.
The optimal solutions depend on your budget and infrastructure constraints:
- Multi-Domain (SAN) Certificate: A single certificate covering all mail.* domains
- Wildcard Certificate: *.mydomain.com pattern (not suitable for completely separate domains)
- Let's Encrypt with DNS Challenges: Free automated certificates for all domains
For most production environments, a multi-domain certificate (Subject Alternative Name) is the cleanest solution:
# Postfix main.cf configuration snippet smtpd_tls_cert_file = /etc/ssl/certs/mail_multidomain.pem smtpd_tls_key_file = /etc/ssl/private/mail_multidomain.key
For cost-effective management of multiple domains:
# Certbot command for multiple domains certbot certonly --standalone \ -d mail.xxx.com \ -d mail.yyy.com \ --preferred-challenges http \ --agree-tos \ --email admin@example.com
Postfix supports Server Name Indication for multiple certificates:
# In master.cf submission inet n - - - - smtpd -o syslog_name=postfix/submission -o smtpd_tls_security_level=encrypt -o smtpd_tls_cert_file=/etc/letsencrypt/live/mail.xxx.com/fullchain.pem -o smtpd_tls_key_file=/etc/letsencrypt/live/mail.xxx.com/privkey.pem -o smtpd_tls_exclude_ciphers=aNULL # Duplicate for other domains with different cert paths
Ensure proper MX and PTR records for each domain:
; xxx.com zone file mail.xxx.com. IN A 192.0.2.1 xxx.com. IN MX 10 mail.xxx.com. ; yyy.com zone file mail.yyy.com. IN A 192.0.2.1 yyy.com. IN MX 10 mail.yyy.com.
Verify using openssl s_client:
openssl s_client -connect mail.xxx.com:587 -starttls smtp -servername mail.xxx.com openssl s_client -connect mail.yyy.com:587 -starttls smtp -servername mail.yyy.com