You might come across a slight gotcha with SPF records if are using Exchange Online Protection (EOP) to provide protection for your on-premises mail environment and you don’t need to use EOP to scan your outbound (i.e. on-premises to Internet) messages. If this scenario is of interest to you, read on…
You may be aware that I run a mailing list running on a single server over at ActiveDir.org that provides a forum for disucssions on the topic of Active Directory. I set up Exchange Online Protection (EOP) to cover the mail.activedir.org namespace a little while ago as a lower-cost alternative to my previous anti-malware provider. When you first set up EOP with there are some DNS records that you are asked to configure. In fact, these *appear* to be mandatory based on the wording (see below).
Without really thinking too deeply about I went ahead and configured the TXT record in DNS for SPF. With hindsight I shouldn’t have done this as I only wanted the traffic from the Internet to my on-premises mail server to be scanned for malware. I don’t need the SMTP traffic in the other direction to be scanned for malware because the only mail generated on the server is from the mailing list (list server) and as such as been scanned on the way in.
All appeared fine for a month or so and then fellow MVP Brian Arkills queried why he wasn’t receiving any email from the list. After a bit of digging, his infrastructure guy pointed to a problem with my SPF TXT record. Basically, the “-all” part of the record indicates that only the servers matching spf.protection.outlook.com are responsible for sending mail from mail.activedir.org. If a different server tries to deliver mail from that address the receiving MTA should fail the SPF check. Interestingly, most organisations treat this as a soft fail and deliver the email anyway. Not so the University of Washington, which is why Brian wasn’t receiving the list emails.
Once alerted to the problem, I modified the record like this:
v=spf1 a -all
What this says to the receiving MTA is to only pass the SPF check if sending server matches the A record for the namespace (i.e. my mail server).
That all seemed fine but then I looked at the message headers for emails that I was receiving from the list. I am subscribed to the list with a standard cloud-based O365 email address. The header contained the following:
Received-SPF: Fail (protection.outlook.com: domain of mail.activedir.org does not designate 126.96.36.199 as permitted sender) receiver=protection.outlook.com; client-ip=188.8.131.52; helo=emea01-db3-obe.outbound.protection.outlook.com; Authentication-Results: spf=fail (sender IP is 184.108.40.206) firstname.lastname@example.org;
The 220.127.116.11 IP address maps to emea01-db3-obe.outbound.protection.outlook.com (very clearly not my mail server). So what was going on? Why was the sending server showing as one of the outlook.com servers and not my mail server? I don’t know for sure but my best guess is that the O365 cloud servers are also EOP servers (makes sense). The EOP servers *think* they are responsible for the mail.activedir.org namespace and as such will effectively take over as the perceived sending server. The upshot was that I needed to go back to my SPF record and change it to include the EOP servers. It now looks like this:
v=spf1 a include:spf.protection.outlook.com -all
To summarise then:
- Emails coming from my mail server to non-O365 addresses need to have a SPF TXT record that matches my mail server (via the A record for mail.activedir.org).
- Emails coming from my mail server to O365 addresses need to have a SPF TXT record that matches the name required by EOP (spf.protection.outlook.com)
More than slightly confusing isn’t it? But then I guess I have a slightly unusual configuration.
For more information on SPF, this web site is a great starting point: http://www.openspf.org/
Another informing post. Thanks Open-a-socket