Postfix mail server is available in almost all Linux distributions. You can use it as a simple relay (smart host) to send email messages from your local network to user mailboxes and forward email queues to SMTP servers outside your organization. In this article, we’ll show you how to set up an SMTP relay for Microsoft 365 (Office 365, Exchange Online) with postfix on Linux (using Ubuntu/Debian as an example).
Enable Authentication in Microsoft 365 (Exchange Online)
By default, postfix only supports basic authentication for users in Microsoft 365. So you need to enable SMTP AUTH (basic authentication) for the user under which your postfix will be sending emails.
By default, SMTP AUTH is disabled at the level of the entire Exchange Online tenant. Check it out with PowerShell. Connect to your Exchange Online tenant using the Exchange Online PowerShell v2 (EXO v2) module:
Connect-ExchangeOnline
Check the SMTP authentication settings for the tenant:
Get-TransportConfig | Format-List SmtpClientAuthenticationDisabled
In our case, it is enough to enable SMTP AUTH for a single user account using PowerShell:
Set-CASMailbox -Identity username@m365tenantname.com -SmtpClientAuthenticationDisabled $false
You can also enable SMTP authentication for EOL user through the Microsoft 365 Admin Center: Users -> Active Users -> select a user, go to the Mail tab and click Manage email apps. Enable the Authenticated SMTP option.
Configure Postfix SMTP Relay for Microsoft 365
Install the following packages on your Linux host (Ubuntu in this case):
$ sudo apt-get update
$ sudo apt-get install postfix sasl2-bin mailutils
When configuring the postfix initial setting, set:
- General type of mail configuration -> Internet Site
- System mail name -> your FQDN (
hostname --fqdn
)
Save the username and password for authentication on Microsoft 365 SMTP to a file /etc/postfix/sasl_passwd.
[smtp.office365.com]:587 username@m365tenantname.com:user_password
Such a plain text password file cannot be used in postfix directly. To create a hash for this file, run:
# postmap /etc/postfix/sasl_passwd
The file hash will be saved to /etc/postfix/sasl_passwd.db.
When using Office 365 SMTP, you can only send a message on behalf of the user under which you authenticated (must match the FROM field). Postfix can override the FROM field for all outgoing emails. To do this, create a file /etc/postfix/sender_canonical and add the following line to it:
/.+/ username@m365tenantname.com
Then create a hash for this file:
#postmap /etc/postfix/sender_canonical
Check file owners and permissions:
# chown root:root /etc/postfix/{sasl_passwd,sasl_passwd.db,sender_canonical,sender_canonical.db}
# chmod 640 /etc/postfix/{sasl_passwd,sasl_passwd.db,sender_canonical,sender_canonical.db}
We will use TLS for the SMTP connection. Get Microsoft 365 certificates:
#openssl s_client -showcerts -starttls smtp -crlf -connect smtp.office365.com:587
And copy them to /etc/postfix/cacert.pem file.
Now make the following changes to the postfix configuration file /etc/postfix/main.cf:
inet_protocols = ipv4
relayhost = [smtp.office365.com]:587
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
smtp_tls_CAfile = /etc/postfix/cacert.pem
smtp_use_tls = yes
smtp_always_send_ehlo = yes
mynetworks = 127.0.0.0/8, 192.16.31.0/24
inet_interfaces = ipv4
Restart the service:
# systemctl restart postfix
Create a file:
$ nano /etc/postfix/testemail.txt
to: emailto@m365tenantname.com subject:Test M365 Delivery
Try sending a test email through your SMTP relay using Microsoft 365 saved user credentials:
# sendmail -v username@m365tenantname.com < /etc/postfix/testemail.txt
Or you can send an email using the mail tool:
# echo "Test email via Microsoft 365 SMTP " | mail -s "Check Postfix SMTP Relay via M365" admin@m365tenantname.com -a "FROM:username@m365tenantname.com "
Verify that your email was successfully sent via Microsoft 365 SMTP relay host:
# journalctl -u postfix
To debug SMTP relay connections and view email logs, check the file:
# less /var/log/mail.log
v=spf1 ip4:xxx.xxx.xxx.xxx include:spf.protection.outlook.com -all
awesome ty!
Finaly something that work… BIG thanx (Latest the greatest)
This is great. Are you planning to do a full OAUTH version of this?
(i am embarrassed to say i have no idea how to “use fetchmail-oauth2 and cyrus-sasl-xoauth2 packages” and “Use the systemd timers to regularly refresh the token”
Funktioniert auf Anhieb – Super danke !
Die eckigen Klammern [] benötigt man nicht. Das sind nur Platzhalter ?
relayhost = [smtp.office365.com]:587
[smtp.office365.com]:587
Ich habe sie einfach weggelassen.
Works straight away – thank you very much! You don't need the square brackets []. Are these just placeholders? [smtp.office365.com]:587 I just left them out.
thnx