Using Office 365 as a Smart Host with Postfix

Since writing this post I've learned a better way. If you're using a personal account or only need to relay 1 server the below may be sufficient. If you're managing more than one server and can manage your Office365 domain please see my updated post Better Use of Office 365 as a Smart Host with Postfix.

One great thing about Linux systems is that we can get automagic reporting on so many things just by setting up a mail server. Want to run a command and find out if it failed? Throw it in cron and redirect the output to stdout. Want to write a script to generate a report? Save it as ASCII text and run the mail command. Bam! Instant report distribution. Also because of how easy it is to interact with the mailing subsystem many applications are written with it in mind. Just like how logging is, largely, standardized on syslog reporting has largely standardized on email.

In the Sendmail world we could set this up fairly easily using a SmartHost. Even authenticated is not that big a deal, though truthfully that's mostly because I worked out a successful config aeons ago that is easily modified. These days, however, I'm working in an Ubuntu environment which now has a pretty strong preference for postfix. Fortunately I was a somewhat easy grognard to retrain, the syntax is certainly easier. Just as with sendmail you start with setting your SmartHost, now called a relayhost

relayhost = [smtp.office365.com]:587

Next up we'll need to define the user credentials necessary to send mail through our relayhost. Just as with sendmail we'll create a file containing the credentials, say /etc/postfix/sasl_passwd, with the contents of

[smtp.office365.com]:587 user@domain.tld:soopersekretPassvv0rd

In order to turn this into a file that postfix can use we'll run it through a processor.

postmap hash:/etc/postfix/sasl_passwd

This generates a BerkDB file based on the raw text file we created before. Now we tell postfix to use it by adding this to the main.cf.

smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd

In theory this should be sufficient but it's actually not. If you'll notice I'm relaying through Office365. Their mailers have an additional restriction, first you must authenticate using a valid username and password then your user must be allowed to send messages as the email address given in the From header.

Mail coming from Linux services can be all over the map. Typically cron output will be root@servername, webapps may send as no-reply@servername.tld, others like logwatch, may use application@servername. All of those will be rejected by the relayhost since our service account user doesn't have those permissions. Postfix lets us do this using what they call a generic-map.

Create the map file, here /etc/postfix/generic with

/.*/    user@domain.tld

Then just as above we'll turn it into a database

postmap hash:/etc/postfix/generic

And update main.cf to look for the file.

smtp_generic_maps = hash:/etc/postfix/generic

Now all outgoing messages will have the From field replaced in both the envelope and header. The first field, the /.*/, is a regular expression that defines everything. You can replace that with more specific addresses, more details are in the official docs.

Now you can just restart the postfix service and start routing your mail. Well... nearly. Office365 has some additional settings so I'll include a full config at the bottom.

All we've done so far is just set up relaying for outgoing messages. Almost all applications that prompted this work send their messages to root. This isn't really all that grand since in order to read the messages you'll have to log into the host directly. What we really want to do is have these go someplace else. Edit the file /etc/aliases and look for a line where the first entry is root. Make it look like this.

root: scottpack+totesspam@hotmale.com

Next run the command /usr/bin/newaliases and all messages sent to root will get forwarded to my system reports address. If the applications you want to get messages from send do a different address, for example apt-mirror really likes sending mail to itself, then add additional lines for each local user name. Just make sure to run newaliases each time you save the file.

Now, with the rest of the changes to your main.cf listed below, you should start getting all those great email alerts all routed through your spiffy O365 server.

relayhost = [smtp.office365.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_generic_maps = hash:/etc/postfix/generic
smtp_tls_security_level = may
smtp_sasl_security_options = noanonymous