Sender authentication part 10: More on SPF Syntax

Moving onwards to mechanisms, let's take a look at them in a bit more detail.  Again, this information comes straight from the OpenSPF page, with extra commentary by me.

The all mechanism

all

This mechanism always matches. It usually goes at the end of the SPF record.

Example 1

v=spf1 mx -all

Allow the domain's MXes to send mail for the domain, prohibit all others.  Reading the syntax from left to right, the version of SPF is 1.0, return a pass if the sending IP is in the MX records for the domain, return a Fail on everything else.  Note that the implied syntax is the following:

v=spf1 +mx -all

Example 2

v=spf1 -all

The domain sends no mail at all.  Read left to right, the version of SPF is 1.0, return a Fail on everything (ie, if any IP has this domain name in the envelope sender, return a Hard Fail).

Example 3

v=spf1 +all

A record like this defeats the purpose of SPF.  To interpret it, the version of SPF is 1.0, return a pass on everything.  If you are returning a pass on everything, it means that whatever IP is sending mail for your domain, you say that's okay.  That means any IP can forge your domain.

The ip4 mechanism
 ip4:<ip4-address>
ip4:<ip4-network>/<prefix-length>

The argument to the "ip4:" mechanism is an IPv4 network range. If no prefix-length is given, /32 is assumed (singling out an individual host address).  This is one of the easier records to interpret.

Example 1

"v=spf1 ip4:192.168.0.1/16 -all"

Allow any IP address between 192.168.0.1 and 192.168.255.255.  If the transmitting IP is not within this range, return a Hard Fail.

The ip6 mechanism
 ip6:<ip6-address>
ip6:<ip6-network>/<prefix-length>

The argument to the "ip6:" mechanism is an IPv6 network range. If no prefix-length is given, /128 is assumed (singling out an individual host address).

Example 1

"v=spf1 ip6:1080::8:800:200C:417A/96 -all"

Allow any IPv6 address between 1080::8:800:0000:0000 and 1080::8:800:FFFF:FFFF.

Example 2

"v=spf1 ip6:1080::8:800:68.0.3.1/96 -all"

Allow any IPv6 address between 1080::8:800:0000:0000 and 1080::8:800:FFFF:FFFF.

 

The a mechanism
 a
a/<prefix-length>
a:<domain>
a:<domain>/<prefix-length>

All the A records for the domain are tested. If the client IP is found among them, this mechanism matches.

If domain is not specified, the current-domain is used.

The A records have to match the client IP exactly, unless a prefix-length is provided, in which case each IP address returned by the A lookup will be expanded to its corresponding CIDR prefix, and the client IP will be sought within that subnet.

Example 1

v=spf1 a -all

Lookup the A-record of the current domain.  If it matches the transmitting IP, return a Pass. If not, return a Fail.

Example 2

v=spf1 a:example.com -all

Lookup the A-record of example.com.  If it matches the transmitting IP, return a Pass.  If not, return a Fail.

Example 3

v=spf1 a:mailers.example.com -all

Example.com has explicitly listed all of its outbound mailers in a special A-record under mailers.example.com.  Lookup the A-record for mailers.example.com, and if the transmitting IP is found amoung them, return a Pass.  If it is not, return a Fail. 

Example 4

v=spf1 a/24 a:offsite.example.com/24 -all

This SPF record lists two possible mailers, a/24 and a:offsite.example.com/24.  Lookup the A-record of teh current domain and assume that it resolves to 192.0.2.1; the entire class C of 192.0.2.0/24 would be searched for the client IP.  Similarly, assume that the A-record for offsite.example.com is 192.0.3.1.   It would be expanded to 192.0.3.0/24 and would be searched for transmitting IP.  If more than one A record were returned for the domain, each one would be expanded to a CIDR subnet.

If not match was no found, a Fail would be returned.

In my next post, we will get to the mx, ptr, exists and include mechanisms.  Then, we will take a look at some real-life SPF records.