macdevcenter.com
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Sanitizing Mail on Panther Server

by Jason Deraleau
01/27/2004

With Mac OS X Server 10.3, Apple has replaced Apple Mail Server with the Postfix and Cyrus software packages. Postfix handles message delivery and routing via SMTP, while Cyrus is used to allow the server's mail users to access their mail via POP3 or IMAP. Due to the versatility of the Postfix mail package, it's possible to use common Unix and open source tools to perform various tasks with your mail. One of these tools, Procmail, allows mail messages to be processed based upon special "recipes."

There are Procmail recipes to perform a wide range of actions, but one of its most valued is the ability to pipe mail messages through external utilities. One such utility is the Anomy Sanitizer. This free Perl script is designed to scan email messages for dangerous file attachments, malicious JavaScript, or even pass attachments through an anti-virus program. By configuring Mac OS X Server's Postfix to use Procmail, it's possible to have your mail server pass messages through the sanitizing script.

Once I've walked you through configuring Postfix to use Procmail, I'll explain installing Anomy's Sanitizer and configuring it to use a common anti-virus package, Virex. Virex is an excellent virus scanner and works well for this situation because of its command-line interface features. Virex is also in common use, this having a lot to do with the fact that it is free to Apple's .Mac members.

Configuring Postfix

This article will assume that you have properly configured Postfix and are able to successfully send and receive mail through your Mac OS X Server. By default, Panther's Postfix does not pass data through Procmail. In order to enable this feature, we'll need to add it as a transport to Postfix. This involves editing two files: main.cf and master.cf. Both of these files are located in the /etc/postfix directory.

We'll add the transport to master.cf first. Start by opening up a new Terminal (/Applications/Utilities) session and issuing the command sudo cp /etc/postfix/master.cf /etc/postfix/master.cf.back. If prompted, enter your user account password. This command will create a backup copy of the file, in case you need to revert back at a later date. Now, enter the command sudo pico -w /etc/postfix/master.cf. You'll be presented with the pico editor and the contents of the master.cf file. Hold down Ctrl+V to scroll to the bottom of the file and paste the two lines below into the file. These lines are long, so be careful of line wrapping. Make sure you end up with just two lines in the Postfix configuration file.

Note: For readability, an extra line break was inserted into Line 2. Lines 2 and 3 should be entered on one line.

procmail  unix  -       n       n       -       -       pipe
  flags=R user=cyrus argv=/usr/bin/procmail -t -m USER=${user} 
  EXTENSION=${extension} /etc/procmailrc

Now that we've added the transport mechanism, we need to make the Postfix master daemon aware of the new Procmail connection and to use it for local deliveries. This involves editing the file /etc/postfix/main.cf. First, make a backup of the file with the command sudo cp /etc/postfix/main.cf /etc/postfix/main.cf.back . Next, open up the file in the pico editor with the command sudo pico -w /etc/postfix/main.cf. In the file, comment out the line that says mailbox_transport = cyrus by placing a # in front of it. Then, at the end of the file, add these two lines:

mailbox_command = /usr/bin/procmail -t -a "$EXTENSION" 
mailbox_transport = procmail

Configuring Procmail

Now that Postfix is configured to pass messages destined for local delivery through Procmail, you'll need to configure Procmail to then continue the mail chain and deliver the messages to the Cyrus mail system. To do this, we'll work with the file /etc/procmailrc. This is the system-wide configuration file for Procmail and will be used when Postfix passes the messages through Procmail. Open the file in the pico editor with the command sudo pico -w /etc/procmailrc. If there is anything in the file, remove it by holding down Ctrl+K. Then, paste the contents below into the file:


#
# /etc/procmailrc - System-wide procmail recipes
#

# Uncomment the line below to allow users to specify individual
# procmail recipes
#INCLUDERC=/Users/$USER/.procmailrc

# Default: Deliver mail that makes it to this point to the user's
# Cyrus INBOX
:0 w
    | /usr/bin/cyrus/bin/deliver -e -a $USER -m user/$USER
            

Once you've saved these changes, enter the command sudo postfix reload to restart the Postfix daemons. Congratulations! At this point, you have a functioning Postfix server with Procmail support. Now, let's bring in some helpful tools.

Setting Up the Sanitizer

With Procmail in the mix, messages bound for local delivery now come in through Postfix, pass through Procmail, and then finally get delivered in the Cyrus mail stores. We're now going to add a stage that will insert the Anomy Sanitizer in the Procmail stage. First, we'll need to download the latest version of the Sanitizer package. You can find the latest release in the Downloads section of the Anomy mail tools site. Download the most recent version to your Desktop and issue this command to extract it to an appropriate place on the system: sudo tar -zxvf ~/Desktop/anomy-sanitizer-1.66.tar.gz -C /opt/.

The Sanitizer is now installed, we just need to configure it for basic attachment screening. This configuration file is a simple set up for the Sanitizer. It has two policy groups. The first detaches inbound attachments that have an extension of any of the common Windows executable formats (e.g. EXE or COM). The detached files are stored according to the value of file_name_tpl, and a message is inserted in the email, which informs the recipient that the attachment was stripped. This policy helps prevent many Visual Basic scripts and executable viruses from coming in through the mail server. The second policy group passes many common binary data files (e.g. JPG or MPG) through unmodified. Finally, the default policy of defang will help make HTML-formatted emails and other attachments a bit safer.

To have the Sanitizer start up with this configuration, first create the directory /var/quarantine with the command sudo mkdir /var/quarantine. Now, enter the command sudo chmod 1777 /var/quarantine to make sure that stripped attachments can be saved to this location easily. Next, insert the contents of the configuration file into /opt/anomy/sanitizer.cfg by opening it up in the pico editor (sudo pico -w /opt/anomy/sanitizer.cfg) and then pasting. Next, we'll need to set up Procmail to call the Sanitizer as each message comes in. Open the /etc/procmailrc file like we did earlier and modify it so it looks as follows:


#
# /etc/procmailrc - System-wide procmail recipes
#

# Uncomment the line below to allow users to specify individual
# procmail recipes
#INCLUDERC=/Users/$USER/.procmailrc

# Run sanitizer on locally delivered messages
ANOMY=/opt/anomy/
:0 fw
    |/opt/anomy/bin/sanitizer.pl /opt/anomy/sanitizer.cfg
    
# Default: Deliver mail that makes it to this point to the user's
# Cyrus INBOX
:0 w
    | /usr/bin/cyrus/bin/deliver -e -a $USER -m user/$USER
            

Once you've saved the file, the changes take effect immediately, so be careful as you type or you run the risk of losing inbound mail. Try testing the system by sending one of your mail users a message with an empty attachment named test.vbs. If all went well, the recipient will get an email that explains what happened to the attachment, as well as an attached log of what the Sanitizer did. In addition, you'll find a renamed copy of the file on the server in the /var/quarantine directory.

Incorporating Virex

While the Sanitizer configuration will certainly help eliminate a lot of common nasties coming through via email, it is still based around blocking certain types of attachments, which may still allow trouble to come in. For example, the filter will allow Word documents in, which could have a virus in the form of a macro. To help eliminate these kinds of problems, the Sanitizer can pass attachments through a virus scanner.

I chose Virex for this solution not only because it was free with my .Mac account, but also because it has a decent command-line interface. The Sanitizer expects certain responses from the virus scanner to help it determine how to treat the attachment after it's been scanned. I wrote a small wrapper shell script for Virex, which you can find listed below. Once you've installed Virex (and updated your virus definitions!), continue with these instructions to incorporate it with your mail Sanitizer.


#!/bin/sh
#
# virex.sh - wrapper script for Virex 7.2
#

# *******************************************
#                Exit Status
# *******************************************
#  Status:      1       Uninfected file
#               2       Cleaned file
#               3       Infected file
#               4       Error encountered
# *******************************************
EXITSTATUS=0

if [ -d /usr/local/vscanx ]; then
    if [ -f "$1" ] && [ "$1" != $(basename $1) ]; then
        cd /usr/local/vscanx
        ./vscanx $1 2>&1 >/dev/null
        
        case "$?" in
            0)          # Found no viruses
                        EXITSTATUS=1
                        ;;
            19)         # Found a virus, but cleaned it
                        EXITSTATUS=2
                        ;;
            12 | 13)    # Found a virus and file remains infected
                        EXITSTATUS=3
                        ;;
            *)          # Some sort of error occurred
                        EXITSTATUS=4
                        ;;
        esac
    else
        # The argument specified (if any) could not be found or is not a
        # full path
        echo "The file $1 could not be found. Please specify its full path."
        EXITSTATUS=4
    fi
else
    # Virex is not installed
    echo "Virex was not found in /usr/local/vscanx."
    EXITSTATUS=4

fi

exit $EXITSTATUS
            

Paste the contents of this script into /opt/anomy/bin/virex.sh using pico. Then, make the script executable with the command sudo chmod 0755 /opt/anomy/bin/virex.sh. Now that we have the script in place, we'll need to modify our Sanitizer configuration to make use of it. Open /opt/anomy/sanitizer.cfg and modify it to match this configuration file.

The new configuration adds a policy group that passes many common document formats (e.g. DOC or XLS) through the virus scanner. If the file passes as uninfected, it is included in the message normally. If the file fails to pass the virus scan, it will be deleted and a notification will be included in the email message. If an error of some sort is encountered, the attachment will be saved, much like our first policy group.

To test your new virus scanner, create a new file named eicar.doc using Text Edit (/Applications) and paste the following into it:


X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
            

When you send one of your mail users this file, the attachment will be stripped by the Sanitizer and placed in the quarantine area. The Sanitizer will then use the virex.sh script to have Virex scan the attachment. Virex will detect that the file is infected, causing the wrapper script to return an exit code of 3. Our policy for this exit code will be to drop the attachment. The file is removed from the quarantine (and thus the system completely) and a message is inserted into the email informing the recipient of the attachment's status.

Final Thoughts

While the configuration we've just set up is great for processing email attachments, much more can be done with these tools than can easily be described in a single article. Anomy's Sanitizer is an excellent tool for working with email attachments. I strongly suggest perusing their documentation for information on customizing directives and performing other types of scans.

Much more can be done with Procmail as well, especially performing actions based on mail headers or body texts. For example, it's quite trivial to have Procmail drop all mail from a specific sender, a troublesome domain, or even based upon words in the subject. There are a lot of great sites for Procmail recipes. Take a look at Timo's Procmail Tips and Recipes to get a head start on using this powerful utility.

Jason Deraleau works as a systems administrator by day, IT consultant and technical writer by night, and is the coauthor of the upcoming Running Mac OS X Tiger.


Return to the Mac DevCenter.