Creating an Outgoing Mail Relay with Postfix and SpamAssassin

We have been fighting a lot of spam recently on our web hosting service. We decided the best route to go was to set up a mail gateway on a separate server and run spam scans on all outgoing mail with SpamAssassin to discard junk. This helps prevent our servers from appearing on blacklists and helps keep customers happy. This tutorial walks through the process we used to set up our mail gateway. We are running CentOS 6.6 x64 with postfix and SpamAssassin. We always assume your server has been updated, selinux is off, and iptables is either off or has the appropriate rules set up.

Install SpamAssassin and Configure Postfix

Begin by installing SpamAssassin. By default, even in the minimal installs, postfix is already installed and ready to go.

yum install spamassassin

We will want to enable the AutoWhitelist plugin in SpamAssassin. The AutoWhitelist plugin monitors emails sent and helps prevent false positives. For example, it may adjust scores for those users who send a lot of “good” email.

vim /etc/mail/spamassassin/v310.pre

Find and Uncomment
loadplugin Mail::SpamAssassin::Plugin::AWL

Next, we need to make some configuration changes to Postfix. The configuration file is in /etc/postfix/

1) Set your server’s hostname. Find and uncomment settings below. Make sure to use your fully-qualified domain and that you have a reverse DNS entry set up for your IP address to match.
mydomain =
myorigin =

2) Ensure these settings are uncommented and set to “all”.
inet_interfaces = all
inet_protocols = all

3) Since we are operating a relay, not an actual mail server with mailboxes, we don’t want any mail stopping here. Find the values below, make sure they are uncommented, and leave them blank.
mydestination =
local_recipient_maps  =

4) Again, because this is just a relay… Add this to the end of the configuration file as a new line
local_transport = error:local mail delivery is disabled

5) To avoid spam, we need to secure the service. Right now, it will accept mail from anyone and relay it (open relay). We have iptables set up to only allow specific IPs. In addition, we recommend setting IP restrictions in postfix configuration as well. Find and uncomment one of the “mynetworks” lines. You can set a comma-separated list, or use CIDR notation, such as We always recommend adding localhost in addition to your list of IPs.
mynetworks = localhost,

6) Then, to enforce the restrictions, add this line to the very bottom of the file as a new line
smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination

7) Later on, we’ll be setting up some real email addresses to map to virtual host names. To prepare for this, add this line to the end of the file.
virtual_alias_maps = hash:/etc/postfix/virtual

8) Find and uncomment the header checks line. This will be used to handle spam.
header_checks = regexp:/etc/postfix/header_checks

9) Add to the end of the file…
transport_maps = hash:/etc/postfix/transport
show_user_unknown_table_name = no

Next, we need to make a small change to /etc/postfix/ to disable local delivery. Find and commend the line below.
#local     unix  –       n       n       –       –       local

In /etc/postfix/virtual, we want to define our real email addresses. We recommend setting up at least these three.

You’re ready to start your postfix server!

service postfix start
chkconfig postfix on


Configure SpamAssassin

Next, we need to tell postfix to scan emails with SpamAssassin. We will create a new user/group for the SpamAssassin service to run under.

groupadd spamd
useradd -g spamd -s /bin/false -d /usr/local/spamassassin spamd
chown spamd: /usr/local/spamassassin

Lastly, we need to tell SpamAssassin to run as the newly-created spamd user. Edit /etc/sysconfig/spamassassin and replace its contents with the following.

SPAMDOPTIONS="-d -c -m5 --username ${SUSER} -H ${SAHOME} -s ${SAHOME}/spamfilter.log"

Ready to start SpamAssassin!

service spamassassin start
chkconfig spamassassin on

Great! Now we have postfix and SpamAssassin running, but they still need to be interfaced with each other. To do this, edit the /etc/postfix/ file. Add the following lines to the existing list of rules.

smtp      inet  n       -       n       -       -       smtpd -o content_filter=spamassassin
spamassassin unix -     n       n       -       -       pipe user=spamd argv=/usr/bin/spamc -f -e  /usr/sbin/sendmail -oi -f ${sender} ${recipient}

When we receive a spam message, we want to discard it. Edit /etc/postfix/header_checks and add this to the bottom. This will tell postfix to discard any message where SpamAssassin indicated the message is spam.

/^X-Spam-Flag:.YES/ DISCARD This is spam

Restart postfix so the changes take affect.

service postfix restart


Installing STARTTLS SSL Support

Nobody wants plain-text unencrypted emails these days. To begin with the SSL setup, we’ll need to create a new directory to store our certificates and generate a new request. Make sure your key is at least 2048 bits. Anything 1024 and below is considered unsafe in 2015. As you’re entering the information in the key generation prompts, make sure your Common Name matches your host name exactly.

mkdir /etc/postfix/ssl
cd /etc/postfix/ssl
openssl req -nodes -newkey rsa:2048 -keyout -out

Once your certificate is signed, upload the new files to /etc/postfix/ssl and edit /etc/postfix/ and add the following lines to the bottom.

# SSL Configuration
smtpd_use_tls = yes
smtpd_tls_auth_only = yes
smtpd_tls_key_file = /etc/postfix/ssl/
smtpd_tls_cert_file = /etc/postfix/ssl/
smtpd_tls_CAfile = /etc/postfix/ssl/
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom

Restart postfix (again)…

service postfix restart


Install Razor2 with SpamAssassin

Razor is a plugin for SpamAssassin that helps catch a large portion of emails that might otherwise be missed. We always recommend installing this with all SpamAssassin installations.

To install Razor, you need the EPEL repositories. For CentOS 6 x64, use the command below

rpm -Uvh epel-release-6*.rpm

Install the software

yum install pyzor perl-Razor-Agent

Restart spamassassin again…

service spamassassin restart

You can test the Razor plugin by feeding it some sample spam data

spamassassin -t -D razor2 < /usr/share/doc/spamassassin-3.3.1/sample-spam.txt


Installing SOUGHT Ruleset

For additional protection, we also recommend installing the SOUGHT ruleset. For more information on this ruleset, please visit their official page. Installation is simple. We only need to import their key then do an sa-update to update the rules.

sa-update --import GPG.KEY
sa-update --gpgkey 6C6191E3 --channel --channel



Leave a Reply