From ArchWiki
Jump to: navigation, search

Sender Policy Framework (SPF) is a protocol to indentify qualified servers, which are allowed to send emails on behalf of a domain. It consists of two parts, a DNS TXT record explained in record and a validating mail filter explained in validator. SPF can lead to problems when forwarding mail. For a solution for this see the Sender Rewrite Scheme (SRS) section below.


An example record could look like this v=spf1 ip4: ip4: a -all and is entered as TXT record of the email sending domain.

The following mechanisms are supported:

Tag Name Explanation
ALL Matches always; used for a default result like -all for all IPs not matched by prior mechanisms.
A Matches domains A and AAAA record
IP4 Matches given IPv4 address or address range
IP6 Matches given IPv6 address or address range
MX Matches domains mx record
PTR Matches PTR record. This mechanism is deprecated and should no longer be used.
EXISTS Matches if domain exists, regardless of the address. This is rarely used. Along with the SPF macro language it offers more complex matches like DNSBL-queries.
INCLUDE Includes the SPF record of a given domain

where you can use the following quantifiers:

Qantifier Explanation
+ PASS result. This can be omitted; e.g., +mx is the same as mx.
? NEUTRAL result interpreted like NONE (no policy).
~ SOFTFAIL, a debugging aid between NEUTRAL and FAIL. Typically, messages that return a SOFTFAIL are accepted but tagged.
- FAIL, the mail should be rejected (see below).


This is shown for Postfix only.


There are several SPF validators available [1], perl-mail-spf and perl-mail-spf-query can be found in the official Repositories. Below python-postfix-policyd-spfAUR is combined with the postfix mailserver.


Edit /etc/python-policyd-spf/policyd-spf.conf to your needs. An extensively commented version can be found at /etc/python-policyd-spf/policyd-spf.conf.commented. Pay some extra attention to the HELO check policy, as standard settings strictly reject HELO failures.

Postfix integration

In the main.cf add a timeout for the policyd:

policy-spf_time_limit = 3600s

Then add a transport

policy-spf  unix  -       n       n       -       0       spawn
     user=nobody argv=/usr/bin/policyd-spf

Lastly you need to add the policyd to the smtpd_recipient_restrictions. To minimize load put it to the end of the restrictions:

     check_policy_service unix:private/policy-spf


You can test your Setup with the following:

defaultSeedOnly = 0

Sender Rewrite Scheme (SRS)

To prevent future SPF checks from failing when forwarding mails, SRS provides a scheme to rewrite the ENVELOPE-FROM field to your own domain, thus passing the SPF test at the recipient server. To prevent creating open relays and still catch and backwrite bounces, this often contains a hash of the original adress combined with a secret only known to the server, providing validability of bounce email. For postfix install postsrsdAUR and adjust the settings:


Enable and start the daemon, making sure it runs after reboot as well. Then configure postfix accordingly by tweaking the following lines:

sender_canonical_maps = tcp:localhost:10001
sender_canonical_classes = envelope_sender
recipient_canonical_maps = tcp:localhost:10002
recipient_canonical_classes= envelope_recipient,header_recipient

Restart postfix and start forwarding mail.


SPF can even be helpful for domains not supposed to send email. Publishing a policy like v=spfv -all prevents anyone from sending in this domains name thus preventing misuse.

Known problems

Some contact form providers send mails impersonating the sender using its email address in FROM-field. This is bad practice but still used, and leads to rejected emails with strict SPF policies (such als v=spf1 a -all).

See also