The PostFix mail server, part of OSX Server, is a wonderfully flexible and configurable mail transfer agent. This tutorial fills in the gaps of many online tutorials and provides a recipe to harden OSX server from spam using a combination of blacklists, backscatter filtering, checking the sending mail server, recipient and email content. This supplements the anti-virus and spam checks already included in OSX Server to significantly reduce spam received and load on the mail server.
Revised April 2011 v1.12
THIS IS PRESENTED FOR ARCHIVAL PURPOSES ONLY : IT IS STRONGLY RECOMMENDED YOU USE A SPAM FILTERING SERVICE OR APPLIANCE INSTEAD OF ATTEMPTING TO MANAGE THIS ON OSX SERVER
See Mailcleaner as Spam Filtering Solution for OSX Server
Beware!
These instructions assume that you are knowledgeable of postfix, command line, and UNIX syntax. If you make a mistake you could lose email, disrupt mail services, or at worst completely hose your server. If you are not comfortable with this risk, do not do this! This tutotial is provided without warranty or claim of fitness. We will not fix your server for free. Proceed at your own risk!
Since this overrides much of the settings controlled by Server Admin, you need to be comfortable with configuring postifx from /etc/postfix/main.cf . If you don't know what this is, you are probably in trouble if you proceed.
RBLs
Here are some excellent realtime blackhole lists. If you do not intend to do greylisting or other hardening, add these using Server Admin.
- l1.spews.dnsbl.sorbs.net : blocks by IP address known spammers, level 1 is less aggressive and has less collateral rejections than level 2 SPEWS
- zen.spamhaus.org : Spamhaus block list of verified spam sources
- list.dsbl.org : Distributed Sender Blackhole List
- cbl.abuseat.org : Composite Blocking List
- bl.spamcop.net : SpamCop Blocking List
What Version of Postfix Are You Running
OSX Server ships with different version of Postfix (which are not automatically upgraded by Apple), and configuration directives vary, so it is important to know what version of Postfix your are using. Below is a list by version of OS X:
OS X Version | Postfix Version |
10.7 | (not yet released) |
10.6 | 2.55 |
10.5 | 2.43 |
10.4 | 2.15 |
Or you can query Postfix directly to find out its version:
- Open Terminal.
- Type:
postconf -d mail_version
and press return. Enter your password if prompted.
- This greylist solution uses Pearl, so we are using CPAN, a Pearl package manager, to add some capabilities to Pearl, type:
cpan
and type return. If this is the first time you've ever used cpan, it will ask if you're ready for manual configuration. Tell it yes. You can usually just accept the defaults for what it asks. When it asks me for "Policy on building prerequisites (follow, ask or ignore)?" I use follow to avoid being asked about prerequisites but its up to you.
- cpan> prompt, type:
install IO::Multiplex
and press return. Wait while it does its thing.
- Once you're back at the cpan> prompt, type:
exit
and press return.
- Go to http://isg.ee.ethz.ch/tools/postgrey/ and download the current version of Postgrey. Expand the archive.
- Return to Terminal and CD into your newly created Postgrey directory. Issue these commands, one line at a time. Hit return after each line.
niutil -create . /groups/postgrey
niutil -createprop . /groups/postgrey gid 25
niutil -create . /users/postgrey
niutil -createprop . /users/postgrey uid 25
niutil -createprop . /users/postgrey gid 25
niutil -createprop . /users/postgrey shell /bin/tcsh
niutil -createprop . /users/postgrey home /tmp
niutil -createprop . /users/postgrey passwd "*"
mkdir /var/spool/postfix/postgrey
cp postgrey /var/spool/postfix/postgrey
cp postgrey_whitelist_clients /etc/postfix/postgrey_whitelist_clients
cp postgrey_whitelist_recipients /etc/postfix/postgrey_whitelist_recipients
chown -R postgrey /var/spool/postfix/postgrey
chgrp -R postgrey /var/spool/postfix/postgrey
chmod -R 755 /var/spool/postfix/postgrey
/var/spool/postfix/postgrey/postgrey --inet=10023 -d --user=postgrey --group=postgrey
- Lingon from http://lingon.sourceforge.net/ and used it to to start Postgrey at system start time.
- Open Lingon,
- Click on Assistant,
- Label, enter Postgrey
- UNcheck: Launch only when I login
- CHECK: Must run as root, then Next
- Job, enter:
/var/spool/postfix/postgrey/postgrey --inet=10023 -d --user=postgrey --group=postgrey
- Create
- Quit (the system will go ahead and start postgrey on its own, no need to reboot)
Applying Grey Listing to Postfix and Other Hardening
The following configuration hardens postfix:
- utilizes greylisting
- sending mail server checks, optimized to reduce load on server
- recipient checks
- backscatter reduction
- extensive RBLs
- header and body checks
You need to be logged-in as root
About hash files
Hash files are compiled text files, ending in suffix .db, and are created using the command postmap on a plain text file. Whenever changes are made to the plain text file, you must run postmap on the file for any changes to be reflected.
helo_access.db
- create the following file in /etc/postfix by pasting the following block of code into Terminal:
echo "# helo_access
# --- SPAMCONFIG : Spam filtering recommended by HappyMac
# implementaton v 1.1 April 2007 C Gray www.HappyMac.info
# About this directive: http://www.postfix.org/uce.html#smtpd_helo_restrictions
# See for syntax: http://www.postfix.org/access.5.html
# restricts what hostnames clients may send with the HELO (EHLO) command
# (prob do not want to permit here, as it may allow masqueraders)
# any client claiming to be cenergy.com at this point is lying, as we allowed all local networks in main.cf
#example.com REJECT HELO: You are not a example.com mail server
#.example.com REJECT HELO: You are not a example.com mail server
# this also applies to our static WAN IP address
#100.100.100.100 REJECT HELO: You are claiming to be the public IP of our mail server
# any client claiming to be localhost is lying
localhost REJECT HELO: You are not localhost
127.0.0.1 REJECT HELO: You are not host loopback
" > /etc/postfix/helo_access - edit /etc/postfix/helo_access to apply to this mail server
- change on lines 11 and 12 the 4 instances example.com to the domain name of the mail server
- mind the preceeding '.' on L12
- remove the comments '#' so your changes take effect
- change the IP on L15 to match the static IPs of the mail server
- this line can be duplicated if server has multiple WAN IPs
- remove the comments '#' so your changes take effect
- change on lines 11 and 12 the 4 instances example.com to the domain name of the mail server
- save, then compile the changes
postmap /etc/postfix/helo_access
recipient_access.db
- create the following file in /etc/postfix by pasting the following block of code into Terminal:
echo "# recipient_access
# --- SPAMCONFIG : Spam filtering recommended by HappyMac
# implementaton v 1.1 April 2007 C Gray www.HappyMac.info
# About this directive: http://www.postfix.org/uce.html#smtpd_recipient_restrictions
# See for syntax: http://www.postfix.org/access.5.html
# Search this access database for the resolved destination address, recipient domain or parent domain, or localpart@.
# Specific local email addresses
#This email address is being protected from spambots. You need JavaScript enabled to view it. REJECT This is a forged account.
" > /etc/postfix/recipient_access - save, then compile the changes
postmap /etc/postfix/recipient_access
sender_access.db
- create the following file in /etc/postfix by pasting the following block of code into Terminal:
echo "# sender_access
# --- SPAMCONFIG : Spam filtering recommended by HappyMac
# implementaton v 1.1 April 2007 C Gray www.HappyMac.info
# About this directive: http://www.postfix.org/uce.html#smtpd_sender_restrictions
# See for syntax: http://www.postfix.org/access.5.html
#Search this access database for the sender mail address, sender domain and parent domain, or localpart@.
# We always want to accept from our backup MX server
#mailhop.org OK
# specific domains to always accept mail from
#bellsouth.net OK
efax.com OK
# servers not yet caught by RBL lists or known troublemakers
0733.com REJECT
" > /etc/postfix/sender_access - edit /etc/postfix/sender_access to apply to this mail server
- on line 10, make an entry for the backup MX server
- save, then compile the changes
postmap /etc/postfix/sender_access
header_checks.txt
- create the following file in /etc/postfix by pasting the following block of code into Terminal:
echo "#header_checks.txt
# --- SPAMCONFIG : Spam filtering recommended by HappyMac
# implementaton v 1.1 April 2007 C Gray www.HappyMac.info
# See for syntax: http://www.postfix.org/uce.html#header_checks
# Postmaster is OK, that way they can talk to us about how to fix their problem.
/^postmaster@.*$/ OK
# Back scatter prevention
# See: http://www.elantech.ru/docs/postfix-docs-ru/BACKSCATTER_README.html?prin...
# See also body_checks.txt
# Our mail server is not just the name of the TLD, but the name of an actual server
# so bounce all messages with forged return addresses
#/^Received: +from +(example\.com) +/ REJECT Forged client name in Received: header: $1
#/^Received: +from +[^ ]+ +\(([^ ]+ +[he]+lo=|[he]+lo +)(example\.com)\)/ REJECT forged client name in Received: header: $2
# (You can add multiple domains by using a pipe, ie: "(domain|domain|...)"
#
# Block all email from this address (useful for filtering backscatter
#/^(From|Return-Path):.*[[:<:]](user@domain\.tld)[[:>:]]/ REJECT Forged sender address in $1: header: $2
# reject foreign TLDs
# See: http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains
/^(From|Return-Path):.*[[:<:]](\.ar|\.br\.cn|\.in|\.jp|\.mx|\.pe|\.pl|\.ru|\.tr)[[:>:]]/
REJECT We do not accept email from TLD: $1
# Encoding
/^Subject: =?big5?/ REJECT Chinese encoding not allowed.
/^Subject: =?EUC-KR?/ REJECT Korean encoding not allowed.
/^Subject: .*\=\?ISO/ REJECT We don't accept strange character sets.
# Bad dates
/^Date: .* 18[0-9][0-9]/ REJECT Your email has a date from the past. Fix your system clock and try again.
/^Date: .* 19[0-9][0-9]/ REJECT Your email has a date from the past. Fix your system clock and try again.
/^Date: .* 200[0-6]/ REJECT Your email has a date from the past. Fix your system clock and try again.
# Disposition notification
#/^Disposition-Notification-To:/ REJECT Your email tries to trick mail clients into reporting if your mail was read or not. This is not legal and your mail is rejected according to EU and local law.
#/^Hel-Tracking: .*/ REJECT Your email tries to trick mail clients into reporting if your mail was read or not. This is not legal and your mail is rejected according to EU and local law.
#/^Kel-Tracking: .*/ REJECT Your email tries to trick mail clients into reporting if your mail was read or not. This is not legal and your mail is rejected according to EU and local law.
#/^Lid-Tracking: .*/ REJECT Your email tries to trick mail clients into reporting if your mail was read or not. This is not legal and your mail is rejected according to EU and local law.
#/^Bel-Tracking: .*/ REJECT Your email tries to trick mail clients into reporting if your mail was read or not. This is not legal and your mail is rejected according to EU and local law.
#/^BIC-Tracking: .*/ REJECT Your email tries to trick mail clients into reporting if your mail was read or not. This is not legal and your mail is rejected according to EU and local law.
# Address checks
/^From: <>/ REJECT You need to specify a return address, otherwise we will not accept your email.
# Attachments
/^Content-(Type|Disposition): .*name *=.*\.(scr|pif|exe|com|bat|shs|shb|vxd|rm|chm|vbs|ini|cmd|do|hta|reg|lnk|js|jse|pps)"?$/
REJECT Microsoft .${2} attachment rejected. Please remove it and resend.
# Subject line content
/^Subject: .* / REJECT Your subject had too many subsequent spaces. Please change the subject and try again.
/^Subject: ADV:/ REJECT Advertisements not accepted here.
# Bulk mail tools
/^content-type: .*qzsoft_directmail_seperator/ REJECT We do not accept email sent using this program.
/^X-Mailer: 0001/ REJECT We do not accept email sent using this program. 001
/^X-Mailer: Avalanche/ REJECT We do not accept email sent using this program. 002
/^X-Mailer: Crescent Internet Tool/ REJECT We do not accept email sent using this program. 003
/^X-Mailer: DiffondiCool/ REJECT We do not accept email sent using this program. 004
/^X-Mailer: Easy Mass Mailer/ REJECT We do not accept email sent using this program. 005
/^X-Mailer: .*eGroups Message Poster/ REJECT We do not accept email sent using this program. 006
/^X-Mailer: E-Mail Delivery Agent/ REJECT We do not accept email sent using this program. 007
/^X-Mailer: Emailer Platinum/ REJECT We do not accept email sent using this program. 008
/^X-Mailer: Entity/ REJECT We do not accept email sent using this program. 009
/^X-Mailer: Extractor/ REJECT We do not accept email sent using this program. 010
/^X-Mailer: Floodgate/ REJECT We do not accept email sent using this program. 011
/^X-Mailer: GOTO Software Sarbacane/ REJECT We do not accept email sent using this program. 012
/^X-Mailer: MailWorkz/ REJECT We do not accept email sent using this program. 013
/^X-Mailer: MassE-Mail/ REJECT We do not accept email sent using this program. 014
/^X-Mailer: MaxBulk.Mailer/ REJECT We do not accept email sent using this program. 015
/^X-Mailer: News Breaker Pro/ REJECT We do not accept email sent using this program. 016
/^X-Mailer: SmartMailer/ REJECT We do not accept email sent using this program. 017
/^X-Mailer: StormPort/ REJECT We do not accept email sent using this program. 018
/^X-Mailer: SuperMail-2/ REJECT We do not accept email sent using this program. 019
/^X-Mailer: SMTP COMPONENT/ REJECT We do not accept email sent using this program. 020
#/^X-Mailer: MIME::Lite/ REJECT We do not accept email sent using this program. 021
/^X-Mailer: The Bat/ REJECT We do not accept email sent using this program. 022
#/^X-Mailer: QUALCOMM Windows Eudora Version 6.0.0.22/ REJECT We do not accept email sent using this program. 023
# AV notifications
/^X-Mailer: ravmd\// DISCARD virus notification
/^Subject: *Your email contains VIRUSES/ DISCARD virus notification
/^Content-Disposition:.*VIRUS1_DETECTED_AND_REMOVED/ DISCARD virus notification
/^Content-Disposition:.*VirusWarning.txt/ DISCARD virus notification
" > /etc/postfix/header_checks.txt - edit /etc/postfix/header_checks.txt to apply to this mail server
- On lines 14 & 15, substitute example.com with the name of the domain AND uncomment the lines
- (You can add multiple domains by using a pipe, ie: "(domain\.com|domain\.net|...), which will be necessary if this is a backup MX for another server or you host multiple domains
body_checks.txt
- create the following file in /etc/postfix by pasting the following block of code into Terminal:
echo "# body_checks.txt
# --- SPAMCONFIG : Spam filtering recommended by HappyMac
# implementaton v 1.1 April 2007 C Gray www.HappyMac.info
# Back scatter prevention
# See: http://www.elantech.ru/docs/postfix-docs-ru/BACKSCATTER_README.html?prin...
# See also header_checks.txt
# Our mail server is not just the name of the TLD, but the name of an actual server
# so bounce all messages with forged return addresses
#/^[> ]*Received: +from +(example\.com) / REJECT Forged client name in Received: header: $1
#/^[> ]*Received: +from +[^ ]+ +\(([^ ]+ +[he]+lo=|[he]+lo +)(example\.com)\)/ REJECT Forged client name in Received: header: $2
# (You can add multiple domains by using a pipe, ie: "(domain\.com|domain\.net|...)
#
# Block all email from this address (useful for filtering backscatter
#/^[> ]*(From|Return-Path):.*[[:<:]](user@domain\.tld)[[:>:]]/ REJECT forged sender address in $1: header: $2
# This filter is adapted from the one used by http://linuxreviews.org/ for filtering mail.
# found at http://linuxreviews.org/zaboutus/nospam/body_checks.txt
# ------------------
# The tag below can cause some mail clients to open new windows or execute code.
/iframe src=cid/ REJECT Your email contained potentially dangerous code. Please resend your message in plain text.
# This will reject any line that uses more then seven "=20" to replace whitespace.
#/^.*=20[^>]*=20[^>]*=20[^>]*=20[^>]*=20[^>]*=20[^>]*=20[^>]*/ REJECT Your email program uses "=20" instead of spaces. Please correct this (try setting your mail program to use plain text) and resend your message.
# This will reject any line that uses more than three &# to hide links. There are two possible ways of doing this:
#/^.*\&\#[^>]\&\#[^>]\&\#[^>]/ REJECT Your email is not using a proper character set. Please correct this (try setting your mail program to use plain text) and resend your message.
/^.*\&\#[^>]{0,3}\;\&\#[^>]{0,3}\;\&\#[^>]{0,3}\;/ REJECT Your email is not using a proper character set. Please correct this (try setting your mail program to use plain text) and resend your message.
# Thanks to Liviu Daia and Noel Jones
# This will reject emails where any line contains eight or more script/comment tags.
/(]*>).*){6}/ REJECT Your email contained a lot of script tags. Please correct this (try setting your mail program to use plain text) and resend your message.
# Thanks to Brad Emerson and Victor Duchovni
# This will reject emails with script/comment tags that are in the middle of a word.
/^.*[a-z][a-z]/ REJECT Your email contained wrongly placed script tags. Please correct this (try setting your mail program to use plain text) and resend your message.
# Thanks to Jeroen Ouwehand
# This will reject more kinds of script/comment tags that are in the middle of a word.
/^.*[a-z][a-z]/ REJECT Your email contained wrongly placed script tags. Please correct this (try setting your mail program to use plain text) and resend your message.
# These are simple strings to identify sites and products marketed by spam
#/^.*www.bovanno.org/ REJECT spam id 2001 - know spam sender
" > /etc/postfix/body_checks.txt - edit /etc/postfix/body_checks.txt to apply to this mail server
- On lines 10 & 11, substitute example.com with the name of the domain AND uncomment the lines
- (You can add multiple domains by using a pipe, ie: "(domain\.com|domain\.net|...), which will be necessary if this is a backup MX for another server
Changes to main.cf
- Edit /etc/postfix/main.cf with your favorite editor. This assumes you have the default Apple Server file, so if you've tinkered check for dependencies.
- Paste this at the beginning of main.cf
# --- SPAMCONFIG : Spam filtering recommended by HappyMac
# implementaton v 1.1 April 2007 C Gray www.HappyMac.info
# see also: http://www.postfix.org/uce.html
# see also: http://www.freesoftwaremagazine.com/articles/focus_spam_postfix
smtpd_delay_reject = yes
# - SMTP Client Restrictions (are performed first)
# but we're performing RBL checks later in the process
#smtpd_client_restrictions=
# - HELO restrictions (are performed 2nd)
smtpd_helo_required = yes
smtpd_helo_restrictions = permit_mynetworks,check_helo_access hash:/etc/postfix/helo_access,
reject_non_fqdn_hostname,
reject_invalid_hostname,
reject_unauth_pipelining, permit
# - Sender restrictions (are performed 3rd)
smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks,
reject_non_fqdn_sender, reject_unknown_sender_domain, permit
# - Recipient restrictions and expensive tests (are performed 4th)
smtpd_recipient_restrictions = reject_unauth_pipelining, reject_non_fqdn_recipient, reject_unknown_recipient_domain,
permit_mynetworks, permit_sasl_authenticated,
reject_unauth_destination,
check_sender_access hash:/etc/postfix/sender_access,
check_recipient_access hash:/etc/postfix/recipient_access,
reject_rbl_client list.dsbl.org,
reject_rbl_client l1.spews.dnsbl.sorbs.net,
reject_rbl_client zen.spamhaus.org,
reject_rbl_client cbl.abuseat.org,
reject_rbl_client bl.spamcop.net,
check_policy_service inet:127.0.0.1:10023,
permit
# the following will be used with SPF (coming soon)
# check_policy_service unix:private/spfpolicy
# header and body checks
header_checks = regexp:/etc/postfix/header_checks.txt
body_checks = regexp:/etc/postfix/body_checks.txt
# --- END SPAMCONFIG
- Paste this at the beginning of main.cf
If you use Verizon email from a Treo, you may need to remove reject_non_fqdn_hostname from smtpd_helo_restrictions in order to send email from the phone without error.
Check the rest of the main.cf file for matching, conflicting directives. * Go to the bottom of main.cf in the last block, labelled # THE FOLLOWING DEFAULTS ARE SET BY APPLE
- Add a # at the begginning of line to comment-out and override the Apple settings:
- #smtpd_recipient_restrictions = ...
- #smtpd_client_restrictions = ...
- NOTE: you can no longer set RBLs using Apple's Server Admin tools. These changes must be made in main.cf
Checking and Restarting Postfix
To make sure that everything is syntacticly correct, type:
postcheck
and fix whatever it reports.
To restart postfix and start using all this, type:
postfix reload
References
How to get greylisting working (afp548.com) with the included Postfix SMTP server on OS X Server 10.4
About Postgrey - Postfix Greylisting Policy Server
Effective ways to reduce unwelcome mail
Postfix Configuration - UCE Controls
Apple: Fighting Spam on OSX Server
How To Fight Spam Using Your Postfix Configuration
Special Ham: bulk emailers mercenary site (sometimes down)
If this install fails under 10.49, consider this thread at Apple