postfix SMTP relay to MS-Exchange server

Success!!! After hours and hours of attempts over many years, I have finally managed to get the postfix MTA to send mail via the Harvard FAS MS-Exchange server’s SMTP port. Sharing this information here because I found several forum posts with similar queries, none of which seemed to have been solved.

For a number of reasons (logging, general integration, mailqueue management, etc), I’ve kept coming back to wanting to use postfix as the primary mail manager on my Arch Linux setup (a widely roaming laptop), but for a long time have had to use ‘domain spoofing’ via a Dreamhost SMTP server to send mail from my @oeb.harvard.edu address; the official FAS SMTP kept failing to authenticate. But domain spoofing (sending @foo.com mail via a bar.com server) can lead to mail being SPAM filtered, and I suspect many of my emails never got delivered to an Inbox. I put up with this (on and off) until yesterday, when several emails started bouncing with a note that the Dreamhost mail server IPs had been blacklisted by Spamcop and the various receiving servers that used Spamcop were rejecting the messages. Uggh. So back to the frustrating task of trying to send email through the ornery MS server.

But this time, I was fortunate enough to find a reference to the SMTP troubleshooting app swaks (a ‘SWiss-Army Knife for SMTP!’; thanks to John Jetmore!). E.g.:

  $ swaks --to foo@bar.com --from me@oeb.harvard.edu \
    --auth-user username --auth-password password \
    --server smtp.fasmail.harvard.edu:587

And by fiddling around realized that while I couldn’t authenticate with the server’s two (TLS and non-TLS) AUTH options (GSSAPI and NTLM; who knows why!), if I used -tls and forced standard LOGIN (available only after STARTTLS) with --auth LOGIN, I could send though the server. Yay! It was then a fairly simple step to find the parameters to do this with postfix:

In main.cf:

  relayhost = [smtp.fasmail.harvard.edu]:587
  smtp_sasl_auth_enable = yes
  smtp_use_tls = yes
  smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
  smtp_sasl_mechanism_filter = login
  smtp_sasl_security_options = noanonymous  # needed!

The password info is in sasl_passwd:

  [smtp.fasmail.harvard.edu]:587 username:password

(Note that the username is the simple user name, not username@fas.harvard.edu and not fas_domain\username). Then simply,

  # postmap sasl_passwd  # to rehash the passwd file
  # postfix reload
  # postqueue -f         # to flush any messages undelivered

and your mail should be sent via the MS-Exchange server and have a higher chance of evading aggressive SPAM filters. Phew!!

(Update) Multiple SMTP servers

To send via multiple SMTP servers, dependent on sender address (e.g., via smtp.gmail.com for mail from username2@gmail.com), add these lines to main.cf:

  smtp_sender_dependent_authentication = yes
  sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay

add a lookup (on email address or domain) to other (non-default) SMTP servers to sender_relay:

  @gmail.com    [smtp.gmail.com]:587

and the new passwords to sasl_passwd:

  username2@gmail.com    username2gmail.com:password2

(Remember to ‘postmap XXXX’ and ‘posfix reload’ after each of these hashed files is changed).

Mail new sent with a MTA ‘envelope’ containing From: username2gmail.com should now be routed via the gmail servers. In the process of troubleshooting this, I found that:

  1. GNUS users: If you have used (setq user-mail-address "user1@oeb.harvard.edu") in your .emacs file, you need to add (setq message-sendmail-envelope-from 'header) so that the MTA From: line is taken from the From: address in the email you are writing (in Message Mode), not set by default.
  2. mailx -r foo@bar.com sets the MTA From: line fine, but...
  3. mailx without -r will send the message to postfix with a generic From: user@localhost.localdomain address, which is of little use (and will not be accepted by SMTP servers). This default user@localhost.localdomain can be generically re-written by postfix.

The only drawback I found is that the SMTP authentication options (e.g. see above) are set in the shared main.cf file and thus need to be the same for all SMTP relays. I am fine with smtp.fasmail.harvard.edu and smtp.gmail.com (TLS and LOGIN), but other combinations of servers may present a problem.