A Sender Policy Framework (SPF
) record is an e-mail validation system designed to prevent spam by verifying IP
addresses. A DNS
system can be configured to add an SPF
TXT
record to the sender domain. In essence, the SPF
is a white-listing service that allows external mail-servers to query the DNS
system and check whether a certain IP
address is eligible for sending e-mail from a given domain.
This tutorial will show you how to add an entry to a domain file in order to allow other DNS
servers to check whether e-mails sent by you are not spam, as well as configuring postfix
to perform checks for incoming e-mails.
This is an easy job and consists in editing your zone file (do not forget to increment the serial) in order to include a TXT
record. For example, the following zone file for the domain named domain.com
:
$TTL 3D @ IN SOA ns0.domain.com. email.domain.com. ( 432561131 3H 15 4W 1D ) NS ns1 ; DNS name server 1 NS ns2 ; DNS name server 2 ; MX 10 mail ; Primary Mail Server ; MX 20 mail2 ; Secondary Mail Server domain.com. A 127.0.0.1 ns1 A 127.0.0.1 ns2 A 127.0.0.1 www CNAME domain.com. @ IN TXT "v=spf1 +mx +ip4:192.168.1.0/24 +ip4:46.228.47.114 +a:domain1.tld +a:domain2.tld +a:domain3.tld -all"
has the following line at the end, which is the SPF
TXT
record:
@ IN TXT "v=spf1 +mx +ip4:192.168.1.0/24 +ip4:46.228.47.114 +a:domain1.tld +a:domain2.tld +a:domain3.tld -all"
The options are:
v=spf1
- the SPF
protocol version. In this case we use SPFv1
.+mx
- if the domain name has an MX
record that resolves to the sender's address then it will match.ip4:192.168.1.0/24
and +ip4:46.228.47.114
- the IP
addresses that are permitted to send e-mails.+a:domain1.tld
, +a:domain2.tld
and +a:domain3.tld
- these are the domain names that are mapped to the IP
addresses allowed to send e-mails.-all
- hints to other mail servers to reject anything that does not match a whitelisted IP
or DNS
hostname specified previously with +
.This is all that is required to whitelist your servers.
Alternatively, domain name servers now support an SPF
record, instead of a TXT
record. So, instead of the configuration mentioned previously, we have the following record:
@ IN SPF "v=spf1 +mx +ip4:192.168.1.0/24 +ip4:46.228.47.114 +a:domain1.tld +a:domain2.tld +a:domain3.tld -all"
Another, more simple rule is:
@ IN SPF "v=spf1 a mx -all"
which matches if the domain name has an A
record corresponding to the sender address or if the domain name has an MX
record that resolves to the sender address - otherwise, it will reject any other IP
s. This relies on an MX
record being present for the zone.
After the record has replicated, send an e-mail to yourself on some other e-mail provider (for example, GMail
) and open the e-mail when you receive it and check the full headers. You should see something like:
Received-SPF: pass (google.com: domain of yourmail@domain.tld designates 46.228.47.114 as permitted sender) client-ip=91.70.104.88;
On Debian, you can choose between python
and perl
, so let us go with perl
and install the required packages:
aptitude install postfix-policyd-spf-perl
the next step is to edit /etc/postfix/master.cf
to include the lines:
policy unix - n n - - spawn user=nobody argv=/usr/bin/perl /usr/sbin/postfix-policyd-spf-perl
at the end of the file.
The next step is to add a restriction to the smtpd
restrictions by editing /etc/postfix/main.cf
and adding the line:
check_policy_service unix:private/policy
to the list smtpd_recipient_restrictions
. The result will look something like this:
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, check_policy_service unix:private/policy, reject_unauth_pipelining, # reject_invalid_hostname, # reject_unknown_recipient_domain, # reject_unauth_destination, reject_rbl_client sbl.spamhaus.org reject_rbl_client zen.spamhaus.org, reject_rhsbl_helo dbl.spamhaus.org, reject_rhsbl_sender dbl.spamhaus.org, permit
depending on your other rules.
After that, postfix
needs to be restarted with:
service postfix restart
Perform the same test again, by sending yourself an e-mail, this time, to your newly configured mail server and check /var/log/mail.log
when you receive your e-mail:
May 10 11:03:23 was postfix/policy-spf[14580]: Policy action=PREPEND Received-SPF: pass (gmail.com ... _spf.google.com: Sender is authorized to use 'john.doe+caf_=john=domain.com@gmail.com' in 'mfrom' identity (mechanism 'include:_netblocks.google.com' matched)) receiver=domain.com; identity=mailfrom; envelope-from="john.doe+caf_=john=domain.com@gmail.com"; helo=mail-wi0-f174.google.com; client-ip=209.85.212.174
A good way to test your domain for SPF
approval is to use the form on openspf.org and check whether certain IP
s are allowed to send e-mail through your mail server. A good syntax checker can be found on the openspf page.