Email notifications from your server are not very useful if you need to log into the box to check them. I've set up Postfix to work with Gmail and Mailgun in the past, but this was my first run in with Office 365. The setup works out to be relatively the same, but there are a few extra steps required for Office 365 to work correctly.
Keep in mind I'm running on an Ubuntu 16.04 LTS box, so if you're on something else there might be some slight deviations from the following.
Install Posfix and dependencies
Let's get started by installing Postfix and necessary dependencies. If it's been a while since you've used
apt don't forget to run
sudo apt-get update sudo apt-get install postfix sasl2-bin mailutils
Postfix Install Time Configuation
During the Postfix configuation select
Internet Site for the
General type of mail configuation.
System mail name, use your FQDN (Fully Qualified Domain Name) here.
Before any mail can be sent through our relay host, Office 365 in this case, we need to define the credentials that will be used to establish the connection. Create a file called
sudo nano /etc/postfix/sasl_passwd
In our credentials file we'll define the SMTP server, the username, and the password. Replace
password with the appropriate credentials.
Keep in mind when using Office 365 the user you connect with can only send mail as itself or as a user it has Send As permissions for.
We've got our credentials saved, but we need to do some work for Postfix to be able to use them.
sudo postmap hash:/etc/postfix/sasl_passwd
We can see that it worked if we run a quick
ls /etc/postfix. You should see
sasl_passwd.db in the list.
For good measure let's also make sure the owner of the files is the
root user and the permissions are
sudo chown root:root /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db sudo chmod 644 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
Remember how in Office 365 we can only send as the user we are connecting with or an account that user has Send As permission on? Senders are kind of a free for all depending on what is sending the mail. Cron might be
root@myserver while an application might be
To fix this problem we need to map our senders to the user we are connecting to Office 365 with. Craete a file called
sudo nano /etc/postfix/sender_canonical
In this file we'll use a regular expression to map any sender to our Office 365 user.
Note the use of a
+ rather than a
*. Using the
* wildcard could lead you to a mail loop if a message is undeliverable.
Like before we need to make this file useable for Postfix and we'll set the owner and permissions.
sudo postmap hash:/etc/postfix/sender_canonical sudo chown root:root /etc/postfix/sender_canonical /etc/postfix/sender_canonical.db sudo chmod 644 /etc/postfix/sender_canonical /etc/postfix/sender_canonical.db
Finally, let's bring everything together in the Postfix config. We'll need to modify
sudo nano /etc/postfix/main.cf
We'll change the folloing line of our
relayhost = [smtp.office365.com]:587
Then we'll add the following lines to our
smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd smtp_sasl_security_options = noanonymous smtp_tls_security_level = may sender_canonical_maps = regexp:/etc/postfix/sender_canonical
main.cf and restart Posfix.
sudo service postfix restart
Send a test message to see if everything worked. Replace
email@example.com with the address you want to send your test to.
echo "Test Message" | mail -s "Test Subject" firstname.lastname@example.org
If your test fails you can check the
mail.log file to try and determine why.
cat /var/log/mail.log | less
After making changes be sure to restart Postfix before testing.
sudo service postfix restart
Network is unreachable
If you see a message like:
connect to smtp.office365.com[some ipv6 address]:587: Network is unreachable
Try changing the
inet_protocols line in
inet_protocols = ipv4
Looping or unknown user
If you are sending to a user that is part of the same domain as the server and your log seems to show Postfix is stuck in a mail loop or if you see a message like:
to=<email@example.com>, relay=local, ..... staus=bounced (unknown user: "user")
domain.tld from the
mydestination setting in
/etc/postfix/main.cf. In this case
server_hostname will be you server's hostname.
mydestination = $myhostname, server_hostname, localhost.localdomain, localhost