How To Fight Spam Using Your Postfix Configuration
In this guide you will learn how to tweak the default Falko mail guide for Postfix (+Auth SMTP + Quota), https://www.howtoforge.com/virtual_postfix_mysql_quota_courier, setup to better combat SPAM and allow a little bit of backward compatibilty of the older Qmail systems.
So lets get started...
The HowtoForge guide is great for everything however if you have a very busy mail server running Spam Assasin on 1000s of message per minute is a CPU killer. The best answer is to stop the mail before it hits Spam Assasin with a range of RBL (Realtime Blacklists) and RHBL (Same but different), Greylistings and Helo Checks.
First of all we want to change the existing smtpd restrictions and add a whole host of new checks to help reduce the amount of mail the system accepts in /etc/postfix/main.cf
### Checks to remove badly formed email
smtpd_helo_required = yes
strict_rfc821_envelopes = yes
disable_vrfy_command = yes
unknown_address_reject_code = 554
unknown_hostname_reject_code = 554
unknown_client_reject_code = 554
smtpd_helo_restrictions = permit_mynetworks, reject_invalid_hostname, regexp:/etc/postfix/helo.regexp, permit
### When changing sender_checks, this file must be regenerated using postmap <file>, to generate a Berkeley DB
smtpd_recipient_restrictions =
check_client_access hash:/etc/postfix/helo_client_exceptions
check_sender_access hash:/etc/postfix/sender_checks,
reject_invalid_hostname,
### Can cause issues with Auth SMTP, so be weary!
reject_non_fqdn_hostname,
##################################
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unknown_sender_domain,
reject_unknown_recipient_domain,
permit_mynetworks,
reject_unauth_destination,
# Add RBL exceptions here, when changing rbl_client_exceptions, this
file must be regenerated using postmap <file>, to generate a
Berkeley DB
check_client_access hash:/etc/postfix/rbl_client_exceptions,
reject_rbl_client cbl.abuseat.org,
reject_rbl_client sbl-xbl.spamhaus.org,
reject_rbl_client bl.spamcop.net,
reject_rhsbl_sender dsn.rfc-ignorant.org,
check_policy_service inet:127.0.0.1:60000
permit
Now to explain but first we need to create a few files:
The first file we want to create is /etc/postfix/helo.regexp and this will contain:
/^subdomain\.host\.com$/ 550 Don't use my own hostname
/^xxx\.yyy\.zzz\.xxx$/ 550 Don't use my own IP address
/^\[xxx\.yyy\.zzz\.xxx\]$/ 550 Don't use my own IP address
/^[0-9.]+$/ 550 Your software is not RFC 2821 compliant
/^[0-9]+(\.[0-9]+){3}$/ 550 Your software is not RFC 2821 compliant
This alone will turn away spammers trying to send the helo command and impersonating either the server receiving the mail by IP or by hostname as well as turning away some of the mail that doesn't meet RFC 2821 compliance.
Next up, we need to create /etc/postfix/helo_client_exceptions:
#These client IP addresses are allowed to bypass fqdn checks
# Some Comment to identify IP address below
www.xxx.yyy.zzz OK
This file is needed incase a badly behaved mail server can't send the correct helo and you need to allow mail to be accepted from that source. In my experience, things like standalone devices, CCTV camera are poor at complying to standards so you might need to make an exception for this.
Before any changes in this file become usable you need to run
postmap /etc/postfix/helo_client_exceptions
This will create a file called /etc/postfix/helo_client_exceptions.db
Moving down, we have /etc/postfix/sender_checks which allows you to bypass the various FQDN checks and allow a particular sender through. This is particular useful if a company runs an internal mail network such as domain.com but email runs on int.domain.com and there is no DNS setup int.domain.com, this is great for security but not great becuase external DNS doesn't know about the internal structure and therefore postfix will reject the int.domain.com.
user@domain.com REJECT
user@int.domian.com OK
Once again this file once modified must have a Berkely DB file created and thus we create it using:
postmap /etc/postfix/sender_checks
Next we have our RBL checks. There are many websites dedicated to RBLs but to cut down the article length, simply put these lists are updated constantly and provide IPs and hostnames which spammers are using to relay mail. Each IP that tries to send mail to your mail server will be checked against these lists (4 used above) and if the IP isn't listed in the RBLs, the mail server will accept the mail. Ofcourse servers find themselves on these lists all the time inadvertingly or the lists take 24 hours to remove the blacklisted IP after a spam outbreak so it is always best to once again have a way of bypassing these checks.
To do so we create a file called /etc/postfix/rbl_client_exceptions:
## Some Random comment
www.xxx.yyy.zzz OK
Once again you must run postmap to generate the Berkeley DB file
postmap /etc/postfix/rbl_client_exceptions
The final line of the smtpd restrictions is the greylisting filter. I won't go into any detail on this as a guide already exists on howtoforge, https://www.howtoforge.com/greylisting_postfix_postgrey but if you do not wish to use Greylisting, simply omit the line
check_policy_service inet:127.0.0.1:60000
The smtpd restrictions is very easy to follow, until one of the checks gives the green flag for the message to pass into the Postfix queue, most answering not sure move on unless an explicit NO is given the message will move down the list of checks.
QMAIL LEGACY
DJB (Dan Bernstein) developed an alternative to SMTP called QMQP. It is said to be faster with less overheads. So if you are replacing your old Qmail MTAs with Postfix you may need to enable support for QMQP.
We do this adding the following into /etc/postfix/main.cf
qmqpd_authorized_clients = $mynetworks
qmqpd_error_delay = 5s
qmqpd_timeout = 300s
Realistically you can authenicate against anything but I decided to authenticate against mynetworks. After you have added the above into main.cf you need to further modify /etc/postfix/master.cf and make sure it contains the following:
628 inet n - - - 100 qmqpd
Now all you need to go is restart Postfix
/etc/init.d/postfix restart
You can check your new QMQP aware Postfix by typing:
telnet localhost 628
Authentication Via IP (Ideal for Smarthost relaying in MS Exchange Servers )
Next we are going to mod the guide a little to make the setting of mynetworks a little easier than through flatfiles namely /etc/postfix/main.cf
Create the following /etc/postfix/mysql-mynetworks.cf
user = mail_admin
password = password
dbname = mail
table = allowed_hosts
select_field = 'IP'
where_field = IP
hosts = 127.0.0.1
additional_conditions = and active='yes'
You will need the following SQL at this point
CREATE TABLE `allowed_hosts` (`active` enum('yes','no') NOT NULL default '1',
`IP` varchar(15) NOT NULL default '',
`Client` varchar(128) NOT NULL default '',
`Comments` text NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
mynetworks = 127.0.0.0/8, proxy:mysql:/etc/postfix/mysql-mynetworks.cf
Finally restart Postfix for changes to take effect:
chmod o= /etc/postfix/mysql-mynetworks.cf
chgrp postfix /etc/postfix/mysql-mynetworks.cf
/etc/init.d/postfix restart