By default, any computer connected to the Internet can send emails pretending to come from your domain.
That’s true. If you registered example.com for your business and just configured basic email (i.e for sending and receiving XXX@example.com messages), then someone on a cybercafe on the other side of the world can send an email “coming” from firstname.lastname@example.org, for example.
They can do that just fine.
Surprised? Don’t be. That’s how the Internet has been working for decades, and it still is (for good, practical reasons) standard behavior.
SPF is an Internet technology created to address that.
SPF works by allowing you to publish a list of servers that are allowed to send emails on behalf of your domain.
When a third-party server receives an email pretending to be coming from your domain, the server will check your SPF list. If the sending server is there, then the email is legit.
On the other hand, If the sending server is not on the SPF list, then most likely it is a forged email – and the email server will do whatever you tell them to do on your SPF record with such emails.
Pretty simple, isn't it?
SPF is implemented by adding a TXT record to your DNS domain. A typical SPF record look like this:
v=spf1 a a:example.org mx include:mail.example.net ip4:192.168.78.0/24 ip6:2001:0db8:85a3:0000:0000:8a2e:0370:7334 -all
Breaking down this record, we get a list of words (called “terms”). This is what each term means:
v=spf1 indicates that the TXT record is a SPF record.This term is required, and must come first.
a tells servers that if the email is coming from any IP already associated with your domain in the DNS, then there is a match.
a:example.org works similar to the above, except that the IP must be associated with example.org for the term to match.
mx indicates a match if the sending IP is a MX for the domain.
include:mail.example.net instructs email servers to look at a SPF record found at mail.example.net, and consider it while doing SPF checks.
ip4:192.168.0/24 matches if the IP address of the sending server is on a network. You can use simple (host) IP addresses too.
ip6:2001:0db8:85a3:0000:0000:8a2e:0370:7334 works the same as
ip4, but it applies to IPv6 connections.
-all ends the record telling email servers that they should reject the email if none of the preceding terms have matched (technically speaking this whole term means “everyone else is not authorized”).
Each term can be prefixed by a qualifier, which can be
?. Those qualifiers define the outcome of the check when the term matches. The
+ qualifier is implied — in other words,
+a is the same as
Here’s the outcome each qualifier define:
+ (pass) - sending server is authorized
- (fail) - sending server is not authorized
~ (soft-fail) - sending server is not authorized, but the receiving side should still allow email, probably flagging them as spam, setting them aside for moderation, etc.
? (neutral) - no specific outcome — the domain owner (you) cannot tell whether the server is authorized or not.
Email servers scan the terms from left to right, looking for a match. The first term that matches defines the outcome of the SPF check.
(Technically those match/no match terms are called mechanisms. There are other terms in the SPF specification called modifiers, but these aren’t commonly used, and are out of scope of this post. Suffice to say that usually you can protect any Internet domain email using only the list of mechanisms shown above.)
Continuing with our example, when email servers are scanning the terms, matching them against the server they’re receiving, and any term before
all matches, then the server is authorized (because there’s an implicit
+ — a pass — before the terms).
all is a term that matches “anything” or “the whole Internet”. That’s why it is put at the end of the list – it doesn't make sense to have anything after it. You can think of
all as the “default outcome”.
In the example above,
-all will match if no previous mechanisms matched. This will result in a “fail” outcome, due to the
One special case (not very common or useful, but helpful to understand how SPF works), is when no mechanism matches, and no
all term is present. In this case, the SPF check result is “neutral”. It is as if you had put
?all at the end.
~ qualifier soft-fails the check, and is used to indicate that the sending server is not authorized, yet receiving servers should not reject the message right away. This is commonly used to test SPF. When a SPF check’s outcome is a soft-fail, emails may be saved to spam/junk folders, but still be delivered.
There are a few other mechanisms and modifiers in the SPF specification, but the ones above are the most common ones.
SPF is one authentication method used by DMARC-compliant servers to determine if an email is legit or not.
There is something very important that you need to know, though: while SPF checks whether a sending server is authorized or not by looking at its network host/address, DMARC checks the “From” header of the message.
To conciliate the two checks, DMARC uses something called “alignment”.
For a SPF pass to be considered a DMARC pass, not only the sending server must be authorized, but the domain checked by SPF must be in alignment with the “From“ header.
In DMARC-speak, alignment means that the domain checked by SPF must be the same as the one in the “From” line (for DMARC “strict” alignment), or it is a sub-domain of the sending server (for “relaxed” alignment).
However... the domain checked by SPF is not the one in the “From” line, but the “Envelope From” and server name (from SMTP’s HELO’s command).
Are you still with me?
This can be rather confusing, so let’s draw a small table to illustrate how it works:
|SPF domain||SPF result||DMARC alignment||Email “From“||DMARC||Notes|
|email@example.com||pass||Domain in “From“ is the same checked by SPF|
|firstname.lastname@example.org||fail||Because SPF domain is not the same (not in “alignment”) with “From“, DMARC fails, even though SPF had passed|
|email@example.com||pass||Domains are not the same, but “From“ is a subdomain of the one checked by SPF, so DMARC passes|
|firstname.lastname@example.org||fail||DMARC fails because “strict” alignment does not matches across subdomains|
So when you configure DMARC, you must make sure that your authorized servers (in SPF’s context) have names compatible with your domain, or are sending emails with your domain in the “Envelope From”. If they aren't, then DMARC alignment will fail, even when SPF checks pass.
In summary, SPF is a Internet protocol that allows a domain owner to tell the world (i.e. other email servers) which servers are authorized – and which are not – to send emails on behalf of their domains. It is one of the first barriers one can implement to stop email forgery.
DMARC uses SPF (together with DKIM) as an authentication mechanism to tell email providers how to handle potentially forged emails. DMARC, however, does that using the concept of “alignment” which ties SPF with the “From” header of the email (the one your users see when they open an email).
We hope that this post is helpful to explain what SPF is, and how it can be used in the context of a DMARC-compliant server. Happy emailing!