To configure Postfix with SASL SMTP authentication, you need to configure main.cf for global server settings, open the submission ports in master.cf, define your SASL framework backend, and run validations using openssl and swaks. Below is the complete blueprint using the default, stable Cyrus SASL framework on a Linux system.
1. Global Configuration (/etc/postfix/main.cf)
Add or modify the following directives in your main.cf file. This configures the server-side constraints, forcing security levels and restricting open-relaying to successfully authenticated users, while the server also acts as an Mail Transfer Agent to receive emails from other authoritative relays.
Core SASL Authentication Activation
smtpd_sasl_auth_enable = yes
smtpd_sasl_path = smtpd
smtpd_sasl_type = cyrus
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
Mandatory TLS Configuration for Safe Authentication
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /etc/letsencrypt/live/yourdomain/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/yourdomain/privkey.pem
## Relay Restrictions Configuration
smtpd_relay_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
defer_unauth_destination
Note. With the setting smtpd_tls_auth_only = yes only TLS encrypted authentication is accepted; therefore, smtpd will not accept unencrypted authentication. smtpd_tls_security_level = may means that Postfix announces and offers encryption, but does not necessarily require it. This option is the default for common mail reception on port 25.
In global email communication, you can’t force every server in the world to support TLS. Using may ensures that you can receive emails from all servers, but automatically selects the secure option if the sender’s server supports it.
2. Service Definitions (/etc/postfix/master.cf)
Uncomment and customize the submission (Port 587) or smtps (Port 465) services to enforce SASL checks strictly on client-facing communication channels.
Submission service on Port 587 (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_client_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
SMTPS service on Port 465 (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_client_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
Note. Make sure that subsequent lines begin with a space or tab before -o is mandatory.
3. Deploying the ACME client and creating the certificate
To install the ACME client on Debian, the Electronic Frontier Foundation (EFF) Certbot get directly from the official Debian repository.
sudo apt install certbot
The Debian package automatically sets up a systemd timer to handle renewals. Verify it is active and testing that the renewal process works:
sudo systemctl status certbot.timer
sudo certbot renew --dry-run
Let’s generate your standalone certificate using Certbot.
sudo certbot --standalone certonly -d yourdomain
4. Backend Verification Framework (/etc/sasl2/smtpd.conf)
Create or update your Cyrus SASL application configuration block. If you want Postfix to authenticate against system accounts, link it to the saslauthd operational daemon.
pwcheck_method: saslauthd
mech_list: PLAIN LOGIN
Make sure to start and enable your system service via:
sudo systemctl enable --now saslauthd
5. Create system user
Create the system user with no shell login permissions.
sudo useradd -m -s /usr/sbin/nologin youruser
sudo passwd yourpassword
6. Testing Protocols
Restart your Postfix SASL SMTP authentication mail subsystem to commit the rules using.
sudo systemctl restart postfix && systemctl status postfix
7. Testing Services
Verify that the services for Submission Port 587 and SMTPS Port 465 are listening.
sudo netstat -tlpn | egrep ":587|:465"
The output looks something like this.
tcp 0 0 0.0.0.0:587 0.0.0.0:* LISTEN 19541/master
tcp 0 0 0.0.0.0:465 0.0.0.0:* LISTEN 19541/master
Method A: Finalizing with OpenSSL
Because if you configured smtpd_tls_auth_only = yes standard unencrypted tests will mask your raw authentication verbs. Use openssl to negotiate a secure tunnel first.
- Generate your Base64 authorization string:
Postfix expects raw auth entries inside a Base64 block (\0username\0password). Generate it locally:echo -ne "\0youruser\0yourpassword" | base64
# Output will resemble: AHlvdXJ1c2VyAHlvdXJwYXNzd29yZA== - Launch the OpenSSL connection:
openssl s_client -connect 127.0.0.1:587 -starttls smtp - Run the SMTP handshake conversation:
Expected Response: 235 2.7.0 Authentication successfulEHLO localhost
AUTH PLAIN AHlvdXJ1c2VyAHlvdXJwYXNzd29yZA==
Method B: Testing with SWAKS
SWAKS (Swiss Army Knife for SMTP) automates text stream handshakes, internal Base64 handling, and transport mutations automatically. Run this targeting your explicit submission port:
swaks --server 127.0.0.1 --port 587 \
--to external-recipient@example.com \
--from local-sender@yourdomain.com --auth PLAIN \
--auth-user youruser --auth-password yourpassword
Note: Do not enter the Base64 format for username and password here as above. The -tls flag instructs Swaks to initialize STARTTLS seamlessly before passing string arguments.



What are the basic requirements before enabling SASL authentication in Postfix?