Postfix with clamav-milter
Introduction
The release of Postfix 2.3 brought support for Sendmail milters. The following is an outline for running Postfix with clamav-milter, an anti-virus milter. For information about Postfix and milters, see the Postfix milter readme. Information regarding clamav-milter can be found in clamav-milter/INSTALL in the ClamAV source code directory.
Installation Notes
When compiling ClamAV from source, you should have the Sendmail libmilter library and header files installed. On Slackware, these are part of the sendmail package. On Red Hat systems, they are in the sendmail-devel rpm. An alternative to having libmilter installed on the system is to use a private copy of the library. See the Postfix milter readme for instructions. To build clamav-milter, you must use --enable-milter when you configure. At this point, it's assumed that you have both Postfix and ClamAV installed.
Configuration Notes
Postfix and clamav-milter run as unprivileged users which do not share a common group. Some contortions are necessary in order to allow them to interact.
We create a private directory to hold the milter socket and pid file:
# mkdir /var/run/clamav
# chown clamav:postfix /var/run/clamav
# chmod 750 /var/run/clamav
# mkdir /var/run/clamav/quarantine
# chown clamav:clamav /var/run/clamav/quarantine
# chmod 700 /var/run/clamav/quarantine
The Postfix user postfix needs access to the milter socket. The first step in making this possible is to have /var/run/clamav owned by the group postfix, the parent group of user postfix. Later, in the startup script, we'll adjust the permissions on the socket itself. The quarantine/ subdirectory will hold our infected mail.
On the Postfix side, we need an entry for clamav-milter in main.cf:
smtpd_milters = unix:/var/run/clamav/clamav-milter milter_default_action = accept
The second line tells postfix to bypass the milter in the event of a milter failure, instead of giving a temporary error code. It can be removed after everything works as expected.
Startup Script
Sample startup scripts for clamav-milter are provided in contrib/init/ of the ClamAV source code directory. The following is a minimal script which starts or stops postfix and clamav-milter.
#!/bin/sh
# Sample startup script for Postfix with ClamAV milter.
# Based on Slackware's startup scripts.
clamav_milter_flags="--sendmail-cf= --headers --force-scan \
--max-children=2 --timeout=0 --pidfile=/var/run/clamav/clamav-milter.pid \
--quarantine-dir=/var/run/clamav/quarantine"
milter_socket="/var/run/clamav/clamav-milter"
mailsystem_start() {
if [ -x /usr/local/sbin/clamav-milter ]; then
rm -f $milter_socket
echo "Starting clamav-milter: "
echo " /usr/local/sbin/clamav-milter $clamav_milter_flags $milter_socket"
/usr/local/sbin/clamav-milter $clamav_milter_flags $milter_socket
echo " waiting for ClamAv milter socket to be created..."
for second in 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 20 ; do
if [ -r $milter_socket ]; then
break;
fi
sleep 1
done
if [ "$second" = "20" ]; then
echo "WARNING: Gave up waiting for socket to appear!"
fi
chmod 777 $milter_socket 1> /dev/null 2> /dev/null
fi;
/usr/local/sbin/postfix start
}
mailsystem_stop() {
/usr/local/sbin/postfix stop
killall clamav-milter
}
case "$1" in
'start')
mailsystem_start
;;
'stop')
mailsystem_stop
;;
*)
echo "usage: $0 start|stop"
esac
Explanation
The script waits for the socket to be created, then uses chmod to relax the socket's permissions. This is the final step in making the socket accessible to the postfix user.
The --sendmail-cf= part of clamav_milter_flags leaves empty the path to sendmail.cf, the Sendmail configuration file, thus avoiding the attempt to parse that file during start-up.
Running clamd is not necessary, as clamav-milter is capable of scanning messages itself. You should update the virus database regularly using freshclam, either called from cron or running as a daemon.
External links
- Postfix homepage (www.postfix.org)
- ClamAV homepage (www.clamav.net)