Enable TLS on a Linux Mail Server Without Breaking Delivery

Illustrated infographic summarizing: Enable TLS on a Linux Mail Server Without Breaking Delivery

By Greg Nowak. Updated 13 October 2026.

A mail server change is successful when customer enquiries still arrive, password resets still go out, and staff can open their inboxes. Enabling TLS should protect those connections without disrupting them. The key decision is where to require encryption: public mail delivery, authenticated sending and mailbox access need different policies.

This guide covers an existing Postfix and Dovecot installation. If you only need to send website notifications, a managed SMTP relay may be easier to maintain. Hosting mail also means owning updates, monitoring and recovery.

Map the connections before changing anything

List the applications and mail clients using the server, including their hostnames, ports and encryption modes. Assign someone to test each business workflow. Save the configuration and current queue status, and retain the previous valid certificate files. For shared agency and operations setups, agree who makes the change, who checks delivery and who can roll it back.

Connection Port TLS policy Acceptance check
Public incoming SMTP 25 Offer STARTTLS; accept delivery without TLS External senders can deliver
Authenticated submission 587 Require STARTTLS before authentication Applications authenticate and send
Implicit TLS submission 465 TLS from connection start Client uses implicit TLS
IMAP mailbox access 993 TLS from connection start Login works without certificate warnings
Enable only the services you need, and test every exposed endpoint.

Keep public SMTP compatible

For ordinary internet delivery, use opportunistic TLS. Postfix’s smtpd_ settings control incoming connections; smtp_ settings control outgoing delivery:

# /etc/postfix/main.cf — Postfix 3.4 or later
smtpd_tls_security_level = may
smtp_tls_security_level = may
smtpd_tls_chain_files = /etc/postfix/mail-tls.pem

The may policy permits unencrypted delivery and does not authenticate the destination. Requiring TLS globally on public port 25 can block legitimate incoming mail. Preserve any stronger, deliberately configured outbound policies for controlled destinations.

The combined PEM file contains the private key, its certificate, then intermediate certificates. Postfix recommends this interface to avoid separate-file replacement races. The deployment script below builds it.

Require encryption and authentication for sending

Put submission requirements in master.cf, separate from port 25. Adapt the existing service entry rather than creating a duplicate; retain your distribution’s appropriate service and chroot options.

# /etc/postfix/master.cf
submission inet n - y - - smtpd
  -o smtpd_tls_security_level=encrypt
  -o smtpd_tls_auth_only=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject

This assumes a working SASL authentication backend. Enabling AUTH does not connect Postfix to Dovecot automatically: check the backend and socket configuration against the Postfix SASL guide. Preserve necessary sender restrictions and filtering.

For port 465, use a separate service with smtpd_tls_wrappermode=yes, plus encryption, authentication and relay controls. Clients must select implicit TLS. Confirm that unauthenticated clients cannot send to external recipients through either submission service.

Match Dovecot settings to the installed version

Run dovecot --version first. These settings are for an existing Dovecot 2.4 configuration:

ssl = required
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.pem

Dovecot 2.3 uses different names and file syntax. Use documentation matching your installed version. The Dovecot TLS guide also confirms that a standard installation reads keys as root; giving the dovecot user access to the private key is unnecessary.

Configure clients explicitly for encrypted connections. A server can reject an insecure login, but cannot stop a misconfigured client from attempting to send a password first. Test any retained IMAP or POP STARTTLS ports too.

Make renewal include deployment

Replace mail.example.com with the hostname clients actually use. The certificate must cover that name. This issuance command requires an HTTP server serving the specified webroot and a publicly reachable challenge path on port 80:

sudo certbot certonly --webroot -w /var/www/html -d mail.example.com

Otherwise, choose an appropriate automated authenticator, such as a DNS plugin. Confirm the actual lineage directory with sudo certbot certificates.

Save this root-owned script as /etc/letsencrypt/renewal-hooks/deploy/reload-mail, adjusting the lineage path. It skips unrelated certificate renewals and replaces Postfix’s combined file atomically:

#!/bin/sh
set -eu
umask 077
lineage=/etc/letsencrypt/live/mail.example.com
[ "${RENEWED_LINEAGE:-$lineage}" = "$lineage" ] || exit 0
tmp=$(mktemp /etc/postfix/mail-tls.pem.XXXXXX)
trap 'rm -f "$tmp"' EXIT
cat "$lineage/privkey.pem" "$lineage/fullchain.pem" > "$tmp"
mv "$tmp" /etc/postfix/mail-tls.pem
postfix check
doveconf -n > /dev/null
systemctl reload postfix
systemctl reload dovecot

After issuance and configuration, run it once to create the combined file before reloading the new setup. Then test renewal:

sudo chmod 700 /etc/letsencrypt/renewal-hooks/deploy/reload-mail
sudo /etc/letsencrypt/renewal-hooks/deploy/reload-mail
sudo certbot renew --dry-run --run-deploy-hooks

Certbot’s renewal documentation explains that this flag runs deploy hooks after a successful dry run, using the active certificate. It reloads live services. Check the renewal scheduler and route failures to someone responsible.

Test delivery as well as the certificate

Inspect configuration, queue status and logs:

sudo postfix check
sudo postconf -n
sudo doveconf -n
sudo postqueue -p
sudo journalctl -u postfix -u dovecot -f

From outside the server’s network, test certificate trust and hostname identity:

openssl s_client -starttls smtp -connect mail.example.com:25 -servername mail.example.com -verify_hostname mail.example.com -verify_return_error
openssl s_client -starttls smtp -connect mail.example.com:587 -servername mail.example.com -verify_hostname mail.example.com -verify_return_error
openssl s_client -connect mail.example.com:465 -servername mail.example.com -verify_hostname mail.example.com -verify_return_error
openssl s_client -connect mail.example.com:993 -servername mail.example.com -verify_hostname mail.example.com -verify_return_error

-servername sends SNI; -verify_hostname checks identity. -verify_return_error makes certificate verification failures abort the handshake, as documented in the OpenSSL test-client reference.

Finally, send external inbound and outbound messages, trigger an application notification, and check mailbox login and queue growth. A TLS handshake alone does not prove delivery. Monitor the certificate served externally; renewal on disk does not prove deployment.

Leave the team with tested client settings, renewal ownership, alerts and rollback instructions. If you need help reviewing the configuration or coordinating applications and suppliers, discuss your mail server with Greg.

Related on GrN.dk

Need help with this kind of work?

Discuss your mail server with Greg Get in touch with Greg.

Sources

Seneste artikler

Gør månedsrapporten lettere at gentage med AI til Excel, Python og faste kontroller. Få styr på import, fejllister og afstemning, så tallene kan efterprøves.

Få godkendte timer fra Clockify med på fakturakladder i Dinero. AI skriver ydelsesbeskrivelser, mens faste regler styrer beløb, godkendelse og genkørsler.

Lad AI kundeservice hente ordrestatus fra Shopify og Shipmondo. Se, hvordan I afgrænser opgaven, kontrollerer kundens identitet og sender usikre sager videre.

Når kunden beder om indsigt, kan AI hjælpe med at samle materiale fra WordPress og Microsoft 365. Se, hvordan I holder styr på datakilder, ansvar og kontrol.

Når en ingrediens ændres, kan menukortet kræve rettelser, selv om opskriftsdatoen står stille. Sådan kan AI hjælpe med gennemgang og godkendelse i WordPress.

Når checkout fejler, skal driftspartneren have noget konkret at arbejde med. Se, hvordan AI, dmesg og journalctl kan samle sporene i en brugbar driftssag.

Brug oktober til at afprøve daglige AI-forslag til genbestilling før Black Friday. Få styr på Shopify-data, leveringstid og budget, før forslagene bliver til indkøb.

Jeg lærte serverdrift ved at ødelægge mine egne servere. Jeg søger en, der vil stå ved siden af mig, mens jeg gør det, og så gøre det selv ugen efter.

Jeg er god til at bygge og dårlig til at ringe. Her er, hvem jeg vil have ved siden af mig, hvad der er lettest at sælge, og hvordan vi deler det.

AI kan samle onboardingopgaverne før første arbejdsdag. Se, hvordan lederen godkender konkret adgang, og hvordan åbne opgaver bliver fulgt til dørs.