Configure Postfix to relay through an authenticated SMTP server (relayhost)

Make a Linux server (Ubuntu/Debian/RHEL) send all its mail — cron, monitoring, apps using sendmail — through an authenticated SMTP relay on port 587: main.cf relayhost, SASL password map, TLS, sender rewriting and how to test with the queue.

Install

shell
sudo apt install postfix libsasl2-modules   # choose "Satellite system" / or: sudo dnf install postfix cyrus-sasl-plain

Complete example

Postfix (Linux relayhost) — STARTTLS on 587, credentials from the environment
# /etc/postfix/main.cf  (append / replace)
relayhost = [smtp.queensmtp.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtp_header_checks = regexp:/etc/postfix/header_checks   # optional From rewrite
myorigin = yourdomain.com
inet_interfaces = loopback-only

# /etc/postfix/sasl_passwd
[smtp.queensmtp.com]:587 your-smtp-username:your-smtp-password

# optional: rewrite root@hostname → a verified address
# /etc/postfix/sender_canonical  (add: sender_canonical_maps = hash:/etc/postfix/sender_canonical to main.cf)
root    alerts@yourdomain.com
@$(hostname)    alerts@yourdomain.com

sudo postmap /etc/postfix/sasl_passwd /etc/postfix/sender_canonical
sudo chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
sudo systemctl restart postfix

# test
echo "relay works" | mail -s "postfix relay test" you@yourdomain.com
sudo tail -f /var/log/mail.log        # look for status=sent (250 ...)
mailq                                  # anything stuck shows here; postqueue -f to retry

What to know

  • The brackets in [smtp.queensmtp.com] tell Postfix not to look up MX records for the relay hostname.
  • Every message must have a From on a domain the relay has verified — sender_canonical_maps rewrites root@server to a real address.
  • Docker: the same config works in a postfix container (e.g. boky/postfix with RELAYHOST/RELAYHOST_USERNAME env) or point apps directly at the relay and skip the local MTA.
  • Cloud VMs block port 25 — this setup deliberately uses 587 (2525 on Linode until unblocked).

Same code, different provider

Only the host, port and credentials change. The rules per provider are on the SMTP settings hub.

ProviderHostPortUsernamePasswordNote
QueenSMTP smtp.queensmtp.com587 (STARTTLS) / 465 (SSL) / 2525SMTP username from the dashboardSMTP password$5/year + $0.10 per 1,000; 100 free/day
Gmail smtp.gmail.com587 / 465you@gmail.comApp Password500/day, From must be the account
Amazon SES email-smtp.<region>.amazonaws.com587 / 465 / 2587SES SMTP usernameSES SMTP passwordsandbox 200/day until approved
Office 365 smtp.office365.com587user@yourdomain.commailbox passwordSMTP AUTH must be enabled; 30/min
SendGrid smtp.sendgrid.net587 / 465 / 2525apikeyAPI keyno free plan since 2025

Credentials for the example above

Create a free account, verify your sending domain (SPF + DKIM shown in the dashboard), add an SMTP credential, and paste it into the code. 100 emails a day free; $5/year plus $0.10 per 1,000 after that. Prefer HTTPS? The same account has a REST email API.

Get SMTP credentials Test your settings first

Other languages and frameworks

Examples tested 2026-08-30. If a library changed its API, tell us.

Postfix (Linux relayhost) SMTP — questions

The sasl_passwd entry does not match the relayhost line exactly (brackets and port must match), the .db was not regenerated with postmap, or the credentials are wrong.

Harmless with smtp_tls_security_level = encrypt (it still encrypts). Set smtp_tls_CAfile to the system bundle to make it "Trusted".