python-policyd-spf(1) pure-Python Postfix policy daemon for SPF checking




NOTE: Depending on the packaging and distribution, the exact path to the executable may vary.

$ policyd-spf (Start using installed config file)

$ policyd-spf -h (Display usage message)

$ policyd-spf /etc/postfix-policyd-spf-python/policyd-spf.conf
  (Config file name to use)

Configuration options are described in the sample configuration file installed in /usr/share/doc/postfix-policyd-spf-python (policyd-spf.conf.commented) and in policyd-spf.conf(5). The provided installs an uncommented configuration file in /etc/postfix-policyd-spf-python/.

Additionally, whitelisting certain IP addresses or IP addresses used by listed domains from SPF checks is supported. Skipping SPF checks for local submission or trusted relays is also provided. The sample configuration file and policyd-spf.conf(5) shows the format to use.


Logging is sent to syslogd.

Each time a Postfix SMTP server process is started it connects to the policy service socket and Postfix runs one instance of this Python script. By default, a Postfix SMTP server process terminates after 100 seconds of idle time, or after serving 100 clients. Thus, the cost of starting this Python script is smoothed over time

The default policy_time_limit is 1000 seconds. This may be too short for some SMTP transactions to complete. As recommended in SMTPD_POLICY_README, this should be extended to 3600 seconds. To do so, set "policy_time_limit = 3600" in /etc/postfix/

Messages that get a Fail SPF result will be rejected. Messages that get a Permerror are, by default, treated as if they had no SPF record. Messages that get a Temperror result are, by default, treated as if they had no SPF record, but can (and probably should) be deferred if otherwise permitted. Messages that get other SPF results (Pass, None, Neutral, Softfail) will have the SPF Received header prepended. Note: Spamasassisn 3.2 and follow will use this header for spam scoring so there is no need to configure a separate SPF check in these Spamassassin versions. See Spamassassin documentation for details.

Default Mail From rejection/deferal criteria are, by design, conservative. Default HELO check actions are to reject mail with other than Pass/None. HELO records are much simpler than Mail From records and rejecting based on HELO checking does not present a false positive risk. These settings are a matter of local policy and should be adjusted to meet the requirements of site administrators. See policyd-spf.conf(5) for configuration file details.


 1. Add the following to /etc/postfix/

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

    NOTE: Check the path to both the installed Python interpreter and
          policyd-spf.  These vary from system to system.  To use non-default
          settings, you must also add the config file (see above and 
policyd-spf.conf(5) for details).

 2. Configure the Postfix policy service in /etc/postfix/

        smtpd_recipient_restrictions =
            check_policy_service unix:private/policyd-spf
        policyd-spf_time_limit = 3600

    NOTE:  Specify check_policy_service AFTER reject_unauth_destination or
           else your system can become an open relay.

 3. Reload Postfix.