WTF are SPF Records?

I want to talk about SPF Records. Often overlooked, these are a vital tool in fighting e-mail spam, and ensuring that your domain is not misused for fraudulent purposes.

At best, the failure to set an SPF record for your domain allows miscreants to use your domain for spam purposes. This could get your domain reputation knocked or your domain blacklisted, impacting the deliverability of your legitimate mail, because nobody trusts you anymore.

At worst, spearphishing can involve scammers sending messages to targeted individuals that appear to originate from your organisation. E-mails to suppliers could attempt to make (expensive) unauthorised orders, whilst messages targeting your customers might request payment, whilst “notifying” them of a change in the payment details - to the scammer’s back account! This can lead to both significant financial loss and reputational damage.

It’s important to note that this is not about people hacking your mail server. We’re talking about people sending e-mail from their own servers (or hacked servers) and simply claiming to be from you because email has no in-built security or authentication.

And the most damning thing? SPF is trivially easy to set up for most organisations, especially for community groups and rifle clubs who typically have very simple needs.

So what is an SPF Record?

DISCLAIMER: I’m going to assume here that you have basic familiarity with DNS records and know what A, MX and TXT records are. If you don’t, go read this tutorial.

An SPF Record is contained within a single TXT Record in the DNS for your domain. Whereas MX records tell other people’s mail servers where to send mail destined for your domain, SPF specifies legitimate senders for e-mails purporting to come from you.

If you as a rifle club simply use a gmail or hotmail account for all email and don’t actually send/receive mail using your website’s domain then you can state that as well - “we don’t send email from this domain, anything claiming to be from [@examplerifleclub.org.uk] is fraudulent”. I show how to do that in Example 2.

Okay, so how do I do that?

The format and syntax of an SPF record is very straightforward. The options are all listed at openspf.org.

All you’re doing is listing other DNS resources (such as A, AAAA or MX records) and then qualifying whether or not they are allowed to send e-mail from your domain.

You do this by adding one of four qualifiers to each resource:

Qualifier Action Explanation
+ Pass Does what it says - whitelists that server as a legitimate source of mail from your domain.
- Fail “Hard Fail” tells a server to reject mail that originates from these servers.
~ SoftFail Recipients will generally accept the email, but flag it as spam.
? Neutral Don’t use this. There is no value in saying “this server may or may not be allowed to send mail”.

Worked Examples

Let’s start with a real record - the SPF Resource for richhemingway.co.uk! On a mac or linux system you can pull this up in Terminal with the command:

dig TXT richhemingway.co.uk

My DNS records look something like this:

Host Record Type Value
richhemingway.co.uk A 149.255.60.176
www.richhemingway.co.uk A 149.255.60.176
richhemingway.co.uk MX mail.richhemingway.co.uk
mail.richhemingway.co.uk A 149.255.60.176
richhemingway.co.uk TXT v=spf1 a mx -all

We can see here that all my A and MX records point to the same shared hosting server which hosts both the website and e-mail.

At the bottom we’ve got the TXT record containing SPF details.

v=spf1 a mx -all

Let’s break that down:

v=spf1

v is for version. We’re saying this TXT record is an SPF resource formatted using version 1 of the SPF standard.

a mx

Unwritten here is the + sign. SPF defaults to “Pass”, so we’re telling recipients that any host listed in this domain’s A and MX records is permitted to send mail from our domain. It could also be written +a +mx, which is more explicit for humans to read, but functionally identical.

-all

You always add an “all” to the end. This is a catchall for anything you haven’t already mentioned (i.e. the rest of the internet). This example uses a minus sign for “hard fail” but you could also use a tilde (~) for “soft-fail”. Technically, +all and ?all are valid statements, but all they’d be saying is that anybody can send messages claiming to be from your domain, which is a bit pointless. You’re trying to narrow it down to just the whitelisted hosts!

So this example allows any host listed in my domain’s A or MX records to send email from [example]@richhemingway.co.uk. Any other host is Hard-Failed.

AND THAT IS IT!

Simple right?

If your mail server received an e-mail claiming to be from an address @richhemingway.co.uk which had been sent from 149.255.60.176, then it could look at the SPF and say “Okay, so any host mentioned in an A- or MX- record is allowed to send e-mail from @richhemingway.co.uk.”

It would go through, find that 149.255.60.176 is indeed referenced in my A-records and would accept that mail.

Conversely, if you received an e-mail claiming to be from @richhemingway.co.uk sent by the host 2.2.2.2, then your server would check the A- and MX- records and would not find any match for 2.2.2.2 amongst the authorised hosts. That would leave the -all statement, and the message would be rejected.

Example 2

v=spf1 -all

This is a really short one. Just the SPF introduction, and then “fail everything”. This record is saying “This domain does not send e-mail”.

Example 3

v=spf1 +mx -all

Dead simple, this is saying “the hosts listed in my MX records can send e-mails, but nothing else can”. I’ve included the explicit + qualifier here just to show it in use.

Example 4

Let’s do one last example.

v=spf1 mx include:spf.ess.barracudanetworks.com ip4:47.228.131.143 ip4:47.228.131.144 include:sendgrid.net include:mailgun.org ~all

Ooof, that’s more complicated! Or is it? Let’s list out the statements:

v=spf1

mx

include:spf.ess.barracudanetworks.com

ip4:47.228.131.143

ip4:47.228.131.144

include:sendgrid.net

include:mailgun.org

~all

Hopefully the v=spf1, mx and ~all statements don’t need any explanation by now.

include: is a way of including third party hosts. If you use GSuite, Office365 or (in this case) Barracuda Networks to host your e-mail, they may use different servers to send e-mail than they use to receive e-mail (which you will specify in your MX records). So Barracuda Networks have a list of sending hosts which are referenced by the include:spf.ess.barracudanetworks.com statement. If they add more servers, this customer doesn’t need to modify this SPF record - Barracuda just add them to their list which this include: references. The same is true of the “sendgrid.net” and “mailgun.org” includes, which they probably use to send out newsletters and bulk mail.

ip4: allows you to specify a specific host by IP-address, rather than by domain (like mail.richhemingway.co.uk). This can be “brittle” because if the IP address for that service changes, you need to manually update the SPF-record. You’ll probably remember to change any A- or SRV- Records because otherwise your service will probably break, but SPF is easily overlooked until your mail stops getting delivered! It’s valid, but consider carefully whether it’s the best way forward for you.

So all we actually have here is:

  • Pass on the domain’s MX records
  • Pass on the three “includes” to Barracuda, SendGrid and MailGun
  • Pass on two specific IP4 addresses
  • A soft-fail at the end on all.

Simples? Hopefully!

In general, you’re only going to see stuff like this if you are using a bulk-mailing service like MailChimp or MailGun or a third-party mail-provider like GSuite or O365. Fortunately, those services tend to have great help resources for customers setting up those services - Google Support; Microsoft Docs; MailChimp.

Considerations

  • SPF reads left-to-right. So v=spf1 +a -all is not the same as v=spf1 -all +a. v=spf1 goes at the start, -all or ~all goes at the end and the stuff you’re going to allow goes inbetween.

  • There can be only one. Multiple SPF records will break things. However complicated your needs, it all needs to go on one line. This is doable, the SPF record for the entirety of google.com is v=spf1 include:_spf.google.com ~all.

  • At one stage, there was a plan to introduce a dedicated DNS Record Type of “SPF” instead of adding your SPF details within a TXT Record. This has been deprecated, but sometimes you’ll still see “SPF” in the list of options when setting up DNS Records. Don’t use it, just set it up as a TXT record.

  • If you use +all, the elders of the Internet will hunt you down and do unspeakable things to you. At this point you’re actively facilitating spam.

I hope I’ve shown that SPF records are actually pretty easy to understand once you break them down, and that if you don’t already have one on your domain, then in most cases it will be the work of a minute to set up. For any sports club or community group with a basic website, v=spf1 a mx -all or v=spf1 -all will do. Get to it!