(865) 584-3355

Apple Certified Macintosh Experts
Serving East Tennessee since 1994
 

Server Configuration

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 greylisting, blackholes, 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 June 2007 v1.12 

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.

How to Install Grey Listing

Greylisting is the process of temporarily rejecting e-mail from an unknown host/sender/recipient combination. Spammers will tend not to bother trying to resend the e-mail later while legitimate servers will.

Prerequisite: You must have the Developer Tools installed. It's located on the 10.4 install DVD or http://developer.apple.com/, register an account and download it.

  • Open Terminal.
  • To login as root, type:
    sudo -s  

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.

 

  • 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
  • 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

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

Backscatter email

Special Ham: bulk emailers mercenary site (sometimes down)

If this install fails under 10.49, consider this thread at Apple