Relaying from Postfix to gmail

By Abhijit Menon-Sen <ams@toroid.org>

2017-03-13

Here's how I configured Postfix to relay mail from x@example.com through smtp-relay.gmail.com:587 using the credentials set up for x@example.com on Google Apps.

There are three parts to this: making Postfix relay mail based on the sender address, teaching it to authenticate to gmail, and configuring gmail to accept the relayed mail. (Postfix was already configured to send outgoing mail directly.)

Sender-dependent relay

I created /etc/postfix/relay_hosts with the following contents:

@example.com smtp-relay.gmail.com:587

Then I ran «postmap /etc/postfix/relay_hosts» and set sender_dependent_relayhost_maps in /etc/postfix/main.cf:

sender_dependent_relayhost_maps =
    hash:/etc/postfix/relay_hosts

SMTP SASL authentication

I created /etc/postfix/sasl_passwords (mode 0600) with the following contents:

smtp-relay.gmail.com x@example.com:xpassword

Then I ran «postmap /etc/postfix/sasl_passwords» and added the following to /etc/postfix/main.cf:

smtp_sasl_auth_enable = yes
smtp_sasl_password_maps =
    hash:/etc/postfix/maps/relay_passwords
smtp_sasl_security_options = noanonymous

That enables SMTP AUTH in the Postfix SMTP client and tells Postfix where to look up the username and password for a domain.

Gmail will accept SMTP AUTH only in a TLS session, so TLS client support must be configured in Postfix (which means setting smtp_tls_security_level to "may"). But even once that's done, gmail advertises only the following authentication mechanisms:

250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH

I didn't want to worry about OAUTH, so I was left with PLAIN was the only reasonable choice. Postfix will not use plaintext authentication mechanisms by default, so I also had to remove "noplaintext" from the default value for smtp_sasl_security_options.

As an additional precaution, I also set smtp_tls_policy_maps to change the default TLS policy from "may" to "encrypt" for smtp-relay.gmail.com.

Gmail configuration

When I tried to send mail through the relay, Postfix wasn't able to authenticate:

SASL authentication failure: No worthy mechs found

SASL authentication failed; cannot authenticate to server smtp-relay.gmail.com[74.125.206.28]: no mechanism available

Google considers password authentication to be “less secure”, and you have to explicitly enable it on the less secure apps settings page. There are some other alternatives, but I was happy to take the path of least resistance here.

I did that and tried again, only for mail to bounce with this error:

Invalid credentials for relay [136.243.148.74]. The IP address you've registered in your G Suite SMTP Relay service doesn't match domain of the account this email is being sent from. If you are trying to relay mail from a domain that isn't registered under your G Suite account or has empty envelope-from, you must configure your mail server either to use SMTP AUTH to identify the sending domain or to present one of your domain names in the HELO or EHLO command. For more information, please visit https://support.google.com/a/answer/6140680#invalidcred

This message is misleading, as I found out by using openssl's s_client to establish a TLS session and then authenticating by hand. SMTP AUTH succeeded, but MAIL FROM was subsequently rejected. I followed the link in the message, which led me to the SMTP relay service support page.

The Google Apps admin console doesn't use sensible URLs, but I followed the breadcrumb trail to an “Advanced settings” page where I was able to edit the SMTP relay service settings to set “Allowed senders” to “Only addresses in my domains”, as well as to “Require SMTP authentication” and “Require TLS encryption”. Remember to “Save” the changes.

The error I got was because the “Only accept mail from specified IP addresses” option was checked for this particular domain. I could have added the IP address of my server to the list, but SMTP authentication was what was I wanted to use anyway.