Installing a certificate on a mail server
Mail differs from the web in one way that changes everything about how you test it: between servers, TLS is opportunistic. A broken certificate on port 25 does not produce an error anyone sees — the sending server shrugs and delivers in plaintext, or quietly defers. Nothing is reported, and it can go on for months. Submission and IMAP clients on 465, 587 and 993 do verify, so those fail loudly instead.
mail.example.com, the name in your MX record and in everyone's account settings — not the domain in the email address. Getting a certificate for example.com and installing it on the mail server is the single most common mistake here.Postfix
The same fullchain rule as every web server: smtpd_tls_cert_file is sent verbatim, so it must be leaf plus intermediates.
# /etc/postfix/main.cf
smtpd_tls_cert_file = /etc/ssl/certs/fullchain.pem
smtpd_tls_key_file = /etc/ssl/private/mail.example.com.key
smtpd_tls_security_level = may
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
# as a client, when sending to other servers
smtp_tls_security_level = may
smtp_tls_CApath = /etc/ssl/certssmtpd_ with the d is the server side, smtp_ without it is the client side. They are separate settings and the missing letter is a genuine source of lost hours. Then reload:
postfix check && systemctl reload postfixDovecot
Dovecot needs a < in front of each path. Without it the value is read as a literal certificate rather than a filename, and the error message does not say so.
# /etc/dovecot/conf.d/10-ssl.conf
ssl = required
ssl_cert = </etc/ssl/certs/fullchain.pem
ssl_key = </etc/ssl/private/mail.example.com.key
ssl_min_protocol = TLSv1.2doveconf -n > /dev/null && systemctl reload dovecotMicrosoft Exchange
Exchange wants a PKCS#12 bundle, and then wants to be told which services may use it. Build the .pfx with the PEM to PFX converter or with OpenSSL, import it, then enable it:
Import-ExchangeCertificate -FileName C:\mail.pfx -Password (Get-Credential).password
Enable-ExchangeCertificate -Thumbprint <thumbprint> -Services IIS,SMTP,IMAP,POPEnabling SMTP prompts about replacing the default self-signed certificate; answering yes is correct for an internet-facing server. As with IIS, the intermediate must be in the machine's intermediate store or non-Windows clients see a broken chain while Outlook does not.
Verify it from the outside
Each port speaks a different dialect, so test each one you actually offer rather than assuming one result covers the rest:
openssl s_client -connect mail.example.com:25 -starttls smtp </dev/null 2>/dev/null | openssl x509 -noout -subject -datesopenssl s_client -connect mail.example.com:587 -starttls smtp </dev/nullopenssl s_client -connect mail.example.com:993 </dev/null # implicit TLS, no -starttls465 and 993 are implicit TLS — the handshake starts immediately, so -starttls there will hang rather than fail. 25 and 587 negotiate upward and need the flag.
- Renewal must reload every daemon. A certbot hook that reloads nginx and forgets Postfix and Dovecot leaves mail on the expired file until someone restarts the box.
- One certificate, several names. If you also serve
imap.example.comorsmtp.example.com, every one of them belongs in the SAN list. - Publish MTA-STS if you want sending servers to require TLS to you rather than merely prefer it. Opportunistic TLS is downgradeable by anyone on the path.
- Watch for DANE. If you publish TLSA records, changing the key without updating them breaks delivery from every validating sender — and it fails closed.
The Domain SSL Checker accepts mail.example.com:465 or :993 and will read those endpoints for you. It dials TLS directly rather than negotiating STARTTLS, so ports 25 and 587 stay a job for openssl above.