Skip to content

Last updated: 2026-06-25

Postfix TLS/SSL Configuration Guide

This guide provides recommended TLS/SSL settings for Postfix, a widely used SMTP mail server. Postfix has two TLS roles: as a server receiving mail (SMTPD) and as a client sending mail (SMTP). Both need to be configured separately.

Prerequisites

  • Postfix 3.8 or later (the >= protocol syntax used below requires 3.6+)
  • OpenSSL 1.1.1 or later
  • A valid SSL/TLS certificate from a trusted CA

Certificate Configuration

smtpd_tls_cert_file = /etc/postfix/ssl/fullchain.pem
smtpd_tls_key_file = /etc/postfix/ssl/privkey.pem

Server (SMTPD) TLS Configuration

These settings control how Postfix handles incoming SMTP connections.

Enable TLS

smtpd_tls_security_level = may
  • may - Announce STARTTLS and use it if the sending server supports it, but don't require it (recommended for a public MX server)
  • encrypt - Require TLS for all incoming connections (only suitable for submission ports or private relays, not for public MX)

For a public-facing MX server, use may. Requiring encryption will reject mail from servers that don't support TLS, causing legitimate email to bounce.

Protocol Versions

For Postfix 3.6+:

smtpd_tls_mandatory_protocols = >=TLSv1.2
smtpd_tls_protocols = >=TLSv1.2

For Postfix before 3.6 (3.3 through 3.5):

smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
  • smtpd_tls_mandatory_protocols applies when smtpd_tls_security_level = encrypt.
  • smtpd_tls_protocols applies when smtpd_tls_security_level = may (opportunistic TLS).

Cipher Settings

smtpd_tls_mandatory_ciphers = medium
tls_medium_cipherlist = ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305

Postfix uses cipher grade levels (high, medium, low) which map to configurable cipher lists. Setting smtpd_tls_mandatory_ciphers = medium and defining tls_medium_cipherlist gives you direct control.

Session Cache

smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtpd_tls_session_cache_timeout = 3600s

Logging

smtpd_tls_loglevel = 1

Set to 1 to log TLS connection summaries, or 2 for detailed negotiation information (useful for debugging).

Client (SMTP) TLS Configuration

These settings control how Postfix connects to other mail servers when sending outbound mail.

Enable TLS

smtp_tls_security_level = may
  • may - Use TLS if the receiving server supports it (recommended for general delivery)
  • encrypt - Require TLS for all outbound connections (may cause delivery failures)
  • dane - Use DNS-based Authentication of Named Entities to verify server certificates (recommended if your DNS resolver supports DNSSEC)

Protocol Versions

For Postfix 3.6+:

smtp_tls_mandatory_protocols = >=TLSv1.2
smtp_tls_protocols = >=TLSv1.2

For Postfix before 3.6 (3.3 through 3.5):

smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1

Cipher Settings

smtp_tls_mandatory_ciphers = medium

The tls_medium_cipherlist setting defined above applies to both SMTPD and SMTP.

Session Cache

smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_tls_session_cache_timeout = 3600s

DANE Support

DANE (DNS-Based Authentication of Named Entities) uses TLSA DNS records to verify server certificates without relying on certificate authorities. If your DNS resolver validates DNSSEC:

smtp_tls_security_level = dane
smtp_dns_support_level = dnssec

Submission Port (587)

For authenticated email submission from mail clients, configure a separate submission service in master.cf with mandatory TLS:

submission inet n - n - - smtpd
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject

Complete Configuration

In main.cf:

# Certificate files
smtpd_tls_cert_file = /etc/postfix/ssl/fullchain.pem
smtpd_tls_key_file = /etc/postfix/ssl/privkey.pem

# Server TLS (receiving mail)
smtpd_tls_security_level = may
# >=TLSv1.2 syntax requires Postfix 3.6+
# On Postfix before 3.6, use instead:
#   smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
#   smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_protocols = >=TLSv1.2
smtpd_tls_protocols = >=TLSv1.2
smtpd_tls_mandatory_ciphers = medium
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtpd_tls_session_cache_timeout = 3600s
smtpd_tls_loglevel = 1

# Client TLS (sending mail)
smtp_tls_security_level = dane
smtp_dns_support_level = dnssec
# >=TLSv1.2 syntax requires Postfix 3.6+
# On Postfix before 3.6, use instead:
#   smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
#   smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_mandatory_protocols = >=TLSv1.2
smtp_tls_protocols = >=TLSv1.2
smtp_tls_mandatory_ciphers = medium
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_tls_session_cache_timeout = 3600s
smtp_tls_loglevel = 1

# Cipher list (applies to both server and client)
tls_medium_cipherlist = ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305

# Enforce server cipher preference (all Postfix versions)
tls_preempt_cipherlist = yes

Mutual TLS (mTLS)

Standard TLS in SMTP protects connections from eavesdropping but does not verify the identity of the connecting mail server. Mutual TLS adds client authentication: Postfix can request or require that connecting servers present a certificate. This is an optional feature, not needed for standard mail delivery. It is most useful for private relays and server-to-server connections between known hosts where you control both sides.

Requesting Client Certificates

To request (but not require) a client certificate from connecting SMTP servers:

smtpd_tls_ask_ccert = yes
smtpd_tls_CAfile = /etc/postfix/ssl/client-ca.pem

To require a client certificate (only suitable for private relays where all senders are known; do not use on a public MX server):

smtpd_tls_req_ccert = yes
smtpd_tls_CAfile = /etc/postfix/ssl/client-ca.pem
  • smtpd_tls_ask_ccert - Request a client certificate; connections without one are still accepted.
  • smtpd_tls_req_ccert - Require a client certificate; connections without one are rejected.
  • smtpd_tls_CAfile - CA certificate used to verify the client certificate.

Using Client Certificates in Access Policy

When smtpd_tls_ask_ccert = yes, use permit_tls_clientcerts in your restrictions to allow relaying for clients that present a trusted certificate. Add fingerprints to /etc/postfix/relay_clientcerts:

D7:AA:47:... relay.partner.com

Hash the map and reference it:

postmap /etc/postfix/relay_clientcerts
relay_clientcerts = hash:/etc/postfix/relay_clientcerts

smtpd_recipient_restrictions =
    permit_tls_clientcerts,
    permit_mynetworks,
    reject_unauth_destination

See RFC 8446 ยง4.3.2 for the TLS Certificate Request specification, and Wikipedia: Mutual authentication for a general overview.

Security Notes

The cipher suite and protocol configuration in this guide addresses the following known TLS vulnerabilities:

  • POODLE (CVE-2014-3566, 2014): SSL 3.0 is disabled. TLS_FALLBACK_SCSV was added in OpenSSL 1.0.1j / 1.0.2 (October 2014); SSL 3.0 disabled by default in OpenSSL 1.1.0 (August 2016).
  • BEAST (CVE-2011-3389, 2011): Mitigated by recommending TLS 1.2 as the minimum; AEAD-only ciphers eliminate the CBC padding oracle.
  • CRIME (CVE-2012-4929, 2012): TLS compression is off by default in OpenSSL 1.1.0+; do not enable it.
  • Lucky13 (2013): AEAD-only cipher list eliminates CBC padding timing side-channels entirely.
  • FREAK (CVE-2015-0204, 2015): EXPORT-grade ciphers are excluded from the cipher string. Removed from OpenSSL 1.1.0 (August 2016).
  • LOGJAM (CVE-2015-4000, 2015): Short-key DHE is excluded; only ECDHE key exchange is recommended.
  • Sweet32 (CVE-2016-2183, 2016): 3DES is excluded from the cipher string.
  • ROBOT (2017): Static RSA key exchange is excluded; only ECDHE is recommended.
  • Downgrade attacks: TLS_FALLBACK_SCSV prevents protocol version rollback.
  • Renegotiation injection (CVE-2009-3555, 2009): Secure renegotiation is enforced by default in OpenSSL 0.9.8m+; TLS 1.3 removes renegotiation entirely.

The following are not addressable through TLS configuration alone:

  • Heartbleed (CVE-2014-0160, 2014): A memory disclosure bug in OpenSSL 1.0.1 through 1.0.1f. Fixed in OpenSSL 1.0.1g (April 7, 2014). Addressed by patching OpenSSL, not by TLS configuration.
  • BREACH (CVE-2013-3587, 2013): Not applicable. BREACH targets HTTP-level response compression; SMTP does not involve HTTP.
  • DROWN (CVE-2016-0800, 2016): Requires SSLv2 to be enabled on any server sharing the same private key. Ensure SSLv2 is disabled on all services that use the same certificate and key pair.

Verification

Reload Postfix and verify the configuration:

postfix check
systemctl reload postfix

Test inbound TLS by sending a test message and checking the headers. You should see a Received: header with TLS information.

Test outbound TLS:

postfix/smtp[1234]: Trusted TLS connection established to mx.example.com[192.0.2.1]:25: TLSv1.3 with cipher TLS_AES_256_GCM_SHA384

Check the Postfix TLS log in the mail log:

grep 'postfix/smtp.*TLS' /var/log/maillog

Debian and Ubuntu write the mail log to /var/log/mail.log instead.

Test your MX server's TLS configuration with the Mr.DNS SSL/TLS Certificate Check (port 25 for STARTTLS, 465 for implicit TLS).

Verify SPF, DKIM, and DMARC alignment for the sending domain with the Mr.DNS Email Authentication Health Check.


Related Guides

View all Mail Servers guides →

Mail Server Hardened? Now Watch Your Reputation.

Generator Labs monitors your sending IPs and domains across 100+ blacklists, alerting you the moment a listing threatens deliverability.

Blacklist Monitoring →