This document describes how to lock down the Postfix mail server configuration, to include spam filtering. There are many methods available, ours uses only two. First we tweak Postfix to block crud and secondly filter through SpamAssassin.
How does it work?
Firstly Postfix will be "hardened" to prevent poorly written software from sending with it. Postfix will also be configured to filter connections, who says HELO, even recipient and sender domains by using RBL and RHSBL restrictions.
SpamAssassin is used to process messages that pass this first test and then delivers them to the maildir. SpamAssassin is not designed to listen directly to the "untrusted network", as in the internet, Postfix however is. Postfix will still be the first line of defense, SpamAssassin will receive messages from Postfix for further processing.
Postfix Spam Filter Configuration
Below is cut from our main.cf file, each configuration option is commented. Changes are made for more restrictions on all aspects of Postfix. They are listed in increasing order of complication, so start with the changes at the top and work your way down with only a few changes at a time. Test your configuration after each set of changes, at least a fire-test if not more. The amount of connections, use of strict RFC compliance, blacklists and other restrictions will serve to harden Postfix. The links at the end provide more information about blacklists, an important feature.
The first part is to change basic operations for a more strict environment. Do these first then test your environment.
# Fundamental checking allow_percent_hack = no allow_untrusted_routing = no disable_vrfy_command = yes parent_domain_matches_subdomains = strict_rfc821_envelopes = yes smtpd_delay_reject = yes smtpd_helo_required = yes
Connection Restrictions
Sometimes your machine is pretty open, like an inbound gateway or other utility mailhub. And, because it's open, there are some who will abuse that. You can use firewall rules to block IPs, that's quite easy but you can also block them in Postfix.
I like to use the smtpd_client_restrictions with a hash table of Bad IPs.
smtpd_client_restrictions = permit_mynetworks reject_unknown_client_hostname reject_unknown_reverse_client_hostname check_client_access hash:/etc/postfix/main.cf.d/check_client_access permit
Now the table file check_client_access
can be used to specify IPs, or hosts, or patterns to reject.
This annotated example shows some of each.
# By Hostname Patterns (depends on parent_domain_matches_subdomains .bad.tld REJECT # IP 8.8.8.8 REJECT # IPv4 CDIR 192.168.0.0/16 REJECT # IPv6 too 2600::2600 REJECT
Restricting at HELO
This blocks connects at the next stage, when they say HELO, which we require. Additional checks can be made here, everyone who's doing it right has proper hostname and reverse DNS configured for their hosts. We reject mis-configured or silly hostnames here.
smtpd_helo_restrictions = permit_mynetworks reject_invalid_helo_hostname reject_non_fqdn_helo_hostname reject_unknown_helo_hostname permit
Restricting at MAIL FROM
smtpd_sender_restrictions = permit_mynetworks permit_sasl_authenticated reject_non_fqdn_sender reject_unknown_sender_domain permit
Restricting at RCPT TO
smtpd_relay_restrictions = smtpd_recipient_restrictions = permit_mynetworks permit_sasl_authenticated reject_unlisted_recipient reject_unauth_destination reject_unauth_pipelining reject_non_fqdn_recipient reject_unknown_recipient_domain check_policy_service unix:/var/spool/postfix/private/postgrey permit
These changes restrict what hostnames we accept in the required HELO, test changes after this stage. Put the permit authenticated users, reject silly hosts, then allow. Note that some people will not be able to send with rules like reject_non_fqdn_hostname because they are using bad clients or mis-configured servers.
smtpd_helo_restrictions = permit_mynetworks permit_sasl_authenticated reject_non_fqdn_hostname reject_invalid_hostname reject_unknown_hostname permit
This prevents unauthorized mail, like relay, from happening but allows our trusted connections to relay.
smtpd_recipient_restrictions = permit_mynetworks permit_sasl_authenticated reject_non_fqdn_recipient reject_unauth_destination permit
This filter is applied on the senders domain name, trust who we trust first, filter bad stuffs, allow.
# harden who can send inbound or relay mail smtpd_sender_restrictions = permit_mynetworks permit_sasl_authenticated reject_non_fqdn_sender reject_unknown_sender_domain reject_unauth_pipelining reject_rhsbl_sender blackhole.securitysage.com reject_rhsbl_sender rhsbl.ahbl.org permit
If a log was kept of previous junk emails before the configuration then compare those with logs with this configuration in place. In our experience this catches a log of junk, both by restricting poorly written spam software and using the blacklists. Additional blacklists can be used, see the links at the bottom.
SpamAssassin Configuration
If the above configuration is not tight enough SpamAssassin can be used to further filter spam messages out. We however, currently have no more information, it will be here soon.
See Also
- Postfix Mail Server Setup - the email server configuration this is built on.
- SMTPD Access Readme
- Postfix Manual access(5).
- SpamAssassin - you know what this is.
- Blocking SPAM (UCE) using Postfix
- Security Sage: ANTI-SPAM GUIDE - RBL LISTS
- Daemon News : Postfix and SpamAssassin - has amavisd-new too.
- Open Directory - Computers: Internet: Abuse: Spam: Blacklists - Good list of RBL and RHSBL service providers.
Change Log
- 2013-12-13 - Added IP Blocking /djb
- 2005-02-04 - Created /djb