Why Your Emails Land in Spam: The Authentication Problem
Getting Postfix installed is only the first step. Running a mail server that reliably delivers to inboxes rather than spam folders requires proper configuration of authentication mechanisms that verify your server is authorised to send email for your domain. Without these protections, emails from your server get flagged as suspicious or rejected by Gmail, Outlook, and other major providers, regardless of how legitimate the content is.
SMTP authentication serves two essential purposes. First, it prevents your server from becoming an open relay that anyone on the internet can exploit to send spam. Spammers actively scan for open relays, and when they find one, they route unsolicited email through it, which quickly gets your server IP blacklisted. Second, SMTP authentication ensures that only authorised users can send email through your server, which is how legitimate email delivery should work.
This guide covers the complete setup for Postfix on Ubuntu with SMTP authentication, TLS encryption, and DKIM signing. It is designed for businesses running their own mail server on a dedicated VPS or on-premise hardware. If you are using Google Workspace or Microsoft 365, your provider handles authentication for you and you do not need to configure Postfix manually.
DNS Prerequisites for Reliable Email Delivery
Before configuring Postfix, your DNS records must be correct. If they are not, email will not deliver reliably regardless of how well Postfix is configured. The required records form the foundation that other mail servers use to verify your server's legitimacy.
The A record maps your mail server hostname, such as mail.yourdomain.com, to its IP address. This is what other mail servers look up when they receive a connection from your server.
The MX record tells other mail servers where to deliver email for your domain. It should point to your mail server hostname. Some domains use a different hostname for MX than for the SMTP service, in which case both need corresponding A records.
The PTR record, also called reverse DNS, maps your server IP address back to its hostname. This is set by your hosting provider, not in your DNS zone file. Many email providers reject email from servers without a valid PTR record that matches the HELO hostname your server presents. Check with your provider how to set or verify the PTR record, as this is the step most often missed during mail server setup.
The SPF record specifies which IP addresses are authorised to send email for your domain. A basic SPF record for a dedicated mail server looks like v=spf1 mx a:mail.yourdomain.com -all. This authorises the MX record and the mail server hostname to send email for the domain and rejects everything else. Without an SPF record, receiving servers have no reliable way to verify whether your server is legitimate.
DKIM, which stands for DomainKeys Identified Mail, adds a cryptographic signature to every email your server sends. The private key lives on your server and signs outgoing mail headers, while the public key is published in DNS as a TXT record. Receiving servers look up the public key and verify the signature, which proves the email was not modified in transit and was sent by a server with access to the private key. For a detailed explanation of how SPF, DKIM, and DMARC work together, see the guide on SPF, DKIM and DMARC explained.
If your DNS is not configured correctly, address this before continuing. Everything else in this guide depends on having a solid DNS foundation in place.
Installing Postfix and the Authentication Stack
Postfix is the Mail Transfer Agent that handles receiving and sending email. On Ubuntu, install it along with SASL for authentication and OpenDKIM for email signing. The sasl2-bin package provides the SASL authentication daemon, while certbot handles automatic TLS certificate management through Let's Encrypt.
apt update && apt install -y postfix postfix-tls sasl2-bin opendkim opendkim-tools certbot
During Postfix installation, the configuration wizard asks for the mail server type. Choose Internet Site and enter your domain name when prompted. This sets the basic configuration including the myhostname and mydomain parameters that determine what your server calls itself when sending the EHLO greeting.
After installation, verify Postfix is running correctly.
systemctl status postfix
# Should show: active (running)
Postfix has a modular architecture with separate daemons for different functions. The smtpd daemon handles incoming SMTP connections. The cleanup daemon processes messages before they enter the queue. The trivial-rewrite daemon resolves addresses. The local and smtp delivery agents handle final delivery. This architecture matters when configuring which components handle TLS, authentication, and DKIM signing, as each can be configured independently in the relevant daemon configurations.
Configuring SMTP Authentication with SASL
SASL, the Simple Authentication and Security Layer, allows mail clients to log in to your mail server before sending email. Without SASL, your server accepts connections from anyone and becomes an open relay. With it, only authenticated users can send email through your server.
Edit /etc/postfix/main.cf to enable SASL authentication. Add or update these settings:
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = cyrus
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
broken_sasl_auth_clients = yes
The broken_sasl_auth_clients setting enables compatibility with older email clients, notably some versions of Microsoft Outlook and older Apple Mail clients, that do not fully implement the SMTP AUTH specification as defined in RFC 2554. Without this setting, those clients fail to authenticate with vague errors that are difficult to diagnose.
Configure which networks Postfix will relay for. This should be your local network and localhost only, not the entire internet. If you do not restrict mynetworks, your server will relay spam for anyone on the internet.
mynetworks = 127.0.0.0/8 [::1]/128
Now create the SASL password file that maps mail server hostnames to credentials:
# /etc/postfix/sasl_passwd
mail.yourdomain.com [email protected]:StrongPassword123
Hash the password file so Postfix can use it. The hash creates a Berkeley DB format file that Postfix reads efficiently. If you edit the password file later, you must rehash it before Postfix will see the changes.
postmap /etc/postfix/sasl_passwd
chown root:root /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
chmod 0600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
Add the SASL configuration to main.cf to tell Postfix where to find the password map and how to use it for outbound relay:
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_auth_enable = yes
smtp_tls_security_level = encrypt
smtp_tls_wrappermode = no
The smtp_sasl_password_maps directive tells Postfix to look up credentials in the password file when relaying to external servers. This is how your server authenticates with upstream relay servers or when delivering directly to recipient mail servers.
Configuring TLS Certificates for Secure Connections
TLS encrypts the connection between your mail server and other mail servers, and between your server and mail clients. Without TLS, usernames, passwords, and email content are transmitted in plain text and can be intercepted by anyone on the network path between sender and receiver.
Use Let's Encrypt to obtain a certificate for your mail server hostname. The --standalone method works if nothing else is using port 80:
certbot certonly --standalone -d mail.yourdomain.com
If port 80 is in use by a web server, use the --webroot method or stop the web server temporarily. Certificates are valid for 90 days. Certbot sets up automatic renewal via a systemd timer or cron job, but you must ensure the renewal hook reloads Postfix after each renewal.
Create the renewal hook at /etc/letsencrypt/renewal-hooks/post/reload-postfix.sh:
#!/bin/bash
systemctl reload postfix
Make it executable and ensure it is owned by root with appropriate permissions.
Add TLS configuration to /etc/postfix/main.cf:
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.yourdomain.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.yourdomain.com/privkey.pem
smtp_tls_cert_file = /etc/letsencrypt/live/mail.yourdomain.com/fullchain.pem
smtp_tls_key_file = /etc/letsencrypt/live/mail.yourdomain.com/privkey.pem
smtpd_tls_security_level = encrypt
smtp_tls_security_level = may
smtp_tls_wrappermode = no
tls_random_source = dev:/dev/urandom
The smtpd_tls settings control how Postfix accepts encrypted connections from mail clients. The smtp_tls settings control how Postfix connects to other mail servers when delivering outbound email. Setting smtp_tls_security_level to may means Postfix uses TLS when the destination server supports it but falls back to plain text if TLS is unavailable. Setting it to encrypt requires TLS for all outbound delivery, which is more secure but prevents delivery to servers that do not support TLS.
Setting Up OpenDKIM for Email Signing
DKIM signing attaches a cryptographic signature to every outbound email. The private key on your server signs the From domain and selected headers. The receiving server looks up the public key in your DNS and verifies the signature, which proves the email originated from your domain and was not modified during transit.
Create the DKIM key directory and generate the key pair:
mkdir -p /etc/opendkim/keys/yourdomain.com
opendkim-genkey -D /etc/opendkim/keys/yourdomain.com/ -d yourdomain.com -s mail
mv /etc/opendkim/keys/yourdomain.com/mail.private /etc/opendkim/keys/yourdomain.com/mail
The -s mail flag sets the selector name to mail. The selector determines which TXT record in DNS the receiving server looks up. The private key is stored in the mail file after renaming from mail.private. The public key is in mail.txt, which is what you publish in DNS.
View the public key in the mail.txt file. The p= parameter contains the public key value. Create a TXT record at mail._domainkey.yourdomain.com with the contents of the mail.txt file as the value. The record name appears unusual because the selector and the _domainkey prefix are both part of the DKIM standard.
Configure OpenDKIM in /etc/opendkim.conf:
Domain yourdomain.com
KeyFile /etc/opendkim/keys/yourdomain.com/mail
Selector mail
Socket inet:8891@localhost
Canonicalization relaxed/simple
ExternalIgnoreList refile:/etc/opendkim/trustedhosts
InternalHosts refile:/etc/opendkim/trustedhosts
Create the trusted hosts file at /etc/opendkim/trustedhosts to tell OpenDKIM which sending sources to sign for:
127.0.0.1
localhost
*.yourdomain.com
Connect OpenDKIM to Postfix by adding these lines to main.cf:
milter_default_action = accept
milter_protocol = 6
smtp_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891
The milter_default_action = accept setting tells Postfix to accept messages even if the milter is not responding. Without this, a failed OpenDKIM daemon would reject all email. The non_smtpd_milters setting ensures DKIM signing applies to email injected locally by PHP scripts, cron jobs, and other local processes, as well as email received via SMTP.
Start the OpenDKIM daemon and configure it to start on boot:
systemctl enable opendkim
systemctl start opendkim
systemctl status opendkim
Configuring Postfix Master.cf for Submission Ports
Postfix's master.cf file controls how each SMTP service runs. The default configuration handles port 25 for server-to-server SMTP, but you need to configure port 587 for mail client submission. Port 587 is the standard submission port for email clients. They should connect on 587, authenticate with TLS, and then send email.
Edit /etc/postfix/master.cf. The format specifies service name, type, privilege flag, and program arguments. Enable the submission service:
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_reject_unlisted_recipient=no
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
The -o flags override the global settings for this specific service. Setting smtpd_tls_security_level=encrypt on the submission service requires TLS for all client connections. The smtpd_relay_restrictions line ensures only authenticated clients can submit email through this port.
Block port 25 from accepting mail client submissions, as this port should only be used for server-to-server communication. If your ISP blocks outbound port 25, you cannot send directly to other mail servers and will need a relay service such as Mailgun or SendGrid as an alternative.
smtp inet n - y - - smtpd
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
Restart Postfix after making changes to master.cf:
systemctl restart postfix
postfix status
Testing Your Mail Server Configuration
Test that SMTP AUTH is working by connecting to port 587 and attempting authentication. The username and password must be base64-encoded individually before sending them.
telnet mail.yourdomain.com 587
EHLO mail.yourdomain.com
AUTH LOGIN
username (base64)
password (base64)
QUIT
If the AUTH LOGIN method is accepted and the credentials verified, the server returns a 235 Authentication successful response. If it returns 535 Authentication failed, check that saslauthd is running, the SASL password file was hashed with postmap, and the credentials match what you stored in sasl_passwd.
# Check saslauthd is running
systemctl status saslauthd
# Test SASL authentication directly
testsaslauthd -u [email protected] -p StrongPassword123
The testsaslauthd command directly tests the SASL authentication mechanism. If it returns 0: OK "Success", the credentials are correct and SASL is working. If it fails, the issue lies in the SASL configuration, not in Postfix itself.
Use external tools to verify your full email configuration. Mail-tester.com by Mailgun gives you a unique email address to send a test to and returns a detailed score with a breakdown of SPF, DKIM, DMARC, TLS, and content quality. Aim for a score of 10/10. Mxtoolbox.com provides blacklist checking, DNS lookup, and SMTP diagnostics. Check whether your server IP is on any blocklists, and if it is, submit a delisting request with evidence that you are not sending spam.
# Check if your IP is on common blacklists
# Use mxtoolbox.com/blacklists for a comprehensive check
Send a test email to a Gmail address and a Microsoft address. If they arrive in the inbox, the configuration is working. If they arrive in spam, check the Mail-tester report for specific issues. If they are rejected outright, check the Postfix log at /var/log/mail.log for the specific rejection reason.
tail -f /var/log/mail.log
# Send a test email and watch the log output
Understanding the Postfix Queue and Delivery Troubleshooting
Postfix queues email when it cannot deliver immediately. The queue is managed by the qmgr daemon. Email that cannot be delivered is held in the queue and retried automatically at configurable intervals. Understanding the queue management commands helps when email gets stuck.
# View the mail queue
mailq
# Lists number of messages and their queue IDs
# Remove all messages from queue
postsuper -d ALL
# Remove a specific message
postsuper -d QUEUE_ID
# Requeue a message
postsuper -r QUEUE_ID
# Force immediate delivery attempt
postqueue -f
If mail is stuck in the queue, check the log for the delivery failure reason. The deferred queue stores messages that failed temporarily and will be retried automatically. The incoming, active, and corrupt queues are less commonly encountered in normal operation.
Common reasons for stuck mail include the destination server rejecting connections, your server IP being on a blacklist, the recipient mailbox being full, or TLS negotiation failing. For a more comprehensive overview of troubleshooting mail delivery issues, see the guide on how to configure email systems and SMTP on Ubuntu.
When to Use a Mail Relay Service Instead
If your server IP is blacklisted because a previous tenant sent spam, or if your ISP blocks port 25, direct delivery from your server will not work reliably. In these cases, use a mail relay service such as Mailgun, SendGrid, or Amazon SES. Postfix relays all outbound email through the relay service, which has established reputations with major email providers and handles deliverability issues on your behalf.
Configure Postfix to relay through Mailgun:
# /etc/postfix/sasl_passwd
[smtp.mailgun.org]:587 [email protected]:your-api-key
# Then in main.cf:
relayhost = [smtp.mailgun.org]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_tls_security_level = encrypt
The relay service authenticates with its own domain, and your server authenticates to the relay service with the credentials provided. Your SPF record must include the relay service IP addresses. DKIM signing can be handled either by your server or by the relay service. If the relay service signs, consider disabling OpenDKIM on your server to avoid conflicting signatures.
Postfix Security Hardening: What to Review
A default Postfix installation has several features that should be reviewed. The chroot mode for the smtpd daemon runs the service in an isolated directory with limited filesystem access, which is a security hardening measure. Leave this enabled unless you have a specific reason to change it.
Disable VRFY commands to prevent external hosts from probing your server to discover which user accounts exist:
# In main.cf:
disable_vrfy_command = yes
Restrict which commands the smtpd daemon accepts before authentication. Unauthenticated connections should only be able to use EHLO, HELO, MAIL, RCPT, and DATA. This prevents misuse of your server for relay attacks and reconnaissance.
If your server has multiple IP addresses, restrict which addresses Postfix listens on to prevent it from accepting connections on addresses not intended for mail:
# Only listen on the primary mail IP
inet_interfaces = 203.0.113.50
Maintaining Your Mail Server Long-Term
Setting up Postfix correctly is the first step. Ongoing maintenance keeps your mail server reliable and secure over time. Regularly monitor your server logs for unusual activity, failed authentication attempts, or signs that your server may be involved in relay abuse.
Keep your system packages updated, including Postfix, OpenDKIM, and the underlying Ubuntu distribution. Security vulnerabilities in mail server software are discovered periodically, and updates patch these issues. Set up automated security updates on Ubuntu using the unattended-upgrades package to reduce the risk of missing critical patches.
Monitor your server IP reputation. Use services like MXtoolbox or Sender Score to check your reputation regularly. If you notice a sudden drop in delivery rates, check whether your IP has been added to a blacklist and address the cause promptly.
Back up your Postfix configuration, SASL passwords, DKIM keys, and TLS certificates. Document your setup so that if you need to rebuild the server or migrate to new hardware, you have everything you need to restore service quickly.