Postfix on a server is usually there for mail that programs send: cron, monitoring, a website calling sendmail. Delivered directly, that mail leaves from the server's IP with no history and no DKIM, and the big mailbox providers meet it with their filters. The relayhost setting hands all outgoing mail to the Postwing relay instead: the relay signs it with your domain's DKIM key, and Postfix only has to log in and pass messages on.
| Setting | Value |
|---|---|
| SMTP host | smtp.postwing.app |
| Port | 587 |
| Encryption | STARTTLS (the connection is upgraded to TLS before login) |
| Username | The login of an SMTP token for your domain |
| Password | The password of that token — shown once, when the token is created |
Postfix authenticates through Cyrus SASL, and the PLAIN mechanism ships in a separate package. Without it authentication never starts and the log says No worthy mechs found:
# Debian, Ubuntu: SASL modules including PLAIN
sudo apt install postfix libsasl2-modules
# RHEL, AlmaLinux, Rocky
sudo dnf install postfix cyrus-sasl-plainAdd to /etc/postfix/main.cf:
# /etc/postfix/main.cf — send all outgoing mail through the relay
relayhost = [smtp.postwing.app]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
# PLAIN sends the password in the clear, so allow it only inside TLS
smtp_sasl_tls_security_options = noanonymous
smtp_tls_security_level = encrypt| Parameter | What it does |
|---|---|
relayhost | Where to hand all mail for other domains. The brackets turn off the MX lookup; :587 is the submission port with STARTTLS. |
smtp_sasl_auth_enable | Turns on client-side SMTP authentication. |
smtp_sasl_password_maps | The table holding a login and password per relay. |
smtp_sasl_tls_security_options | Lifts the ban on plaintext mechanisms inside TLS. Without it Postfix refuses to use PLAIN. |
smtp_tls_security_level = encrypt | Never send unencrypted: if STARTTLS fails, the message stays queued and the password is never sent in the clear. |
Create /etc/postfix/sasl_passwd. The key at the start of the line must match relayhost exactly, brackets and port included:
# /etc/postfix/sasl_passwd
# the key must match relayhost exactly, brackets and port included
[smtp.postwing.app]:587 token-login@your-domain.com:your-token-password Make the file readable by root only, build the index and reload. Run postmap after every edit, or Postfix keeps reading the old .db:
sudo chmod 600 /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd # builds sasl_passwd.db
sudo postfix check
sudo systemctl reload postfixhash: tables. If postconf -m does not list it, use the type from postconf default_database_type, such as lmdb:, both in main.cf and in postmap lmdb:/etc/postfix/sasl_passwd. Implicit TLS on port 465 needs smtp_tls_wrappermode (Postfix 3.0 and later). Without it Postfix waits for a plaintext greeting that never comes and gives up on a timeout:
# /etc/postfix/main.cf — port 465, TLS from the first byte
relayhost = [smtp.postwing.app]:465
smtp_tls_wrappermode = yes
smtp_tls_security_level = encrypt
# /etc/postfix/sasl_passwd — the key uses :465 too
[smtp.postwing.app]:465 token-login@your-domain.com:your-token-password If the server hosts several sites or its own mail and only your verified domain should go through Postwing, leave relayhost empty and pick the relay by sender. Postfix looks the envelope sender up in full first, then by @domain:
# /etc/postfix/main.cf — relay only mail from your-domain.com
# no relayhost: everything else is delivered directly, as before
sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_tls_security_options = noanonymous
# TLS is mandatory for the relay only, opportunistic elsewhere
smtp_tls_security_level = may
smtp_tls_policy_maps = hash:/etc/postfix/tls_policy# /etc/postfix/sender_relay
@your-domain.com [smtp.postwing.app]:587
# /etc/postfix/tls_policy
[smtp.postwing.app]:587 encrypt
# /etc/postfix/sasl_passwd
[smtp.postwing.app]:587 token-login@your-domain.com:your-token-passwordsudo postmap /etc/postfix/sender_relay
sudo postmap /etc/postfix/tls_policy
sudo postmap /etc/postfix/sasl_passwd
sudo systemctl reload postfix Credentials are still looked up by the relay's address, so smtp_sender_dependent_authentication is not needed here; it is for giving different senders different credentials. If you already route this domain with transport_maps, note that it takes precedence over sender_dependent_relayhost_maps.
The relay advertises a single mechanism, AUTH PLAIN. Postfix chooses from what it supports, what the server advertises and what smtp_sasl_mechanism_filter lets through, so nothing extra is needed. Two things can get in the way: the default smtp_sasl_security_options (noplaintext), and a leftover smtp_sasl_mechanism_filter = login from another provider.
Send from an address on your verified domain. The address after -f becomes the envelope sender, and that is what the relay checks:
# Test message: the sender must be on your verified domain
printf 'From: noreply@your-domain.com\nTo: you@example.com\nSubject: Postfix relay test\n\nHello from Postfix\n' \
| sendmail -f noreply@your-domain.com you@example.com
mailq # an empty queue means it left
sudo journalctl -t postfix/smtp -f # or /var/log/mail.log, /var/log/maillog A successful hand-off looks like this in the log: relay= names the relay and status=sent means the relay accepted the message. What happened next, including the recipient server's reply, is in the delivery log in the dashboard.
postfix/smtp[2817]: 4F1A2C0D3E: to=<you@example.com>,
relay=smtp.postwing.app[…]:587, delay=0.8, dsn=2.0.0, status=sent (250 …)| Log message | Cause and fix |
|---|---|
SASL authentication failure: No worthy mechs found | smtp_sasl_tls_security_options = noanonymous is missing, or libsasl2-modules (cyrus-sasl-plain) is not installed. |
SASL authentication failed; server … said: 535 5.7.8 | Wrong token login or password. Check the line in sasl_passwd and rerun postmap. More on error 535 . |
550 relaying denied | Postfix connected without logging in: the sasl_passwd key does not match relayhost (brackets, port), or smtp_sasl_auth_enable is off. Relay refusals explained . |
550 from must be equal to … | The envelope sender is not on your verified domain, most often root@your-hostname. Use sender_dependent_relayhost_maps or smtp_generic_maps. |
550 not relaying to your domain, required until verified | The domain is not verified yet; until it is, mail can only go to addresses on that same domain. |
timed out while receiving the initial server greeting | relayhost uses port 465 but smtp_tls_wrappermode is off. |
connect to smtp.postwing.app…: Connection timed out | Your host blocks the outbound port. Use 8587 or 8465, and change the port in both relayhost and sasl_passwd. |
550 hourly limit exceeded | The plan's hourly limit is used up. Postfix treats a 5xx reply as permanent and bounces the message back to the sender, so keep an eye on usage on the domain page. |
They tell Postfix not to look up MX records for that name and to connect to the host itself. Without them Postfix queries the domain's MX and may go somewhere else. The key in sasl_passwd must be written the same way, brackets and port included, or the credentials are never found.
Postfix found no authentication mechanism it is allowed to use. Our relay offers PLAIN only, and the default smtp_sasl_security_options forbids plaintext mechanisms. Set smtp_sasl_tls_security_options = noanonymous together with mandatory TLS. The same error appears when libsasl2-modules (cyrus-sasl-plain on RHEL) is not installed.
No. The relay accepts AUTH PLAIN only, and Postfix picks it from what the server advertises. If an old smtp_sasl_mechanism_filter = login is still in the configuration, remove it or add plain: when the lists have nothing in common, authentication fails.
Leave relayhost empty and set sender_dependent_relayhost_maps with an entry @your-domain.com → [relay]:587. Mail whose envelope sender is on that domain goes through the relay; Postfix delivers the rest directly. Use smtp_tls_policy_maps to make TLS mandatory for the relay alone.
Not for a domain verified in the dashboard: the relay signs it with DKIM, and SPF and DMARC are published in the delegated zone. If OpenDKIM already signs that domain, messages arrive with two signatures. That is not an error, but it is a second key to maintain for nothing.
System mail is sent as root@your-hostname. The relay accepts mail from verified domains only and answers "550 from must be equal to …". Relay just your own domain (sender_dependent_relayhost_maps) or rewrite the addresses with smtp_generic_maps.