A carefully tailored SPF record will reduce the likelihood of your domain name getting fraudulently spoofed and keep your messages from getting flagged as spam before they reach your recipients. Email spoofing is the creation of email messages with a forged sender address; something that is simple to do because many mail servers do not perform authentication. Spam and phishing emails typically use such spoofing to mislead the recipient about the origin of the message. A number of measures to address spoofing, however, have developed over the years: SPF, Sender ID, DKIM, and DMARC. Sender Policy Framework (SPF) is an email validation system designed to prevent spam by detecting email spoofing. Today, nearly all abusive e-mail messages carry fake sender addresses. The victims whose addresses are being abused often suffer from the consequences, because their reputation gets diminished, they have to waste their time sorting out misdirected bounce messages, or (worse) their IP addresses get blacklisted.
The SPF is an open standard specifying a technical method to prevent sender-address forgery. SPF allows administrators to specify which hosts are allowed to send mail on behalf of a given domain by creating a specific SPF record (or TXT record) in the Domain Name System (DNS). Mail exchangers use DNS records to check that mail from a given domain is being sent by a host sanctioned by that domain's administrators.
Adding an SPF record to your DNS zone file is the best way to stop spammers from spoofing your domain. In addition, an SPF Record will reduce the number of legitimate e-mail messages that are flagged as spam or bounced back by your recipients' mail servers. The SPF record is not 100% effective, unfortunately, because not all mail providers check for it. Many do, however, so you should notice a significant decrease in the amount of bounce-backs you receive.
An SPF record is added to your domain's DNS zone file as a TXT record and it identifies authorized SMTP servers for your domain.
TXT @ "v=spf1 a include:_spf.google.com ~all"
If you are utilizing the DigitalOcean DNS Manager, make sure to wrap the SPF record with quotes. The following table provides an explanation of the various components of the Example SPF Record:
Components | Description |
---|---|
TXT | The DNS zone record type; SPF records are written as TXT records |
@ | In a DNS file, the "@" symbol is a placeholder used to represent "the current domain" |
v=spf1 | Identifies the TXT record as an SPF record, utilizing SPF Version 1 |
a | Authorizes the host(s) identified in the domain's A record(s) to send e-mail |
include: | Authorizes mail to be sent on behalf of the domain from google.com |
~all | Denotes that this list is all inclusive, and no other servers are allowed to send e-mail |
An SPF record consists of the SPF version number followed by strings comprised of (i) mechanisms, (ii) qualifiers, and (sometimes) (iii) modifiers. SPF clients ignore TXT records that do not start with the version string "v=spf1 ..."
.
SPF records may define zero or more mechanisms. Mechanisms can be used to describe the set of hosts which are designated as authorized, outbound mailers for the domain. The following list are common mechanisms included in an SPF record:
all | ip4 | ip6 | a | mx | ptr | exists | include
Mechanisms can be prefixed with one of four qualifiers:
Qualifier | Description |
---|---|
+ | Pass = The address passed the test; accept the message. Example: "v=spf1 +all" |
- | (Hard) Fail = The address failed the test; bounce any e-mail that does not comply. Example: "v=spf1 -all" |
~ | Soft Fail = The address failed the test, but the result is not definitive; accept & tag any non-compliant mail. Example: "v=spf1 ~all" |
? | Neutral = The address did not pass or fail the test; do whatever (probably accept the mail). Example: "v=spf1 ?all" |
If a qualifier is not included, the +
qualifier is implied.
SPF records may also define 1 of 2 modifiers; or, no modifier at all. Each modifier, however, can appear only once.
redirect | exp
SPF records are evaluated in a two-pass process: First, all mechanisms and qualifiers are evaluated. Then, all modifiers are evaluated:
Mechanism | Description |
---|---|
all | Matches all local and remote IPs and goes at the end of the SPF record. Example: "v=spf1 +all" |
ip4 | Specifies a single IPv4 address or an acceptable IPv4 address range. A mask of /32 is assumed if no prefix-length is included. Example: "v=spf1 ip4:192.168.0.1/16 -all" |
ip6 | Same concept found in ip4, but, obviously, with IPv6 addresses, instead. If no prefix-length is given, /128 is assumed (singling out an individual host address). Example: "v=spf1 ip6:1080::8:800:200C:417A/96 -all" |
a | Specifies all IPs in the DNS A record. Example: "v=spf1 a:domain.com -all" |
mx | Specifies all A records for each host's MX record. Example: "v=spf1 mx mx:domain.com -all" |
ptr | Specifies all A records for each host's PTR record. Example: "v=spf1 ptr:domain.com -all" |
exists | Specifies one or more domains normally singled out as exceptions to the SPF definitions. An A query is performed on the provided domain; if a result is found a match occurs. Example: "v=spf1 exists:domain.com -all" |
include | Specifies other domains that are authorized domains. Example: "v=spf1 include:outlook.microsoft.com -all" |
The all
mechanism usually goes at the end of the SPF record; and it is prefixed with a qualifier, e.g.
Examples | Description |
---|---|
"v=spf1 mx -all" | Allows the domain's MX hosts to send mail for the domain, and prohibits all other hosts. |
"v=spf1 -all" | The domain sends no mail at all. |
"v=spf1 +all" | This SPF is useless, as it does not limit the hosts that are authorized to send e-mail. |
Modifiers are optional and a modifier may appear only once per record. Unknown modifiers are ignored.
The “redirect” modifier sends the inquiry to another domain.
redirect=example.com
That is, the SPF record for example.com replaces the SPF record for the current domain. The redirect modifier is useful to those that wish to apply the same record to multiple domains. For example:
Sample entry in ny.yourdomain.com's zone file: | TXT @ "v=spf1 redirect=_spf.yourdomain.com" |
Sample entry in sf.yourdomain.com's zone file: | TXT @ "v=spf1 redirect=_spf.yourdomain.com" |
Sample entry in am.yourdomain.com's zone file: | TXT @ "v=spf1 redirect=_spf.yourdomain.com" |
Sample entry in _spf.yourdomain.com's zone file: | TXT @ "v=spf1 mx:yourdomain.com -all" |
For clarity, it is RECOMMENDED that any "redirect" modifier appear as the very last term in a record.
The "exp" modifier sets up an explanation in the SPF record.
exp=[macro-string]
If an SPF query produces a FAIL result, the explanation is queried and the explanation string provides more information to the nonconforming user. The explanation is typically placed in an SPF log. Example: exp=spf-error. An SPF publisher can specify the explanation string that senders see. This way, an ISP can direct nonconforming users to a web page that provides further instructions.
Although you do not need an SPF record on your DNS server to evaluate incoming email against SPF policies published on other DNS servers, the best practice is to set up an SPF record on your DNS server. Setting up an SPF record lets other email servers use SPF filtering (if the feature is available on the mail server) to protect against incoming email from spoofed, or forged, email addresses that may be associated with your domain. As SPF records are implemented more widely, SPF filtering will become more effective at identifying spoofed email messages.
As always, if you need help setting up your SPF record, look to the DigitalOcean Community for assistance by posing your question(s), below.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
@schroeder.noia: Did you follow a specific article on setting up postfix?
Also, try changing your TXT record to this:
<pre>TXT @ “v=spf1 mx a ip4:<strong>yourdropletsip</strong> ~all”</pre>
Replace yourdropletsip with your droplet’s IP.
Can misconfiguration in an SPF record lead to blacklisting of the sender domain?
What if I only want to allow sending email from Postfix directly from the server?The example shows
include:_spf.google.com
. I’m not sure what to do…should I leave out the include part?hhhhhhhhhhhhhh how to make it
Thank you for your post! I was really clear and helpful to me.
I find it easier to just use an SPF wizard such as https://www.spfwizard.net/.
i tried many solutions but with no result, i can receive mail from gmail but can’t send or reply. Any other soution please
Hello, I have integrated TrendMicro HES into Office 365 so the mail goes to TrendMicro HES first and is filtered and then sent to Office 365 for delivery. I was trying to keep the original Office 365; mail.protectiuon.outlook.com in place as a fail over in case there is an issue with the TrendMicro HES system. Would I need to completely remove the spf.protection.outlook.com -all and add the v=spf1 include:spf.hes.trendmicro.com –all? It seems I have a conflict where the SPF is set for office 365 but the email is really coming from TrendMicro HES.
Thanks in Advance.
Here is what my SPF record shows from MX Toolbox: v=spf1 ip4:XXX.XXX.XXX.XXX include:sl8v-hv2j.accessdomain.com include:spf.mailjet.com include:spf.protection.outlook.com -all
But my Office 365 settings show: Expected vs actual record Priority Host name Points to address or value TTL Status Expected record 0 @ XXXXXXX-com.mail.protection.outlook.com. 3600 The records matched, however the priority doesn’t match the expected values Actual record 20 @ XXXXXXX-com.mail.protection.outlook.com. 43200 Actual record 10 @ in.hes.trendmicro.com. 43200 Invalid entry CNAME records Copy this table Expected vs actual record Host name Points to address or value TTL Status Expected record autodiscover autodiscover.outlook.com. 3600 Correct Expected record sip sipdir.online.lync.com. 3600 Correct Expected record lyncdiscover webdir.online.lync.com. 3600 Correct TXT records Copy this table Expected vs actual record TXT name TXT value TTL Status Expected record @ v=spf1 include:spf.protection.outlook.com -all 3600 Correct
grate
Anyone else have issues with not being able to enter a hostname without it being domain.com.domain.com? I can’t leave it blank either…