SPF Postfix Setup

SPF Postfix Setup


Sender Policy Framework (SPF) is here to restrict who can send emails with your domain name, which mail servers are allowed to send your emails.Here we’re going to cover just a SPF Postfix Setup segment, including some DNS adjustments. If you need more details (Qualifier, Mechanisms, Modifiers, Vulnerabilities), check SPF Email Validation Protocol.

Outgoing email – SPF DNS Record

This step is relatively simple. Use the link above (SPF Email Validation Protocol) to gather some details on the flags you need to setup your own record.  Then go to your domain provider (usually panel/dashboard) and set a TXT record with those values. That records is the part of your domain’s DNS zone file, and it specifies a list of authorized hostnames/IPs that mail can originate from for a given domain name. So, all you have to do here is to edit your zone, for instance:

cyberpunk 300 TXT "v=spf1 mx -all"

All we say here is “the mail server for cyberpunk can send mail for cyberpunk”, excluding everyone else.

Incoming email – SPF Postfix Setup

We’re going to rely on

# apt-get install postfix-policyd-spf-python

Since I don’t have much phishing emails, I’ll set a loose config, not rejecting emails that fails SPF check. Alter the config file:

# nano /etc/postfix-policyd-spf-python/policyd-spf.conf
HELO_reject = False
Mail_From_reject = False

We’ll quickly go through some options here, for more details check python-policyd-spf man page. HELO check rejection policy options are:

  • SPF_Not_Pass – If result not Pass, None, or Temperror (Fail, Softfail, Neutral, PermError) => Reject
  • Softfail –  HELO Softfail or Fail => Reject
  • Fail – Reject only on HELO Fail
  • Null – Only reject HELO Fail for Null sender (SPF Classic). This is in connection with pre-RFC 4408 reference implementation. Use of at least this option (SPF_Not_Pass or Fail) are preferred) is highly recommended.
  • False – Never reject on HELO, append header only. This is useful for post-SMTP spam filters such as SpamAssassin.
  • No_Check – Never check HELO. This approach is useful to get both the HELO and Mail From headers prepended to a message.

Default: HELO_reject = SPF_Not_Pass

Mail From rejection policy options are:

  • SPF_Not_Pass – Reject if result not Pass/None/Tempfail.
  • Softfail – Reject on HELO Softfail or Fail.
  • Fail (default) – Reject on Mail From Fail
  • False – Never reject on Mail From, append header only. This is useful for post-SMTP spam filters such as SpamAssassin.
  • No_Check – Never check Mail From/Return Path

Default: Mail_From_reject = Fail

Many of the rules mentioned above are not fully RFC 4408 compliant, so pay attention if you go in deep. Next, inside postfix conf file /etc/postfix/main.cf , add:

policy-spf_time_limit = 3600s

This should prevent policy server from timing out during mail processing. Also, to smtpd_recipient_restrictions append:

check_policy_service unix:private/policy-spf
Note: Make sure it comes after reject_unauth_destination or your server might become open relay to anyone with correct SPF. You could also put policy service after you permit local senders. That way you’ll only check inbound mail, excluding outbound mails from your users.

Next, in master.cf:

# nano /etc/postfix/master.cf


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

All that is left is for you to restart the service:

# /etc/init.d/postfix restart

SPF Test

To test “Outgoing” email, send an email from your mail server towards some external mailbox, for instance Gmail (it supports all necessary mail checks: SPF, DKIM, DMARC). Go and check email source/header. In there, you should find “Received-SPF: pass”.  If there is a “fail”, recheck your config.

Note: DNS propagation takes time. If if SPF fails, wait and try again.

To test “Incoming” email, go ahead and send an email from external mailbox towards your server. Again, go ahead and check header segment. There should also be “Received-SPF” field. You can also examine the mail.log :

Sep  2 02:32:48 cyberpunk policyd-spf[5489]: None; identity=helo; client-ip=xxx.85.xxx.43; helo=mail-ua1-f43.google.com; envelope-from=user@gmail.com; receiver=info-test@cyberpunk.rs 
Sep  2 02:32:48 cyberpunk policyd-spf[5489]: Pass; identity=mailfrom; client-ip=xxx.85.xxx.43; helo=mail-ua1-f43.google.com; envelope-from=user@gmail.com; receiver=info-test@cyberpunk.rs

We clearly see that the email passed SPF check. There are many tools you can use to debug your setup (now SPF, later on DKIM, DMARC), for e.g. this tool.


Sender Policy Framework (SPF) is a method of fighting spam. Setting up an SPF records on your domain can prevent the emails you send to be flagged as spam, and can also deter spammers from spoofing your domain. So, at very least setup your “Outgoing” DNS/TXT SPF record. It’s not that difficult and it’s definitely beneficial to your domain/mail server. If you’re more dedicated, continue with SPF Postfix Setup (Incoming email). If you’re already here, your should check additional protocols/mechanisms for securing your email communication: