What are SPF Records?
SPF records are an important tool for maintaining control over which servers are allowed to send email with your domain name. More complete information regarding the purpose of SPF records in preventing email Spoofing is available here, and quality tools for automatically generating SPF records are available in the Email Authentication icon in cPanel or from external SPF generators that can be used to create SPF records conveniently with very little knowledge about how they work. This is an advanced article that will provide detailed information for anyone who wants a better understanding of the syntax of SPF records. Our article regarding problems with spoofing details how to create an SPF record which will be supplemented here with specific information for how to format the contents of the TXT data field in the advanced DNS editor when creating the TXT record.
This article will be broken up into several sections:
- What should be included in an SPF record?
- What operators may be used on arguments in an SPF record?
- What arguments may be used in an SPF record?
- What order should arguments be in?
What should be included in an SPF record?
A basic SPF record should be composed of three parts. The first required part is the prefix identifying the TXT data as an SPF record. This prefix should then be followed by a list of servers and hosts that are authorized to send email using the domain. Finally, a basic SPF record should be followed by a list of servers that are specifically denied from sending mail as the user. This final section is usually abbreviated to all server not specifically granted authorization. Here is an example of an auto generated SPF record for a domain hosted on a shared HostGator server followed by a breakdown of all of its parts:
v=spf1 a mx include:websitewelcome.com ~all
- The SPF prefix: v=spf1
A list of servers and hosts authorized to send email for this domain: a mx include:websitewelcome.com
This portion of the record can be further broken down as follows:
- If mail is sent from an IP matching the A record of this domain.
- If mail is sent from an IP matching the MX record(s) of this domain.
- If mail is sent that matches any rules for the websitewelcome.com SPF record.
- A soft denial for any server not specifically permitted to send mail: ~all
What operators can be used in an SPF record?
Here is a complete list of operators which may be used to specify how arguments in an SPF record are treated and what effect they should have:
"+" This is a pass operator. If an argument using this operator can be applied to an email, the email will be allowed to pass as authorized. If no operator is specified by an argument it is assumed to be "+"
For example, both of these records would be treated the same:
- v=spf1 a ~all
- v=spf1 +a ~all
- "-" This is a fail operator. Any email that matches an argument with this operator will be specifically rejected.
- "~" This is a soft fail operator. Any email that matches an argument with this operator will be allowed to pass, but will be flagged as spam.
- "?" This is a neutral operator. Email that matches an argument flagged with this operator will neither be actively rejected or allowed to pass.
What arguments can be used in an SPF record?
Here is a list of all arguments which may be used to make rules inside of an SPF record:
The most important argument for creating a well made SPF record is the all argument. The all argument includes all IP addresses and host names which have not been addressed by a previous rule in the SPF record. In this example SPF record all email sent from the domain this record is created for will soft fail since there are no rules prior to the argument all being implemented with a soft fail operator:
An SPF record may also accept a full IPv4 or IPv6 address as an argument using the tags ip4 and ip6 respectively. This example SPF record will mark email sent from the IP addresses 127.0.0.1 and 2001:0db8:85a3:0042:1000:8a2e:0370:7334 as authorized and soft fail all other email:
v=spf1 ip4:127.0.0.1 ip6:2001:0db8:85a3:0042:1000:8a2e:0370:7334 ~all
An SPF record may also accept the terms a, mx, or ptr as arguments, allowing the SPF record to self reference the existing A, MX, or PTR records for the domain the SPF is created for. For example, if the following SPF record were created for example1.com, mail sent from IP addresses matching either the A, MX, or PTR records of example1.com would be allowed to send mail from email addresses using example1.com, and all other email would soft fail:
v=spf1 a mx ptr ~all
These arguments may also be used to include records from other domains. For example to authorize mail to be sent from an IP matching the MX record for example2.com and email from an IP address that matches the PTR for example3.com, this syntax would by used:
v=spf1 mx:example2.com ptr:example3.com ~all
An SPF record may also include the SPF record from other domains by using the include argument. The following example will mark any email that is permitted by the SPF record for websitewelcome.com to send email for the domain it is applied to, and soft fail all other mail:
v=spf1 include:websitewelcome.com ~all
An SPF record may use the term exists as an argument to authorize email to be sent from a domain if an A record for that domain exists. It does not matter if the IP address of that domain name matches the originating IP address for this email or not. What matters is that, an
A record should exist and that's all. For example, in this example, if an A record exists for example2.com, then the email is authorized, and if not it will generate a soft fail:
v=spf1 esists:example2.com ~all
What order should arguments be in?
Arguments are processed from left to right. As soon as an argument is found that matches the information for the server which sent the mail that rule will be followed and the rest of the record will be ignored. With this in mind, arguments should be ordered so that more specific arguments are in front of more general arguments. For example, this record would not work correctly:
v=spf1 ~all +ip4:127.0.0.1
In this rule the argument all is placed with a soft deny rule in front of an allow rule with the argument ip4:127.0.0.1, this will cause the rule using ip4:127.0.0.1 to always be ignored. This is because if an email is sent from ip4:127.0.0.1 it is included in the argument all, and so it will be given a soft fail before the allow argument is addressed.
This is the proper way to format a record so that mail is authorized from the 127.0.0.1 IP address:
v=spf1 +ip4:127.0.0.1 ~all