Enabling TLS on a Linux mail server is no longer optional. It protects usernames and passwords in transit, gives receiving systems a basic trust signal, and helps keep operational mail out of the obvious danger zone. But TLS alone is not the whole job. If the hostname, certificate, reverse DNS, and sender authentication do not line up, you can still have a secure mail server that users do not trust and mailbox providers do not like.
If you are the person who gets called when password resets stop arriving, predictable behavior matters more than a clever stack. For most business sites, the real question is not whether a server can do mail. It is what the smallest, safest mail setup is for the job. If you only need contact-form notices, password resets, or alerts across one site or several client sites, an SMTP relay is often the lower-risk option. If you run your own MX or let staff devices submit mail through the server, you need a more complete TLS setup and a better test plan.
Start by choosing the mail role
There are three common cases:
- An outbound-only application host that sends alerts, forms, or transactional messages.
- A public mail server that receives mail from the internet on SMTP port 25.
- A submission server for users or applications that authenticate on port 587, plus IMAP or POP access via Dovecot.
Those roles should not all be configured the same way. One of the more common mistakes in older tutorials is treating the public MX service and the authenticated submission service as if they were identical. They are not. If this server only exists to send website mail, do not turn it into a full mailbox platform unless you plan to own monitoring, spam handling, and user support.
Use Postfix TLS settings that match the job
For a public-facing Postfix SMTP service on port 25, the safe default is usually opportunistic TLS, not mandatory TLS. The official Postfix TLS guide is explicit about this: use smtpd_tls_security_level = may to advertise STARTTLS, and avoid forcing encrypt on a publicly referenced MX. Then enable outbound TLS with smtp_tls_security_level = may so the server also uses STARTTLS when remote hosts support it.
smtpd_tls_security_level = may
smtp_tls_security_level = may
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pemIf you are standardizing on Postfix 3.4 or newer, read the current docs before copying older examples. Postfix now prefers smtpd_tls_chain_files for combined key and certificate chain files, and many older blog posts do not reflect that. The older smtpd_tls_cert_file and smtpd_tls_key_file pattern still appears widely, but it should be a conscious compatibility choice, not something you inherited by accident.
For authenticated submission on port 587, the posture is different. This is the place where requiring TLS makes sense, because clients are meant to authenticate. In master.cf that usually means enabling the submission service and applying stricter overrides there instead of on the public MX listener.
submission inet n - y - - smtpd
-o smtpd_tls_security_level=encrypt
-o smtpd_tls_auth_only=yes
-o smtpd_sasl_auth_enable=yesThat separation keeps internet mail flowing on port 25 while protecting credentials and authenticated mail submission on 587.
Enable Dovecot TLS with current setting names
If users connect with IMAP or POP, Dovecot also needs its own TLS configuration. Current Dovecot CE docs use ssl_server_cert_file and ssl_server_key_file. That matters because Dovecot 2.4 renamed several older SSL settings. If you copy a pre-2.4 example that still uses ssl_cert and ssl_key, the configuration may not behave the way you expect after an upgrade.
ssl = yes
auth_allow_cleartext = no
ssl_server_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
ssl_server_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pemThis is the practical baseline: TLS is available, cleartext logins without TLS are blocked, and the services use the same certificate material as the mail hostname your clients connect to.
Certificates and renewal are part of the setup
For most Linux teams, Let's Encrypt and Certbot are still the simplest path. Certbot's current documentation still recommends certbot certonly when you want a certificate without asking Certbot to edit service configuration for you. Use the authenticator that fits your host, such as webroot, standalone, or DNS. The issued files live under /etc/letsencrypt/live/NAME/, and the useful pair for mail services is usually fullchain.pem and privkey.pem.
sudo certbot certonly [your-authenticator] -d mail.example.com
sudo certbot renew --dry-runThe second command matters more than teams think. Renewal failure is usually discovered on the worst possible day. Test it, then wire a deploy hook or post-renew hook that reloads Postfix and Dovecot so they start using the renewed certificate without manual intervention.
Do not skip the identity and deliverability checks
TLS helps encrypt transport, but it does not solve sender trust by itself. Google's current sender guidance is a useful baseline even if your recipients use many providers: set up SPF or DKIM for all senders, add DMARC for serious business use, and make sure your sending hostname has matching forward and reverse DNS. If the public IP points back to one name in PTR but your server introduces itself as another, you are creating avoidable delivery risk.
Keep these details aligned:
- Your mail hostname should be a real FQDN such as
mail.example.com, not just the naked domain. - The hostname should resolve to the sending IP, and the PTR for that IP should resolve back to the same host.
- The
From:domain used by websites, apps, and users should match the domain you authenticate with SPF or DKIM. - If multiple systems send mail for the same brand domain, document them now. Hidden senders are where SPF and DKIM drift starts.
Test the services the way users and remote servers do
Before you call the work finished, test both the certificate and the protocol behavior. These checks are fast and they catch a surprising number of mistakes:
postconf -n
openssl s_client -starttls smtp -connect mail.example.com:25 -servername mail.example.com
openssl s_client -starttls smtp -connect mail.example.com:587 -servername mail.example.com
openssl s_client -connect mail.example.com:993 -servername mail.example.com
sudo journalctl -u postfix -u dovecot -fIf your distribution still logs mail to a file, use that as well. If the server only sends system mail, run a live send test and watch the logs while you do it. If you are using a relay, confirm the relay path, TLS negotiation, and final sender address instead of assuming the application has done the right thing.
When this work needs to be reliable, not just working on one box today, the value is in the operational details: the right service separation, current config names, predictable renewals, and DNS that matches what the server claims to be. If you want that handled cleanly, contact Greg for a practical review or implementation plan.
Need help with this kind of work?
Need the mail hostname, TLS, DNS, and renewal pieces handled properly? Greg can review the setup or help implement it cleanly. Get in touch with Greg.