This page defines configuration of a Sender Policy Framework (SPF) record for a domain and its mail servers. DKIM/ADSP is an alternative or complimentary approach involving the signing of mail to authenticate the sender domain. DKIM is significantly more complex than SPF but provides significantly more functionality. Finally, the DMARC RR provides a method by which a domain can advise the mail receiver whether mail originating from a domain will have DKIM, SPF or both, what to do with mail that fails either DKIM or SPF checks and whether it wishes failure reports.
<grovelling apology> The macro feature of SPF was incorrectly documented using parenthesis, these should have been braces ({}).</grovelling apology>
SPF was initiated by Meng Weng Wong of pobox.com to enable validation of legitimate sources of email for a domain and is an IETF standard (RFC 7208).
Briefly, the design intent of the SPF resource record (RR) is to allow a receiving MTA (Message Transfer Agent) to interrogate the Name Server (DNS) of the domain which appears in the email (the sender) and determine if the originating IP of the mail (the source) is authorized to send mail for the sender's domain. The mail sender is required to publish an SPF TXT RR (documented here) in the DNS zone file for their domain but this is transparent to the sending MTA. That is, the sending MTA does not use the sending domain's SPF RR(s) but the receiving domain's MTA will interrogate and use the sending domain's SPF RR(s).
The SPF information must be defined using a standard TXT resource record (RR).
Note: The current SPF RFC (RFC 7208) has essentially moved the SPF RR (defined by RFC 4408) to a deprecated status. The logic behind this advice is that while your DNS may support the SPF RR capability, it's the receiving MTA's DNS (and the MTA's SPF handler) which determines SPF processing and it may not support the SPF RR type but will ALWAYS support the TXT RR type. For the foreseeable future if a domain has both a SPF TXT RR and an SPF RR it will do no harm to leave the SPF RR in place but it should be removed at the earliest sensible opportunity. No mail domains should be using an SPF RR only since this has never been a recomended practice. This page has removed all references to the SPF RR except for this explanation. The term SPF TXT RR, while a little long-winded, is used throughout to mean a TXT RR with the SPF-specific data encoded within its text field.
If a SPF TXT RR exists and authorizes the source IP address the mail can be accepted by the MTA. If the SPF TXT RR does not authorize the IP address, the mail can be bounced - it did not originate from an authorized source for the sender's domain.
Most Open Source MTAs (as well as commercial mail software) have been modified (or have plug-ins) to use the SPF record. There is no down-side (assuming you get the SPF TXT RR right) and plenty of potential up-side (elimination/reduction of some spam categories) in implementing the SPF record.
We use the following terminology to try to simplify the descriptions below:
The SPF record defines one or more tests to carry out to verify the sender. Each test returns a condition code (pre below). The first test to pass will terminate SPF processing.
Configuration of an SPF record may look complicated (all those blasted options) but in practise tends to be quite simple once you understand what it is trying to do. While we suggest you slog your way through the description below, those of a more impatient disposition may want to simply jump to the examples, select the one that most closely fits the circumstances and then go back and read the appropriate text to understand what it is doing.
The standard SPF TXT resource record format is defined as:
name ttl class TXT "SPF-specific text"
The SPF TXT RR is a standard TXT resource record with SPF-specific data encoded within the text field and is defined by RFC 7208. The TXT RR is the only RR type currently defined to support SPF functionality. The previous version of the RFC (RFC 4408) defined, and allowed use of, an SPF RR type. The SPF RR type has, essentially, been deprecated but should continue to work in DNS software that supports it (not all do) for the foreseeable future but should be removed from the zone file at the earliest sensible opportunity.
The SPF data is entirely contained in the text field (a quoted string). SPF defines the contents of the quoted string as follows:
v=spf1 [[pre] type ] ... [mod]
As may be seen the SPF TXT RR allows multiple type arguments to be included. Processing cycles from left to right until either a conclusive result is obtained or until the type arguments have been exhausted. The last type argument should be all which terminates the validation sequence.
Where:
v=spf1 |
||||||||||||||||||||||||||
Mandatory. Defines the version being used. Currently the only version supported is spf1. |
||||||||||||||||||||||||||
pre |
||||||||||||||||||||||||||
Optional (defaults to +). May take one of the following values:
Each sender mechanism returns either a match (the test was successful) or a no match (the test failed) condition. pre defines what happens according to the following matrix:
In all cases if no match is returned processing continues with the next type. Thus, if a sender mechanism test is conclusive either add + or omit (defaults to +). If a test might not be conclusive use "?" or "~" (tilde) processing will continue with the next type. "-"(minus) is typically only used with -all to indicate that if we have had no previous matches - fail but could be used as a negative test such as "if this test matches fail the mail...". |
||||||||||||||||||||||||||
type |
||||||||||||||||||||||||||
Defines the mechanism type to use for verification of the sender. May take one of the following values: Basic MechanismsThese types do NOT define a verification mechanism but affect the verification sequence.
Sender MechanismsThese types define a verification mechanism.
|
||||||||||||||||||||||||||
mod |
||||||||||||||||||||||||||
Two optional record modifiers are defined. If present they should follow the last type directive i.e. after the all. The current values defined are as follows:
|
SPF defines a number of macro-expansion features as defined below:
Note: all macro-expansion delimiters use braces {}.
Modifier | Description |
%{c} | Only allowed in TXT records referenced by the exp field. The IP of the receiving MTA. |
%{d} | The current domain, normally the sender-domain %{o} but replaced by the value of any domain argument in the sender mechanism type. |
%{h} | The domain name supplied on HELO or EHLO, normally the hostname of the sending SMTP server. |
%{i} | sender-ip The IP of SMTP server sending mail for user, say, info@example.com. |
%{l} | replace with local part of sender, for instance, if sender is info@example.com, the local part is info. |
%{o} | The sender-domain, for instance, if email address is info@example.com the sender-domain is example.com. |
%{p} | The validated domain name. The name obtained using the PTR RR of the sender-ip. Use of this macro will require an additional query unless a ptr sender mechanism is used. Note: Both the %p and the ptr sender mechanism are strongly discouraged by RFC 7208 which even goes so far as to suggest their immediate removal for performance reasons. ooh. |
%{r} | Only allowed in TXT records referenced by the exp field. The name of the host performing the SPF check. Normally the same as the receiving MTA. |
%{t} | Only allowed in TXT records referenced by the exp field. Current timestamp. |
%{s} | Replace with sender email address, for instance, info@example.com |
%{v} | Replaced with "in-addr" if sender-ip is an IPv4 address and "ip6" if an IPv6 address. Used to construct reverse map strings. |
The above macros may take one or more additional arguments as follows:
r - Indicates reverse the order of the field, for instance, %{or} would display example.com as com.example and %{ir} would display 192.168.0.2 as 2.0.168.192. The normal split uses "." (dot) as the separator but any other character may be used to define the split but a "." (dot) is always used when rejoining so, for instance, %{sr@} would display info@example.com as example.com.info.
digit - the presence of a digit (range 1 to 128) limits the number of right most elements displayed, for instance, %{d1} displays only com only from example.com but %{d5} would display five right hand elements up to the maximum available, in this case it will display example.com since that is all that is available.
Note: In the various example fragments shown below we use the terms 'domain SPF' and 'mail host SPF'. The domain SPF can be placed anywhere at the top, or apex, of the domain according to taste, say, immediately after the SOA RR or most typically after the MX RR ('cos it just makes sense). A mail host SPF is an optional and defensive strategy since some SPF library routines can use the full name of the sending MTA (from the HELO/EHLO) to look for the SPF TXT RR. This optional RR will normally be placed immediately after the A or AAAA RR which defines the mail server.
Example 1: Assumes a single mail server which both sends and receives mail for the domain.
; zone file fragment for example.com $ORIGIN example.com. .... IN MX 10 mail.example.com. ; SPF stuff ; domain SPF example.com. IN TXT "v=spf1 mx -all" # this could have been writen as either @ IN TXT "v=spf1 mx -all" IN TXT "v=spf1 mx -all" .... mail IN A 192.168.0.4 ; defensive mail host SPF mail IN TXT "v=spf1 a -all"
Notes:
The SPF record states that the A record of mail.example.com alone is permitted to send mail for the domain.
The domain SPF is returned from a sender-domain query constructed from the sender's email address. Thus, if the sender = info@example.com, then sender-domain = example.com. The SPF record only allows the MX host to send for the domain.
The mail host SPF is present in case the receiving MTA uses a reverse query to obtain the source-ip host name and then does a query for the SPF record of that host.
If the domain contains multiple MX servers the domain SPF would stay the same but each mail host should have a mail host SPF/TXT RR.
Example 2: Assumes the domain will send mail through an offsite mail server, for instance, an ISP:
; zone file fragment for example.com $ORIGIN example.com. .... IN MX 10 mail.offsite.com. ; SPF stuff ; domain SPF example.com. IN TXT "v=spf1 include:offsite.com -all" ; the above could also have been written as either @ IN TXT "v=spf1 include:offsite.com -all" IN TXT "v=spf1 include:offsite.com -all" ; WARNING: offsite.com MUST have a valid SPF definition ....
Notes:
This format should be used IF AND ONLY IF you know that offsite.com has a valid SPF configuration.
include recurses (restarts) verification using the SPF records for offsite.com. Mail configuration changes are localised at offsite.com which may simplify administration.
include could have been replaced with redirect.
In the case where offsite.com does NOT have an SPF TXT RR then an ip4 variant can be used as a weak alternative. Assume, in the example above that the SMTP server of offsite.com is smtp.offsite.com (pretty creative!) whose IPv4 address is 192.168.3.7 then we could use the following SPF TXT formats:
; SPF stuff ; domain SPF example.com. IN TXT "v=spf1 ip4:192.168.3.7 -all"
The above is a weak alternative because offsite.com may in turn relay or send mail from other host names or even use other host domain names. It should be used only in extreme cases or when the ISPs mail architecture is well known.
Example 3: Assumes we are the host for a number of virtual mail domains AND that we can send mail from any host in our subnet.
Zone file fragment for one of the virtual mail domains:
; zone file fragment for vhost1.com $ORIGIN vhost1.com. .... IN MX 10 mail.example.com. ; SPF stuff ; domain SPF vhost1.com. IN TXT "v=spf1 include:example.com -all" ; the above could also have been written as either @ IN TXT "v=spf1 include:example.com -all" IN TXT "v=spf1 include:example.com -all" ....
Notes:
The domain SPF is returned from a sender-domain query constructed from the sender's email address. Thus, if the sender = info@vhost1.com, then sender-domain = vhost1.com. The SPF TXT RR recurses to the domain example.com for verification. That is, the receiving MTA will read the SPF TXT RR from example.com to verify the mail.
Zone file for example.com
; zone file fragment for example.com .... IN MX 10 mail.example.com. ; SPF stuff ; domain SPF - any host from ; 192.168.0.1 to 192.168.0.30 (32 - bcast and mcast = 30) ; can send mail example.com. IN TXT "v=spf1 ip4:192.168.0/27 -all" ; the above could have been written as either @ IN TXT "v=spf1 ip4:192.168.0/27 -all" IN TXT "v=spf1 ip4:192.168.0/27 -all" .... ; defensive mail host SPF mail IN TXT "v=spf1 ip4:192.168.0/27 -all"
Notes:
This SPF record allows any host in the 32 address subnet which contains 192.168.0 to send mail for this and any host virtual domain, for instance, vhost1.com in the above example. NOTE: while /27 allows 32 IP addresses subnet rules remove 192.168.0.0 and 192.168.0.31 as the network and broadcast addresses respectively. [read more about IPv4 Classes]
The domain SPF is returned from a sender-domain query constructed from the sender's email address. Thus, if the sender = info@example.com sender-domain = example.com.
example.com. IN TXT "v=spf1 mx/27 -all"This record has the same effect as a:192.168.0/27 above but will cost a further DNS look up operation whereas the IP is already available.
The above scenario relies on the fact that customers will only send mail via the domain example.com, that is, they will NOT send via another ISP at home or when travelling. If you are not sure if this is the case you can terminate the sequence with ?all which says kinda pass (soft fail) and let the mail go through - perhaps using the DMARC RR to have such instances reported to you by the receiving MTA.
If the domain contains multiple MX servers the domain SPF would stay the same but each mail host should have a defensive SPF record.
Example 4: Assumes that the domain never sends mail from ANY location - ever. Typically you would do this to prevent bogus mail for everyone else - it is a supreme act of self-sacrifice!
; zone file fragment for example.com ; zone does NOT contain MX record(s) ... ; SPF stuff ; domain SPF example.com. IN TXT "v=spf1 -all" ; the above could have been written as either @ IN TXT "v=spf1 -all" IN TXT "v=spf1 -all" ....
Notes:
This SPF test will always fail since the only condition it tests is the all which results in a fail.
You will get a warm inner glow for the rest of your life if you implement this type of SPF TXT RR. We're talking a serious incentive here folks.
If your domain does not receive mail then, due to the somewhat strange procedures defined in RFC 5321 (section 5), simply not publishing an MX RR may still result in A/AAAA lookups thus generating unwanted and useless traffic. Instead a NULL MX RR should be published (see RFC 7505 with the following format:.
# zone file fragment for example.com # which will not accept any incoming email ... $ORIGIN example.com. ... # NULL MX RR # the dot (.) signifies a null name # and indicates definitively this domain cannot receive email # use of zero in pref field indicates the highest preference # This MUST be the only MX RR for this domain MX 0 . ...
Example 5: Illustrates various macro expansion features:
; zone file fragment for example.com $ORIGIN example.org. .... IN MX 10 mail.example.com. ; SPF records ; domain SPF @ IN TXT "v=spf1 exists:%{ir}.%{v}.arpa -all exp=badguy.example.com" ... badguy IN TXT "The email from %{s} using SMTP server at %{i} was rejected by %{c} (%{r}) at %{t} because it failed the SPF records check for the domain %{p}. Please visit http://abuse.example.com/badguys.html for more information" ....
Notes:
The badguy TXT above is split across multiple lines for presentation reasons only and should appear on a single line in the zone file.
The exists:%{ir}.%{v}.arpa test is a great example BUT IT WILL NOT WORK (sigh!) because the exists type checks for an A RR, whereas a reverse lookup is defined using a PTR RR. But it does show the power of macro-expansion and we could not think of a better example or use. However, Stuart Gatham could and suggested using the reversed IP address in a DNS Black List (DNSBL) as shown here:
@ IN TXT "v=spf1 exists:%{ir}.blacklist.example.com -all exp=badguy.example.com"
If using this method you may also want to change the text in the badguy.example.com record to reflect the new failure. Many thanks for the suggestion.
Problems, comments, suggestions, corrections (including broken links) or something to add? Please take the time from a busy life to 'mail us' (at top of screen), the webmaster (below) or info-support at zytrax. You will have a warm inner glow for the rest of the day.
Contents
tech info
guides home
dns articles
intro
contents
1 objectives
big picture
2 concepts
3 reverse map
4 dns types
quickstart
5 install bind
6 samples
reference
7 named.conf
8 zone records
operations
9 howtos
10 tools
11 trouble
programming
12 bind api's
security
13 dns security
bits & bytes
15 messages
resources
notes & tips
registration FAQ
dns resources
dns rfcs
change log
This work is licensed under a
Creative Commons License.
If you are happy it's OK - but your browser is giving a less than optimal experience on our site. You could, at no charge, upgrade to a W3C STANDARDS COMPLIANT browser such as Firefox
Search
Share
Page
Resources
Systems
FreeBSD
NetBSD
OpenBSD
DragonFlyBSD
Linux.org
Debian Linux
Software
LibreOffice
OpenOffice
Mozilla
GitHub
GNU-Free SW Foundation
get-dns
Organizations
Open Source Initiative
Creative Commons
Misc.
Ibiblio - Library
Open Book Project
Open Directory
Wikipedia
Site
Copyright © 1994 - 2024 ZyTrax, Inc. All rights reserved. Legal and Privacy |
site by zytrax hosted by javapipe.com |
web-master at zytrax Page modified: February 21 2024. |