Installing MIMEDefang and clamav antivirus sendmail virus scanners

Milter, sendmail's Mail Filter API, transfers mail messages back and forth to third-party programs as they are being processed in order to filter meta-information and content. This is useful in scanning for viruses and spam. Command-line antivirus programs like Clamav can also interact with sendmail using the procmail interface (see linuxsetup28.html).

NOTE: This page is not finished.

Step 1: Enable milter in sendmail

See also linuxsetup50.html for more details on installing sendmail. Backup sendmail and sendmail.cf before starting.
You must use Sendmail-8.12 or higher (www.sendmail.org).
  1. Download the sendmail source code and unpack it (e.g., in /home/myusername/sendmail).
  2. Edit the file
       /home/myusername/sendmail/sendmail-8.12.10/devtools/Site/site.config.m4
    and add the line
       APPENDDEF(`conf_sendmail_ENVDEF', `-DMILTER')
  3. Build sendmail
       cd ../..
       ./Build -c  
       cd  /home/myusername/sendmail/sendmail-8.12.10/obj.Linux.2.4.4.i686/sendmail
       strings sendmail | grep milter | wc 
    This strings command should print a number close to 93. If it prints a 1, milter is not compiled into sendmail.
  4. Build the libmilter libraries
       cd /home/myusername/sendmail/sendmail-8.12.10/libmilter
       ./Build -c
    This should create four libraries. Check to make sure they were created.
       cd ..
       find . | grep .a$
            ./obj.Linux.2.4.4.i686/libmilter/libmilter.a
            ./obj.Linux.2.4.4.i686/libsm/libsm.a
            ./obj.Linux.2.4.4.i686/libsmutil/libsmutil.a
            ./obj.Linux.2.4.4.i686/libsmdb/libsmdb.a
    While still in the libmilter directory, type
      su
     ./Build install
     cd ..
     ./Build install
     ldconfig
    Build needs to be run in both locations, because sendmail's main Build command doesn't compile or install libmilter.
  5. Edit sendmail's configuration file
       cd cf/cf
       cp generic-linux.mc sendmail.mc
       edit sendmail.mc 
    Add this to the end for clmilter:
       MAILER(procmail)dnl       
       INPUT_MAIL_FILTER(`clmilter',\
          `S=local:/var/run/clmilter.sock,\
           F=, T=S:4m;R:4m')dnl
       define(`confINPUT_MAIL_FILTERS',`clmilter') 
    or alternatively for mimedefang:
       INPUT_MAIL_FILTER(`mimedefang', \
       `S=unix:/var/spool/MIMEDefang/mimedefang.sock,\
        F=T, T=S:360s;R:360s;E:15m') 
    The first line adds ability to use procmail, the last two will add milter-handling functions to your sendmail.cf file.
  6. Install sendmail and the config files
       sh Build sendmail.cf
       cd ../..
       su
       cp /etc/mail/sendmail.cf /etc/mail/sendmail.cf.bak
       cp /etc/mail/submit.cf /etc/mail/submit.cf.bak
       sh Build install
  7. Install sendmail.cf as /etc/mail/sendmail.cf and submit.cf as /etc/mail/submit.cf by typing
       sh Build install-cf 
  8. Change the sendmail startup command to use client-queue mode:
       sendmail -Ac -q5m 

Step 2: Compile and install clamav

  1. Add clamav user and build clamav
       useradd clamav
       groupadd clamav
       tar -xzvf
       ./configure --enable-milter
       make
       make install
  2. Build clamav-milter if desired. (We will not use it in this example). Otherwise GOTO 3.

    Note: clamav-milter doesn't compile without correcting the errors in the source code. You have to partially compile sendmail to get the libmilter library.
       cd
       cd clamav/clamav-0.60/clamav-milter
       cp ../clamd/defaults.h .
       cp ../clamd/cfgfile.h .
       cp ../clamd/options.h .
       cp sendmail-8.12.10/include/libmilter/mfapi.h .
       cp sendmail-8.12.10/include/libmilter/mfdef.h .

  3. Edit clamav-milter.c and change the line
       #include <libmilter/mfapi.h>
    to
       #include "mfapi.h"
    Edit mfapi.h and change
       # include "libmilter/mfdef.h"
      to   
       # include "mfdef.h"
    Edit clamav-milter.c and change the line
       snprintf(cmd, sizeof(cmd), "clamdscan --version 2>&1");
    to
       snprintf(cmd, sizeof(cmd), "/usr/local/bin/clamdscan --version 2>&1");
  4. Copy all the libmilter libraries to the local directory and compile clamav-libmilter.
       cp ../libclamav/.libs/*.a .
       cp /home/myusername/sendmail/sendmail-8.12.10/obj.Linux.2.4.4.i686/*/*.a  .
       cc -o clamav-milter -O3 -DCONFDIR=\"/usr/local/etc\"\
        -pedantic -Wuninitialized -Wall -pipe -mcpu=pentium \
        -march=pentium -fomit-frame-pointer -ffast-math \
        -finline-functions -funroll-loops clamav-milter.c\
         -pthread libmilter.a ../libclamav/.libs/libclamav.a \
         ../clamd/cfgfile.o ../clamd/others.o
  5. Check to make sure an executable clamav-milter was created and install it manually.
       cp clamav-milter /usr/local/sbin/
       cd ..
       make install

Step 3: Configure clamav

  1. Edit /usr/local/etc/clamav.conf
    • Comment out the line that says "Example"
    • Uncomment the line that says "ScanMail"
    • Set LocalSocket to /var/run/clamd.sock
    • Uncomment ScanMail
    • Uncomment StreamaveToDisk
  2. Start tcpdump to monitor what traffic is being sent out.
  3. Run freshclam as root with no options to create database. This will download a new database from the clam AV homepage. Port 80 must be open on your firewall. freshclam should connect to port 80 at vhost.sourceforge.net and say:
        Checking for a new database - started at Tue Nov 11 12:04:10 2003
        Connected to clamav.elektrapro.com.
        Reading md5 sum (viruses.md5): OK
        Reading md5 sum (viruses2.md5): OK
        Downloading viruses.db ........... done
        Downloading viruses.db2 .......... done
        Database updated (containing in total 10131 signatures).
        Database updated from clamav.elektrapro.com.  
  4. Next, run the following commands:
       touch /var/log/clam-update.log
       chmod 600 /var/log/clam-update.log
       chown clamav /var/log/clam-update.log
  5. Add a line to root's or clamav's crontab such as:
       45 01 * * *       /usr/local/bin/freshclam --quiet -l /var/log/clam-update.log

Step 4: Test clamav

   clamscan -r -l scan.txt /home/windows_files/virus_infected_files

Step 5: Start clamav

   /usr/local/sbin/clamav-milter -blo /var/run/cmilter.sock
The system logs should say
   Nov 11 15:26:07 entropy clamav-milter[29977]: clamdscan / ClamAV version 0.60
Restart sendmail. If it says:
   (sendmail)WARNING: Xclmilter: local socket name /var/run/clmilter.sock missing
   sendmail: Milter (clmilter): local socket name /var/run/clmilter.sock unsafe
   sendmail: Milter (clmilter): to error state
This may mean you have a permission error somewhere. However, this error is not critical, since in this example we will use mimedefang instead of clamav-milter. The advantage of mimedefang is that, unlike clamav-milter, mimedefang also handles MIME-encoded viruses and spam. The disadvantage is that you need to know Perl to use it.

Step 6: Install Perl modules from http://www.mimedefang.org

  tar -xzvf Digest-SHA1-2.00.tar.gz
  cd Digest-SHA1-2.00 
  perl Makefile.PL
  make
  make install 
Repeat with

Note that MailTools-1.1401 has a coding error. Change the C<$?" in line 143 to C<$?>

Step 7: Install mimedefang from http://www.mimedefang.org

Make sure the sendmail source code is installed before compiling mimedefang.

  1. Copy sendmail's libmilter libraries to the mimedefang directory and compile mimedefang.
      cd mimedefang-2.48
      ln -s /home/myusername/sendmail/sendmail-8.12.8/include/libmilter libmilter
      cd libmilter
      ./Build
      cp /home/myusername/sendmail/sendmail-8.12.8/obj.Linux*/libmilter/*.a .
      cd -
      ./configure
      su
      useradd defang
      groupadd defang
      exit
      make
      su
      make install 
      mkdir /var/spool/MIMEDefang /var/spool/MD-Quarantine
      chmod 700 /var/spool/MIMEDefang 
      chmod 700 /var/spool/MD-Quarantine
      chown defang.defang /var/spool/MIMEDefang
      chown defang.defang /var/spool/MD-Quarantine   
  2. Configure mimedefang by editing /etc/mail/mimedefang-filter. See man mimedefang-filter. For example, you may wish to change lines containing
     return action_discard();  
    to
     return action_accept_with_warning();  
    until you're sure the filter actually works.
  3. Add the following to /etc/init.d/sendmail, right before the line that starts sendmail:
       rm -f /var/spool/MIMEDefang/mimedefang.sock
      /usr/local/bin/mimedefang -p /var/spool/MIMEDefang/mimedefang.sock & 


Back