SPF Records (both TXT style SPF records and 'true' SPF records)
CompletedSPF ('Sender Policy Framework') records are a way to specify which servers are allowed to send email for a domain. Why might this be important? As an example, if your domain is used for important financial information, you almost certainly don't want random "bad guys" to be able to send phishing email claiming to be from your institution! SPF records provide a way for you to specify exactly what mail servers are allowed to send mail claiming to come from your domain.
For the moment I'm only going to discuss "TXT style" SPF records. (I'll add a discussion of "true" SPF records and SENDERID records at the end of this article.) In this context, an SPF record is a specially formatted TXT record. The rdata (Record DATA) section of the record will begin with "v=spf1 " (without the quotes, I use them to make it clear exactly what's supposed to be there...for example, the trailing space in "v=spf1 " is required.) The remainder of the rdata section is a series of "mechanisms" that allow saying things like "this IP address can send mail for the domain", "this server name can send mail for the domain", etc. These are processed in order (left to right), and the mail is to be accepted as soon as a mechanism matches, even if a later mechanism would reject it. This allows things like saying "accept mail if it comes from a particular IP, then follow that with a "reject everything". It's actually possible to use a mechanism to reject something, and follow it with other "accept" mechanisms, but it's quite uncommon...normally the SPF record is a series of "this can send mail" mechanisms, with a "reject everything else" at the end.
The mechanisms can be complex and somewhat confusing. They're specified in RF 7208:
https://datatracker.ietf.org/doc/html/rfc7208
(but RFCs can be hard reading!) Briefly, it says "there are ways to say "allow this if the mail comes from a server that matches" one of:
- a (matches an A record)
- mx (if the sender is also the host in an MX record for the domain)
- ip4 (if the sender's IP matches the specified IPv4 address)
ip6 (if the sender's IP matches the specified IPv6 address) - include (inserts the contents of some other SPF record, either to accept mail from an outside mail server, or just to break the main SPF record into smaller chunks)
- exists (beyond the scope of this article!)
As mentioned, these mechanisms are processed in order, and if one matches, the mail is to be accepted. There's generally a final mechanism that tells what to do if nothing else matched.
The final mechanism is generally one of:
- -all ("HARD FAIL"...reject the mail)
- ~all ("SOFT FAIL"...the mail doesn't match, so flag it as questionable and accept it anyway)
- ?all ("neutral"...also accept it anyway)
It is actually possible to prefix any mechanism with a dash ("-") or a tilda ("~"), in which case, mail from matching servers is to be rejected, but in most cases. only the last mechanism is used to reject mail from a particular server.
The simplest SPF record would simply be "v=spf1 -all" ("this is an SPF record;
reject everything." In other words, "there's never going to be email from this domain".) This may seem odd, but if you have a number of subdomains, and only send mail from the primary domain, this prevents email claiming to come from one of the subdomains.)
In general, SPF records tend to be somewhat complex. There is a fairly good reference page at:
http://www.open-spf.org/SPF_Record_Syntax/
It gives a number of fairly simple examples, and describes how to use each of the mechanisms. The same site used to have a simple wizard for generating SPF records; it was overly simplistic, and has been withdrawn, but there is another at:
which can be quite helpful when you're starting to learn how to write SPF records.
Once you have a tentative SPF record formulated, it is VERY wise to validate it. The best site I'm aware of for this is provided by the principal author of the SPF RFC:
https://www.kitterman.com/spf/validate.html
It has 3 sections. The first, titled "Does my domain already have an SPF record? What is it? Is it valid?" does just what it sounds like; enter your domain name and ask it to get the SPF record. It'll show what is currently configured for your domain and tells whether it is valid.
The second, "Is this SPF record valid - syntactically correct?" lets you enter your domain name and the rdata for the SPF record you want to add; it checks whether it is valid, and if it isn't, it explains why. This section only looks at syntax, so it doesn't check whether the record would do what you intend.
The third, "Test an SPF record" lets you enter the rdata for your SPF record, the IP address the mail comes from, the address the mail server claims it comes from (the "HELO/EHLO" address), and tells what the SPF check would do.
Kitterman's testing site is wonderful, particularly if you're just getting started!
There are two final subjects I said I'd return to: the "true" SPF record type, and SENDERID.
Originally SPF records were specified as I described above, a TXT record with specifically formatted rdata (which begins with "v=spf1 "). At one point, people who ran mail servers asked to make a "true" SPF record type (that is, define a special record type, similar to A, MX, CNAME, etc., specifically for SPF records.) This was done (and UltraDNS actually supports them, both in
the sense that we can return them, and in the sense that our portal allows configuring them.) To make sure that old mail servers (that hadn't been updated to use the SPF record type) would still work, configuring an SPF record required configuring a TXT style record, but allowed a record of type SPF...but it required that the two have identical RDATA. It also required that if a mail server tried ot fetch a true SPF record, but there was no such record, it must try again with a TXT style SPF record. It turned out that the authors of most mail servers just stayed with the TXT style record, so eventually the true SPF record type was deprecated. It remains on UltraDNS to support configuraitons which use the true SPF record, but:
- If you use a true SPF record, YOU must configure the required TXT record as well, and the two record's rdata must be identical.
- For any new configurations, only TXT style SPF records should be configured.
- Ideally if you have an existing SPF record, best practice is to verify that the equivalent TXT style record is configured, then delete the true SPF record.
It's worth noting that many, probably most, mail servers really only look at the TXT style SPF records!
Finally, I mentioned SERVERID. It is NOT an updated SPF (though it was deliberately built to look like it is!) It was an experimental extension to SPF which never solidified. It was largely developed by Microsoft, though others worked on it as well, but even Microsoft no longer uses it. If you have any SENDERID records (TXT records with rdata that begins "v=spf2.0/" you should do your best to add the closest SPF record you can construct, and delete the SENDERID record. In general, SENDERID is similar enough to SPF to allow the equivalent SPF record to be added. And SENDERID is basically ignored by most or all mail servers.