Sender Policy Framework (SPF)
Internet Security, Internet Standard. An email authentication standard that sets which servers can send email from their domain. RFC 7208 defines this standard.
Sender Policy Framework (SPF) lets domains specify which servers they authorized to send email on their behalf. Receiving hosts can confirm this authorization. An SPF is one of three domain-based authentication methods for email. SPF attempts to prevent email sending abuse.
To understand SPF, consider how email traffic changes with SPF.
- An email server receives an email message.
- The receiving email server checks the message's
return-path. Thereturn-pathissender@example.com. - The receiving email server retrieves the SPF record from the DNS records for the
example.comdomain. - The receiving server asks the DNS server listed in the message's
return-pathheader for its SPF record. - The receiving server compares the IP address of the sending server in the
return-pathheader with the SPF record's list of authorized IP addresses. - If the SPF check passes, the receiving server accepts the message.
- If the SPF check fails, the receiving server processes the message in a way consistent with the sending server's SPF policy.
An SPF record resides as the value of a DNS TXT record that resemble the following:
v=spf1 (<mechanism>[:<host or range>])... ~all
The TXT record value must adhere to the following standards:
- It must follow RFC 1035 3.3.14 format for DNS records.
- It can't exceed 512 bytes.
- All SPF record values start with
v=spf1. This means that the value is an SPF version 1 record. - The mechanism covers how the authorized IP address gets identified. Most times, this is a DNS record type. This can appear more than once.
- The host or range covers which host or hosts the domain authorized to send email. This is optional and can appear with additional mechanisms.
- The SPF record value ends with
~allas a catchall for no other hosts or servers.
The mechanisms define the set of hosts allowed to send email. These mechanisms specify either an IP address, an IP address range, a DNS record type, a domain, a domain range, or a DNS query. These values resolve to one or more IP address authorized to send email on behalf of the domain.
| Mechanism | Description |
|---|---|
all | Matches all hosts. Put at the end of the SPF record. |
ip4 | Matches all hosts with IPv4 addresses in the specified CIDR block. |
ip6 | Matches all hosts with IPv6 addresses in the specified CIDR block. |
a | Matches all hosts in the domain with the specified A DNS record. Used for IPv4 addresses only. |
aaaa | Matches all hosts in the domain with the specified AAAA DNS record. Used for IPv6 addresses only. |
mx | Matches all hosts in the domain set as mail exchanger (MX) records. |
ptr | Matches all hosts in the domain set as pointer (PTR) records. |
exists | Perform an A query on the domain. Found results constitute matches. |
include | Search the domain for a match. If lookup doesn't match or returns an error, proceed to next mechanism. |
| Modifier | Description |
|---|---|
redirect=<domain> | Use the domain specified instead of the current domain. |
exp=<domain> | Send an explanation when a host doesn't match an IP address. |
Hosts or ranges can have four qualifiers:
| Qualifier | Result | Intention | Explanation |
|---|---|---|---|
+ | Pass | Accept message | SPF record indicates the host can send email |
~ | Soft Fail | Accept but mark message | SPF record indicates the host can't send email but is transitioning to that state |
- | Fail | Reject message | SPF record indicates the host can't send email |
? | Neutral | Accept message | SPF record indicates explicitly that it has no position on the host's validity |
A typical SPF record that allows Twilio SendGrid to send emails for your domain would look something like this:
v=spf1 include:sendgrid.net -all
| Example | Authorize only these hosts to send email |
|---|---|
v=spf1 mx ~all | Allow all MX hosts in the domain. |
v=spf1 -all | The domain can't send email. |
v=spf1 ip4:192.0.2.1/16 ~all | Allow any IPv4 address between 192.0.0.0 and 192.0.255.255. |
v=spf1 ip4:192.0.2.1 ~all | Allow the IP addresses of 192.0.2.1. |
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. |
v=spf1 a:example.com ~all | Allow any IPv4 address with an A record in the example.com domain. |
v=spf1 a ~all | Allow any IPv4 address with an A record in the current domain |
v=spf1 aaaa:example.com ~all | Allow any IPv6 address and an AAAA record in the example.com domain. |
v=spf1 mx mx:deferrals.example.com ~all | Allow any IP address with an MX record plus another set of hosts used for deferrals. |
v=spf1 ptr ~all | Allow any host in the domain. |
v=spf1 ptr:other.example.com ~all | Allow any host in the other.example.com domain. |
v=spf1 exists:mx.example.com ~all | If the host resolves, allow it. |
v=spf1 include:_spf.example.com ~all | If the IP address can be found in the example.com domain, allow it. |
To resolve an SPF record, the SPF RFC limits the number of DNS lookups to 10. You can exceed this limit through the poor use of the include mechanism.
RFC 7208, Section 4.6.4 "Processing Limits", specifies the following limitations:
Some mechanisms and modifiers (collectively, "terms") cause DNS queries at the time of evaluation, and some do not. The following terms cause DNS queries: the "include", "a", "mx", "ptr", and "exists" mechanisms, and the "redirect" modifier. SPF implementations MUST limit the total number of those terms to 10 during SPF evaluation, to avoid unreasonable load on the DNS. If this limit is exceeded, the implementation MUST return "permerror". The other terms—the "all", "ip4", and "ip6" mechanisms, and the "exp" modifier—do not cause DNS queries at the time of SPF evaluation (the "exp" modifier only causes a lookup at a later time), and their use is not subject to this limit.
This limit prevents bad actors from using SPF lookups for Denial of Service attacks.
To avoid exceeding this limit, minimize the number of SPF mechanisms that need to resolve IP addresses. These include the a, aaaa, mx, ptr, exists, include mechanisms.
To avoid SPF validation issues related to DNS lookup limitations, optimize your SPF record. Consider the following best practices:
- Minimize
includeMechanisms: Reduce the use of theincludemechanism to only include domains that are essential for your email delivery. - Use IP Mechanisms: Specify IP addresses directly with the
ip4andip6mechanisms as these mechanisms don't require DNS lookups. - Monitor SPF Records: Review and update your SPF record on a regular cadence. Keep it efficient and compliant with the SPF specification.
- Check your SPF Record: To validate your SPF record, use the SPF Record Check at MxToolbox.
To learn how Twilio SendGrid assists in SPF configuration, see Configure domain authentication.