allanwallace.uk : Blog
A beginners guide to SPF


What is Sender Policy Framework?
( What is SPF? )

Sender Policy Framework - or as it is better known SPF - was developed in the early 2000s in order to help a domain's owner prove it's genuine emails were genuine and ones from elsewhere were not.


What does SPF do?

SPF is a mechanism by which a domain owner can pubish a list (or lists) of servers that are authorised to send emails from that domain.

It was a great idea, and still is as part of a solution to reduce the risk of your domain being abused by spoofed emails, CEO scams, Invoice Fraud etc, it certainly has it's uses.


Unfortunately here we are in 2018, over a decade later and:
• There are still some remaining issues that SPF doesn't solve on it's own.
• Even within the I.T. field there is still a very common lack of understanding about how SPF works
   - this leads to implementations with problems - problems that may well have simple solutions.

I wrote this article in order to explain it clearly, and hopefully simply. If you're interested, read on and I will deal with these points.

First:
Many thanks to Scott Kitterman for his SPF Record Testing Tools
These are a valuable resource for learning about and testing SPF compliance.




1 - This is one of the simplest SPF records
v=spf1 -all

What this says:

v=spf1
I am an SPF record

-all
all other servers are not allowed to send MAIL FROM my domain*

Essentially, this SPF record simply says: No server is allowed to send MAIL FROM my domain$

$ This I will come back to later.
* the SPF record for any domain does not apply to it's subdomains#.
If you have a subdomain - such as www. - then you should give it it's own SPF record.
# yes, there is an exception, but not with SPF on it's own.

If you do not want to send emails from your domain or a subdomain (such as www.example.com) implement this in the first instance:
v=spf1 -all

Simple?
All clear so far?
- Let's move on:



2 - This is an SPF record
v=spf1 ip4:54.38.79.38 -all

What this says:

v=spf1
I am an SPF record

ip4:
The following IPv4 address (or address range) is explicitly allowed to send MAIL FROM my domain *

54.38.79.38
You could use 54.38.79.38/32 (CIDR notation) to indicate a single IP address
- but why waste 3 characters per DNS lookup when it's not required?

-all
No other servers are allowed to send MAIL FROM $ my domain *

* the SPF record for any domain does not apply to subdomains #.
If you have a www. subdomain, you should give it it's own SPF record.
$ This I will come back to later.
# yes, there is an exception, but not with SPF on it's own.

Hope this is all crystal clear so far!



3 - This is an SPF record
v=spf1 ip4:54.38.79.0/24 -all

What this says:

v=spf1
I am an SPF record

ip4:
The following IPv4 address range is explicitly allowed to send MAIL FROM my domain*

54.38.79.0/24
(an IPv4 address range in CIDR nation).

-all
No other servers are allowed to send MAIL FROM $ my domain*

* the SPF record for any domain does not apply to subdomains. If you have a www. subdomain, you should give it it's own SPF record.
$ This I will come back to later.



4 - This is an SPF record
v=spf1 ip4:54.38.79.38 ip6:2001:41d0:801:2000:0:0:0:51f -all

What this says:

v=spf1
I am an SPF record

ip4:
The following IPv4 address / address range is explicitly allowed to send emails from my domain*

54.38.79.38
(an IPv4 address)

ip6:
The following IPv6 address / address range is explicitly allowed to send emails from my domain*

2001:41d0:801:2000:0:0:0:51f
(an IPv6 address or address range).

-all
No other server is allowed to send MAIL FROM$ my domain*

As above, * the SPF record for any domain does not apply to subdomains $ This I will come back to later.

Hopefully all still clear?
- let's move on further



5 - This is an SPF record
v=spf1 mx -all

What this says:

v=spf1
I am an SPF record

mx
the mailservers published as my MX records are explicitly allowed to send emails from my domain*

-all
all other servers are not allowed to send MAIL FROM$ my domain*

Important - please note:
There are quite a few good reasons why using mx might not be a good idea - requiring DNS lookups is just one reason.
I have seen more than a few places where it has caused issues, so if you are planning on using it in your SPF record you should read this article in full.

Anyway, let's move on!



6 - This is an SPF record
v=spf1 a -all

What this says:

v=spf1
I am an SPF record

a
any server at any A record on my domain is explicitly allowed to send emails from my domain*

-all
all other servers are not allowed to send MAIL FROM$ my domain*

an "A" record is a DNS record that usually contains an IPv4 address, however in the case of SPF "a" is used for both A and AAAA records.
In simple terms, if the addresses are IPv6, use "a" if you need to. if the addresses are IPv4, use "a" if you need to.
There may be many of them. This can be important, and there can be some careful considerations with using a in an SPF
Please note: "Careful" does not mean "difficult".

Important - please note:
There are quite a few good reasons why using a might not be a good idea - requiring DNS lookups is just one reason.
I often encounter domains where someone has added "a" into their SPF record where it is simply not required.
As per mx, if you are planning on using it in your SPF record you should read this article in full.

If you got this far, I guess you understand so let's continue!



7 - This is NOT an SPF record
v=spf1 aaaa -all

What this says:

v=spf1
I am an SPF record

aaaa
If I'm really lucky it will be interpreted as a - but most likely this will break the entire SPF record because aaaa is not valid in an SPF.
If you want to allow AAAA records, simply use a.

By this point you should be getting quite familiar with how to format these things,
so lets move on to something a little different.



The include: Mechanism

This is useful. Useful things can be problematic if mis-used, but let's start with a simple example.
v=spf1 include:spf.wallacenetworks.uk -all

include:spf.wallacenetworks.uk literally "includes" the contents of the SPF record published at spf.wallacenetworks.uk

spf.wallacenetworks.uk contains this:
v=spf1 ip4:54.38.79.38 ip6:2001:41d0:801:2000:0:0:0:51f -all

You probably recognise this example from earlier, essentially it is the same SPF record overall, but requires one additional DNS lookup.
There is a limit of a maximum 10 DNS lookup limit to process an SPF record in the specification for SPF.
One include is generally not a problem - as long as it includes something that actually exists.....

e.g.
brokenspf.allanwallace.uk - a perfectly formatted SPF record - contains this:
v=spf1 include:doesnotexist.wallacenetworks.uk -all

Looks good, except doesnotexist.wallacenetworks.uk does not exist.

This breaks the entire SPF record.

If you go to
Kitterman's SPF Query Tool and paste brokenspf.allanwallace.uk into the "domain" box, you will see what I mean.


So, this is one example of how an include: can be dangerous.
Additionally if the DNS lookup fails for whatever reason, it could cause a TEMPERROR which could cause email to be delayed or fail.


The other problem with DNS lookups, is that the number of DNS lookups required to process an SPF record can be crucial.

Remember:
There is a limit of a maximum 10 DNS lookup limit to process an SPF record in the specification for SPF.

10. Not 11, 12, or any number greater than 10.

Here's a real world example:

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

include:spf.protection.outlook.com costs 1 DNS lookup

spf.protection.outlook.com contains this:
v=spf1 ip4:207.46.100.0/24 ip4:207.46.163.0/24 ip4:65.55.169.0/24 ip4:157.56.110.0/23 ip4:157.55.234.0/24 ip4:213.199.154.0/24 ip4:213.199.180.128/26 ip4:52.100.0.0/14 include:spfa.protection.outlook.com -all

Which includes this:
include:spfa.protection.outlook.com - which costs 1 more DNS lookup (total 2)

and contains this:
v=spf1 ip4:157.56.112.0/24 ip4:207.46.51.64/26 ip4:64.4.22.64/26 ip4:40.92.0.0/14 ip4:40.107.0.0/17 ip4:40.107.128.0/17 ip4:134.170.140.0/24 include:spfb.protection.outlook.com ip6:2001:489a:2202::/48 -all

Which includes this:
include:spfb.protection.outlook.com which costs 1 more DNS lookup (total 3)

and contains this:
v=spf1 ip6:2a01:111:f400::/48 ip4:23.103.128.0/19 ip4:23.103.198.0/23 ip4:65.55.88.0/24 ip4:104.47.0.0/17 ip4:23.103.200.0/21 ip4:23.103.208.0/21 ip4:23.103.191.0/24 ip4:216.32.180.0/23 ip4:94.245.120.64/26 -all

- leaving 7 DNS lookups available before the DNS lookup limit is exceeded and the SPF record breaks.

If you have 8 mx, and you add the term mx into your SPF at this point, you have just broken it.

If you add 9 DNS lookups to the 3 that include:spf.protection.outlook.com requires, you can end up with a situation like this:
Office 365 and mailhop - SPF - a small problem.



Remember! - This is just a beginners guide to SPF.

There is more to it than the above, but based on my experience I would estimate the above covers 99% of the implementations you will see on a day to day basis.
You may also discover that of the perfectly formatted SPF records containing only the above mechanisms, many are still broken.

Realistically, if implementation of the above is perceived to be tricky, the Other SPF mechanisms and modifiers may be best avoided.


Don't run before you can walk, remember the KISS principle.


Other SPF mechanisms and modifiers: (in order of increasing confusion)

ptr: pointer mechanism
exists: exists mechanism

redirect= redirect modifier
exp= exp modifier


If at this point you have lost interest, you are not alone. I don't blame you.
If you wish to persevere for just a few minutes more, I'm going to completely ignore those four things, and tell you about these easy ones instead:

+
the + symbol is the DEFAULT modifier (not required by the specification for SPF).
If you see this in an SPF record, either the writer wants it to be crystal clear that it is prefixing something explicitly allowed,
or they haven't read the specification fully, or they like wasting bytes on every SPF check.

-
This indicates HARDFAIL (I think you have probably worked this one out by now...)
if you prefix something with - then you do not want to allow it to send emails.

?
This indicates NEUTRAL - which is a bit like saying "I dunno! - I'm really not sure if it's genuine".

~
This indicates SOFTFAIL - which is a bit like saying "I'm fairly sure that it's not genuine but I cannot be certain".


Based on the usage and advice I have seen, I would estimate that the latter two are too often misused.

Anyway, that's pretty much it for now.


Final Notes:

$ - SPF is part of a solution to reduce the ability of third parties to spoof emails from your domain.
It was designed to target the MAIL FROM: email header, but this is only one of several "FROM" addresses that can be added to an email, and it does not address the others.

DKIM and DMARC are two more parts of the solution to target those other "FROM" addresses that can exists in emails, and they further reduce the ability of third parties to spoof emails from your domain.

Beyond that, DNSSEC and DANE help you prove that it's not just your emails that are genuine, your DNS records (e.g. SPF DKIM and DMARC...) can be proven genuine too.
(DNS records can be faked too, DNSSEC goes some way towards preventing that, DANE takes it one step further.)

There is of course a problem that increased complexity can introduce, in as much that you can introduce weaknesses.
You could have the strictest DMARC policy on the planet, but if your SPF is weak or allows too many servers (I have seen v=spf1 all in an SPF before, and yes, it is valid......) then it can still allow spoofed emails to slip on by.


If you are a business, you surely have a desire to ensure that your emails can be categorically proven to be genuine,
and you surely DO NOT want your customers or staff to get caught out by a spoofed email from a malicious third party.


I use DKIM and I set my SPF and DMARC to be strict as I do not wish third parties to spoof emails from my domain.

Phishing is a risk. CEO fraud is a risk. Why make it easy for criminals and spammers?


Last Updated 2019/06/19 00:12 CET.

Cookie Policy
Privacy Policy
Security Policy
Terms & Conditions

© 2019 Allan Wallace