Home / guides   Print version

Sender Policy Framework (SPF)

This is a quick tutorial on how to setup and configure Sender Policy Framework (SPF) anti spam forgery system on Linux SMTP mail server.

Normal SMTP allows any computer to send an e-mail claiming to be from anyone. Thus, it’s easy for spammers to send e-mail from forged addresses.
This is why most internet providers don't allow you to send emails with another FROM-address and sometimes even block access to port 25, the default SMTP relay port.

But if you have your own server, you can setup your own SMTP service.
You will need to protected it (login authentication). If not it will be abused by spammers within hours. And your server might be blacklisted, so all the mails it sends will be considered spam, even your own.

We assume your mail server (postfixed) is already setup to receive mails for your (virtual)-domains.
You can check the page Mail server on Debian as guide to install it.
This part show how to setup your own SMTP server, so you can send emails from your (virtual) domains.

This is written for Debian Linux, but should work for most Linux versions:
The software versions:
Bind : bind 9.10.3
Postfix : 3.1.8
Dovecot : 2.2.27

Most of the configuration happens in Bind, the DNS service. It is DNS server who will "tell" other SMTP servers and spam-filters from who they should accept emails with this domains.

You need to adapt your domain.hosts file in /etc/bind,
and add the following line:

domain.com. IN TXT "v=spf1 a mx -all"

or

domain.com. IN TXT "v=spf1 a mx ~all"

  • v=spf1 : Define an SPF recorded.
  • a : defines that all A records in this domain are permitted to send emails for this domain.
  • mx : defines that all MX records in this domain are permitted to send emails for this domain.
  • ~all : SPF queries that do not match any other mechanism will return "softfail". Messages that are not sent from an approved server should still be accepted but may be subjected to greater scrutiny. If you need tight control replace ~all with -all (hard fail -> mail should be rejected).
Save the file and reload bind service:
/etc/init.d/bind9 reload

or simply restart the service:

/etc/init.d/bind9 restart

Multiple (virtual) domains

If you have multiple (virtual)-domains, you have to do it for each domain. But you probably only have 1 SMTP server for all this domains. So instead of modifying each domain everytime there is a change, you can tell it to check the info of the "main"-domain.

other-domain.com. IN TXT "v=spf1 include:main-domain.com ~all"

When you add this to all your domains and point them to your main domain, the rules from the main domain are also applied for the other domains.
And assuming your only SMTP server has a hostname in the main-domain, it works for all the domains.

PTR record

A PTR record, also known as pointer record or Reverse DNS Record is mostly administrative, it shows an IP is in fact used with a particular domain.
It is not required, but it helps to lower your spam-score.

It is simple to setup, add another line to you domain.hosts file in /etc/bind:

33.22.111.in-addr.arpa. IN PTR host.domain.com.

Where 44.33.22.111.in-addr.arpa. is the reversed ip-address of the host.
The real ip-address is something like 111.22.33.44

And if you have an IPv6 address, you can also add it:

b.b.b.0.0.0.e.f.f.f.d.c.b.a.9.8.0.0.0.0.0.0.0.0.0.7.6.5.4.3.2.1.ip6.arpa. IN PTR host.domain.com.

like IPv4 it is the IPv6 address in reverse (+.ip6.arpa.)

Setup SMTP-server

Your mail-server might already be setup to receive mails. To be able to send mail there are some additional steps to do.

You need to add some lines in /etc/postfix/master.cf


#this is for 'user' SMTP-server on 587
submission      inet    n       -       -       -       -       smtpd
 -o syslog_name=postfix/submission
 -o smtpd_tls_security_level=encrypt
 -o smtpd_sasl_auth_enable=yes
 -o smtpd_sasl_type=dovecot
 -o smtpd_sasl_path=private/auth
 -o smtpd_sasl_security_options=noanonymous
 -o smtpd_sasl_local_domain=$myhostname
 -o smtpd_client_restrictions=permit_sasl_authenticated,reject
 -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
And some lines in /etc/postfix/main.cf

# Authentication settings, making use of SASL
queue_directory=/var/spool/postfix
smtpd_sasl_type=dovecot
smtpd_sasl_path=private/auth
smtpd_sasl_auth_enable=yes
#broken_sasl_auth_clients=yes
smtpd_sasl_security_options=noanonymous
#smtpd_sasl_tls_security_options=$smtpd_sasl_security_options
#smtpd_sasl_local_domain=$myhostname
#smtpd_sasl_application_name=smtpd
smtpd_helo_required=yes
smtpd_helo_restrictions=reject_invalid_helo_hostname
smtpd_recipient_restrictions=reject_unknown_recipient_domain, reject_unauth_pipelining, permit_mynetworks, permit_sasl_authenticated, reject_unauth_destinat
What we have done here is setting up postfix to open the 'user'-SMTP on port 587 to be able to send mail. Port 25 is for receiving mail in this case. We also setup authentication, and use the same user/password from dovecot, which was already setup, see Mail server on Debian.

Don't forget to restart the postfix service:
/etc/init.d/postfix restart

Test

There are several ways you can test your setup. But the easiest one is from port25.com. You simply send an email from the domain you want to test to check-auth@verifier.port25.com and they do all the rest. After a couple of minutes you receive a full report.

A similar solution is available at http://www.brandonchecketts.com/emailtest.php where you receive a random email address to send an email to. After the email is received you can click "View Results" and it will give you a detailed report.

You can also use the command :
host -t txt domain.com

 

TOP