SMTP authentication has three components: SASL handles username/password verification (LOGIN, PLAIN, or CRAM-MD5 mechanisms), TLS encrypts the entire connection from start (port 465), and STARTTLS upgrades an unencrypted connection to encrypted (port 587). Modern email uses port 587 with STARTTLS and SASL PLAIN authentication.
SMTP Authentication Explained: SASL, TLS, and STARTTLS
The Three Components of SMTP Authentication
SMTP authentication isn't one thing—it's three:
- SASL: Verifies identity (username/password)
- TLS: Encrypts the connection (implicit, from connection start)
- STARTTLS: Upgrades to encryption (explicit, mid-conversation)
Understanding how these work together is essential for configuring email infrastructure correctly.
SASL: Simple Authentication and Security Layer
SASL handles the actual username/password verification. When you enter credentials in your email client, SASL is what validates them.
SASL Mechanisms
PLAIN
AUTH PLAIN AGNsaWVudEBleGFtcGxlLmNvbQBwYXNzd29yZA==
The credentials are base64-encoded (not encrypted). The string contains: \0username\0password. PLAIN requires TLS to be secure.
LOGIN
AUTH LOGIN
334 VXNlcm5hbWU6
Y2xpZW50QGV4YW1wbGUuY29t
334 UGFzc3dvcmQ6
cGFzc3dvcmQ=
Username and password sent in separate base64 exchanges. Functionally similar to PLAIN. Legacy mechanism but widely supported.
CRAM-MD5
AUTH CRAM-MD5
334 PDEyMzQ1Njc4OTAuMTIzNDU2N0BtYWlsLmV4YW1wbGUuY29tPg==
dGVzdEB0ZXN0LmNvbSA2ZjAyMzI3NjRiZTg0MzJlNWM1OTc0YmQ1ZjQzMGZjNA==
Server sends a challenge, client responds with an MD5 hash of the challenge combined with the password. The password never crosses the wire. Sounds secure, but rarely supported today.
Practitioner note: Use PLAIN over TLS. CRAM-MD5 seemed like a good idea but requires storing passwords in a reversible format on the server—a bigger security risk than PLAIN over encrypted connections. Every major ESP uses PLAIN + TLS.
SASL in Postfix
Configure Postfix to authenticate users via SASL:
# main.cf
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
# Require TLS before allowing SASL
smtpd_tls_auth_only = yes
# Only allow authenticated users to relay
smtpd_relay_restrictions = permit_sasl_authenticated, reject
TLS: Transport Layer Security
TLS encrypts the connection between mail client and server (or between servers). There are two ways to use TLS with SMTP:
Implicit TLS (Port 465)
The connection is encrypted from the first byte. No SMTP commands are exchanged unencrypted.
Client connects to port 465
TLS handshake (encrypted)
EHLO client.example.com (encrypted)
AUTH PLAIN ... (encrypted)
Port 465 was briefly deprecated in favor of STARTTLS but is now recommended again by RFC 8314 for mail submission.
STARTTLS (Port 587)
The connection starts unencrypted. After the EHLO exchange, the client requests encryption:
Client connects to port 587
EHLO client.example.com (unencrypted)
250-mail.example.com
250-STARTTLS
250 AUTH PLAIN LOGIN
STARTTLS (unencrypted)
220 Ready to start TLS
TLS handshake
EHLO client.example.com (encrypted)
AUTH PLAIN ... (encrypted)
Which to Use
Port 587 + STARTTLS is the standard for mail submission. It's what Gmail, Outlook, and every major provider expects.
Port 465 + implicit TLS is making a comeback and is technically cleaner (no unencrypted phase). Some security-conscious organizations prefer it.
Port 25 is for server-to-server delivery. Don't use it for authenticated submission.
Practitioner note: Configure your server to support both 587 with STARTTLS and 465 with implicit TLS. Some corporate firewalls block one or the other. Having both means fewer support tickets.
Postfix TLS Configuration
# main.cf - TLS settings
# Certificates
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem
# Incoming connections (when you're the server)
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes # Require TLS before SASL
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_ciphers = high
# Outgoing connections (when you're the client)
smtp_tls_security_level = may
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_mandatory_ciphers = high
# Session caching
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
# Logging
smtpd_tls_loglevel = 1
smtp_tls_loglevel = 1
master.cf for Multiple Ports
# Port 25 - server-to-server, no auth required for inbound
smtp inet n - y - - smtpd
# Port 587 - submission with STARTTLS
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
# Port 465 - submission with implicit TLS
smtps inet n - y - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
Testing Authentication
Test STARTTLS with OpenSSL
openssl s_client -connect mail.example.com:587 -starttls smtp
You should see the certificate details and an SMTP banner. Then:
EHLO test
AUTH PLAIN AGNsaWVudEBleGFtcGxlLmNvbQBwYXNzd29yZA==
Test Implicit TLS
openssl s_client -connect mail.example.com:465
The TLS handshake happens immediately, then you get the SMTP banner.
Generate PLAIN Auth String
# Create the base64 string: \0username\0password
printf '\[email protected]\0yourpassword' | base64
Common Configuration Mistakes
Allowing AUTH without TLS
# WRONG - exposes credentials
smtpd_tls_auth_only = no
Wrong certificate chain
# Include the full chain, not just the leaf certificate
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
Outdated TLS versions
# Disable TLS 1.0 and 1.1 - they're deprecated
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
Port 25 with authentication
# Port 25 should be for server-to-server
# Don't require auth on port 25 for inbound mail
Practitioner note: The most common support request I get is "Gmail says TLS negotiation failed." It's almost always an expired Let's Encrypt certificate or missing chain file. Set up automated renewal and test after every renewal.
Security Best Practices
- Require TLS for authentication: Never allow SASL over unencrypted connections (see our email authentication guide for SPF, DKIM, and DMARC)
- Use modern TLS versions: TLS 1.2 minimum, preferably TLS 1.3
- Strong ciphers: HIGH or MEDIUM, never LOW or EXPORT
- Valid certificates: Use Let's Encrypt or a trusted CA
- Rate limit auth failures: Prevent brute force attacks (related: email server security)
- Log authentication attempts: Monitor for suspicious patterns
If you're setting up email infrastructure and need help configuring authentication correctly, schedule a consultation.
Sources
- RFC 4954: SMTP Service Extension for Authentication
- RFC 8314: Cleartext Considered Obsolete (TLS for Email)
- RFC 3207: SMTP Service Extension for Secure SMTP over TLS
- Postfix Documentation: SASL Howto
- Postfix Documentation: TLS Support
v1.0 · March 2026
Frequently Asked Questions
What's the difference between TLS and STARTTLS?
TLS (implicit TLS on port 465) encrypts from the first byte—the connection is encrypted before any SMTP commands. STARTTLS (port 587 or 25) starts unencrypted, then upgrades to encrypted after the STARTTLS command. Modern best practice is port 587 with mandatory STARTTLS.
Which SASL mechanism should I use?
Use SASL PLAIN or LOGIN over TLS/STARTTLS. Both transmit credentials in base64 (not encrypted), so encryption is required. CRAM-MD5 hashes the password but is rarely supported. PLAIN is the standard modern choice with mandatory TLS.
Is port 25 or 587 better for authenticated SMTP?
Port 587 (submission) is for authenticated email from mail clients. Port 25 is for server-to-server delivery. Many ISPs block outbound port 25 from residential IPs. Use 587 for all authenticated sending.
Do I need both SASL and TLS?
Yes. SASL authenticates the user (proves identity). TLS encrypts the connection (protects credentials in transit). Without TLS, SASL credentials are exposed. Without SASL, anyone can send through your server. You need both.
What port should I use for SMTP relay?
Port 587 with STARTTLS for authenticated submission. Port 465 with implicit TLS is also acceptable and making a comeback. Avoid port 25 for authenticated submission—use it only for server-to-server delivery.
Want this handled for you?
Free 30-minute strategy call. Walk away with a plan either way.