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 IPs. 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 IPs are allowed to send e-mail through your mail server. A good syntax checker can be found on the openspf page.