Postfix: Using Microsoft 365 as SMTP Relay

PowerADM.com / Linux / Debian / Postfix: Using Microsoft 365 as SMTP Relay

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).

Smart host is most often used as a single service for sending/forwarding email messages from the local network to an external email server. For example, instead of setting up a Microsoft 365 SMTP connection on every device on your network (network printer, all-in-one/ multifunction devices, scanner, etc.), you can set them all to send emails to the postfix SMTP host on your local network. Then you need to configure postfix so that it authenticates to the Microsoft 365 SMTP under a user account and sends emails.

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.

enable smtp basic auth for microsoft365 user

Microsoft is going to completely disable SMTP basic auth in Exchange Online in the near future. In this case, you need to use OAuth authentication for postfix on the Microsoft 365 SMTP service. OAuth supports Modern Authentication, or you can configure Conditional Access policies to bypass MFA. To implement OAuth2 on postfix, you can use fetchmail-oauth2 and cyrus-sasl-xoauth2 packages. Use the systemd timers to regularly refresh the token.

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
sasl2-bin – is the Cyrus SASL API implementation that allows using authentication in postfix.

When configuring the postfix initial setting, set:

  • General type of mail configuration -> Internet Site
  • System mail name -> your FQDN (hostname --fqdn)

configure postfix with office 365 (microsoft 365) smtp relay

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.

Or you can use the file /etc/ssl/certs/ca-certificates.crt.

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

If you want to restrict the networks Postfix is allowed to accept connections from, use the mynetworks directive:

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
To prevent emails from your SMTP relay from getting into the users’ Spam folder, it’s a good idea to configure an ipv4 SPF record for your public IP address in DNS.

v=spf1 ip4:xxx.xxx.xxx.xxx include:spf.protection.outlook.com -all

4 thoughts on “Postfix: Using Microsoft 365 as SMTP Relay”
  1. 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”

  2. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *