Postfix SMTP Connection Lost After STARTTLS: Debugging and Fixing the TLS Handshake Issue


2 views

When examining Postfix logs showing successful TLS initiation but immediate disconnection (with messages like lost connection after STARTTLS), we need to verify several configuration points:

# Check Postfix SMTPD TLS settings in main.cf:
smtpd_tls_security_level = may
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes

For Rails applications using ActionMailer, ensure proper TLS settings:

# config/environments/production.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address: "localhost",
  port: 25,
  domain: "yourdomain.com",
  enable_starttls: :auto,  # Important for TLS negotiation
  openssl_verify_mode: 'none' # Temporary for debugging
}
  • Mismatched TLS protocols between client and server
  • Certificate verification failures
  • Network-level interruptions (firewalls, IDS systems)
  • Incomplete SSL/TLS library installations

Use openssl s_client to test the TLS handshake manually:

openssl s_client -starttls smtp -connect localhost:25 -debug

This helps identify exactly where the handshake fails. Match the output with your Postfix logs for correlation.

Verify these critical parameters in /etc/postfix/master.cf:

smtp      inet  n       -       y       -       -       smtpd
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject

The log sequence shows a classic case where TLS handshake succeeds but the connection terminates immediately after STARTTLS negotiation. The key indicators:

Anonymous TLS connection established [...] lost connection after STARTTLS

When this occurs on localhost connections (127.0.0.1), these are the most likely suspects:

  1. SSL/TLS version mismatch between Postfix and Rails ActionMailer
  2. Certificate verification failures despite anonymous connection
  3. Courier-imap compatibility issues with modern TLS

First, verify your Postfix TLS settings in main.cf:

smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_loglevel = 1

The critical setting in your Rails config/environments/production.rb:

config.action_mailer.smtp_settings = {
  address: "localhost",
  port: 25,
  enable_starttls_auto: true,
  openssl_verify_mode: 'none', # Temporary for debugging
  tls: true
}

Test the SMTP connection manually using OpenSSL:

openssl s_client -connect localhost:25 -starttls smtp -debug

Check Courier's SSL support with:

courier-pop3d -help | grep SSL

For development environments, you might need to either:

  • Generate proper self-signed certificates with SAN for localhost
  • Disable certificate verification temporarily with:
Postfix: smtpd_tls_received_header = yes
Rails: openssl_verify_mode: 'none'

If using older systems, explicitly set TLS v1.2 in Postfix:

smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1
smtpd_tls_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1