Postfix with clamav-milter

From LQWiki
Jump to: navigation, search


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

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.

# 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/ \


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
      sleep 1
    if [ "$second" = "20" ]; then
      echo "WARNING: Gave up waiting for socket to appear!"
    chmod 777 $milter_socket 1> /dev/null 2> /dev/null
  /usr/local/sbin/postfix start

mailsystem_stop() {
  /usr/local/sbin/postfix stop
  killall clamav-milter

case "$1" in
  echo "usage: $0 start|stop"


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