Title: ClamAV + QMVC + Qmail How-To Subject: Configure ClamAV Anti-Virus with Qmail and QMVC (Qmail Virus Control). By: John Streeton Stile Date: Sat Nov 6 10:29:27 PST 2004 Note: Thank you Erwin Hoffmann, Ph.D. for all your help and advice. --------------------------------------------------------- Table of contents: 1. What does ClamAV and QMVC do? 3. Directory Topology 3. Install ClamAV 0.80 4. Install QMVC 1.7.12 --------------------------------------------------------- 1. What does ClamAV and QMVC do? ClamAV does virus blocking Qmail is the MTA QMVC filters email, checking viruses/header/body/api/notification, uses CAR(O)" mechanism: 1st run message 'C'hecks, 2nd take 'A'ction, 3rd perform 'R'eactions, but some Checks can have extra 'O'ptions. --------------------------------------------------------- 2. Directory Topology: ClamAV Base Directory: /var/log/|-clamav/|-clamd.log - scann log | |-freshclam.log - defenition update log /usr/local/|-bin/clamav-config |-clamav/|-bin/clamdctl - start/stop clamd | |-supervise/clamd/|-run -damon script | |-log/run -damon log script | |-supervise/|-control | |-lock | |-ok | |-status |-include/clamav.h |-man/man8/clamav-milter.8 |-share/|-daily.cvd - Virus Defentions | |-main.cvd - Virus Defentions QMVC Base Directory: /var/qmvc/|-archive/ - old logs |-bin/ - all the programs |-control/|-filters - the main control file for QMVC's activity. (Read man qmvc-filters.) | |-scannners - defines which AV Scanners you are using. (Read man qmvc-scanners) | |-mailheader - additional checks on the email header and conformance. (Read qmvc-control) | |-noscantypes - MIME types to be excluded for AV scanning. | |-respmail - Include SMTP addresses for responsible persons. |-current/ |-doc/ - template control files and docs |-etc/ - ??? |-kept/ - viruses |-log/ - a fun and a wonderful toy |-mails/ - test email messages |-tmp/ |-tpl/ - headers for report emails # QMVC DEBUG NOTES/REQUIRED READING # Grab a big cup of coffee and read carefully. # Sample files for the /var/qmvc/control directory # man qmvc-filters, qmvc-log, qmvc-control --------------------------------------------------------- 3. Install ClamAV: # Add user and group groupadd clamav useradd -g clamav -s /bin/false -c "Clam AntiVirus" clamav # Unpack, build, install ClamAV cd ~/Qmail/ tar -zxvpf clamav-0.80.tar.gz cd clamav-0.80/ ./configure --sysconfdir=/etc make su -c "make install" # Make clamav/freshclam log directory. mkdir /var/log/clamav chown -R qscann.clamav /var/log/clamav # Edit the configuration file. vi /etc/clamd.conf ==> BEGIN /etc/clamd.conf <== LogFile /var/log/clamav/clamd.log LogFileMaxSize 10M LogTime LogSyslog PidFile /var/run/clamav/clamd.pid DatabaseDirectory /usr/local/share/clamav LocalSocket /tmp/clamd FixStaleSocket MaxThreads 30 MaxDirectoryRecursion 20 User qscand Foreground ScanMail ==> END /etc/clamd.conf <== # Set cron update: vi /etc/cron.daily/freshclam ==> BEGIN /etc/cron.daily/freshclam <== #!/bin/sh /usr/local/bin/freshclam --quiet ==> END /etc/cron.daily/freshclam <== # Make it executable chmod +x /etc/cron.daily/freshclam # Increase memory available to qmail-smtpd from 4000000 to 6000000 vi /service/qmail-smtpd/run ==> BEGIN /service/qmail-smtpd/run <== #!/bin/sh QMAILDUID=`id -u qmaild` NOFILESGID=`id -g qmaild` MAXSMTPD=`cat /var/qmail/control/concurrencyincoming` HOSTNAME=`cat /etc/HOSTNAME` RECORDIO='/usr/local/bin/recordio' exec /usr/local/bin/softlimit -m 6000000 \ /usr/local/bin/tcpserver -v -p -H -l0 -R \ -x /home/vpopmail/etc/tcp.smtp.cdb \ -c "$MAXSMTPD" -u "$QMAILDUID" -g "$NOFILESGID" \ 0 smtp \ "$RECORDIO" \ /usr/local/bin/rblsmtpd \ -ropm.blitzed.org \ -rrbl-plus.mail-abuse.org \ -rbl.spamcop.net \ -rrelays.ordb.org \ -rsbl.spamhaus.org \ -rKR.rbl.cluecentral.net \ -rBR.rbl.cluecentral.net \ -rblackholes.mail-abuse.org \ -rcbl.abuseat.org \ -rxbl.spamhaus.org \ -rlist.dsbl.org \ /var/qmail/bin/qmail-smtpd "$HOSTNAME" \ /home/vpopmail/bin/vchkpw /bin/true 2>&1 ==> END /service/qmail-smtpd/run <== # Create a startup/shutdown script for clamd. mkdir -p /usr/local/clamav/bin vi /usr/local/clamav/bin/clamdctl ==> BEGIN /usr/local/clamav/bin/clamdctl <== #!/bin/sh # For Red Hat chkconfig # chkconfig: - 80 30 # description: the ClamAV clamd daemon # By Jesse D. Guardiani PATH=/usr/local/bin:/usr/local/clamav/bin:/bin:/usr/bin:/usr/local/bin:/usr/local/sbin export PATH case "$1" in start) echo "Starting clamd" if svok /service/clamd ; then svc -u /service/clamd else echo clamd supervise not running fi if [ -d /var/lock/subsys ]; then touch /var/lock/subsys/clamd fi ;; stop) echo "Stopping clamd..." echo " clamd" svc -d /service/clamd if [ -f /var/lock/subsys/clamd ]; then rm /var/lock/subsys/clamd fi ;; stat) svstat /service/clamd svstat /service/clamd/log ;; restart) echo "Restarting clamd:" echo "* Stopping clamd." svc -d /service/clamd echo "* Sending clamd SIGTERM and restarting." svc -t /service/clamd echo "* Restarting clamd." svc -u /service/clamd ;; hup) echo "Sending HUP signal to clamd." svc -h /service/clamd ;; help) cat < END /usr/local/clamav/bin/clamdctl <== # Make clamdctl an executable and link to path: chmod 755 /usr/local/clamav/bin/clamdctl chown clamav /usr/local/clamav/bin/clamdctl ln -s /usr/local/clamav/bin/clamdctl /usr/local/bin # Create the supervise directories for the clamd service: mkdir -p /usr/local/clamav/supervise/clamd/log # Create supervise the run script vi /usr/local/clamav/supervise/clamd/run ==> BEGIN /usr/local/clamav/supervise/clamd/run <== #!/bin/sh # # -------------------------------------------------- # run # # Purpose - Start the clamd daemon/service. # # Author - Jesse D. Guardiani # Created - 09/10/03 # Modified - 09/25/03 # -------------------------------------------------- # This script is designed to be run under DJB's # daemontools package. # # ChangeLog # --------- # # 09/25/03 - JDG # -------------- # - Changed clamd user to qscand in compliance with # the change to qmail-scanner-1.20rc3 # # 09/10/03 - JDG # -------------- # - Created # -------------------------------------------------- # Copyright (C) 2003 WingNET Internet Services # Contact: Jesse D. Guardiani (jesse at wingnet dot net) # -------------------------------------------------- lockfile="/tmp/clamd" # Location of clamd lock file path_to_clamd="/usr/local/sbin/clamd" # Location of the clamd binary BAD_EXIT_CODE=1 # The exit code we use to announce that something bad has happened # The following pipeline is designed to return the pid of each # clamd process currently running. get_clam_pids_pipeline=`ps -ax | grep -E "${path_to_clamd}\$" | grep -v grep | awk '{print $1}'` # -------------------------------------------------- # Generic helper functions # -------------------------------------------------- # Basic return code error message function die_rcode() { EXIT_CODE=$1 ERROR_MSG=$2 if [ $EXIT_CODE -ne '0' ]; then echo "$ERROR_MSG" 1>&2 echo "Exiting!" 1>&2 exit "$BAD_EXIT_CODE" fi } # -------------------------------------------------- # Main # -------------------------------------------------- ps_clamd="" ps_clamd="$get_clam_pids_pipeline" if [ -n "$ps_clamd" ]; then pid_count="0" for pid in $ps_clamd do pid_count=`expr $pid_count + 1` done die_rcode $BAD_EXIT_CODE "Error: $pid_count clamd process(es) already running!" fi if [ -e "$lockfile" ]; then rm "$lockfile" exit_code="$?" die_rcode $exit_code "Error: 'rm $lockfile' call failed." fi exec /usr/local/bin/setuidgid qscand $path_to_clamd # -- # END /usr/local/clamav/supervise/clamd/run file. # -- ==> END /usr/local/clamav/supervise/clamd/run <== # Create supervise log scrpt vi /usr/local/clamav/supervise/clamd/log/run ==> BEGIN /usr/local/clamav/supervise/clamd/log/run <== #!/bin/sh exec /usr/local/bin/setuidgid qscand /usr/local/bin/multilog t /var/log/clamd ==> END /usr/local/clamav/supervise/clamd/log/run <== # Make executable chmod 755 /usr/local/clamav/supervise/clamd/run chmod 755 /usr/local/clamav/supervise/clamd/log/run # Set up the log directories and permissions: groupadd qscand useradd qscand -g qscand -c "qmail scanner" -s /nonexistent mkdir -p /var/log/clamd chown qscand /var/log/clamd # Link the supervise directory into /service: ln -s /usr/local/clamav/supervise/clamd /service ########## # I didn't do this next part # Install qmail scanner http://qmail-scanner.sourceforge.net/ # Mark Simpson's TNEF Unpacker # http://www.ietf.org/rfc/rfc1521.txt?number=1521 # wget http://xoomer.virgilio.it/j.toribio/qmail-scanner/download/q-s-1.24st-20041101.tgz ########## ------------------------------------------ 4. Install QMVC # Install maildrop wget http://www.fehcom.de/qmail/qmvc/maildrop-1.6.3.tar.bz2 tar -jxvpf maildrop-1.6.3.tar.bz2 cd maildrop-1.6.3/ ./configure make make install-strip make install-man whereis maildrop # Set Path to 'reformime' which is supplied by maildrop PATH=/usr/local/bin:$PATH # Install mess822 wget http://freshmeat.net/redir/mess822/6339/url_tgz/mess822-0.58.tar.gz tar -zxvpf mess822-0.58.tar.gz cd mess822-0.58/ make make setup check # Set Path to '822field', '822header','date', and 'http@' export PATH=${PATH}:/usr/local/bin # Install 'uuencode' and 'uudecode': rpm -i /usr/local/httpd/pub/suse8.0_dvd/suse/ap4/sharutils-4.2c-293.i386.rpm # Set Path to 'uudecode' export PATH=${PATH}:/usr/bin # Install 'qmvc-1.7.12' rm -rf /var/qmvc/tpl/* rm -rf /var/qmvc/control/* cd /home/my_user/Qmail/qmvc-1.7.12 ./install # Create filters file: vi /var/qmvc/control/filters ==> BEGIN /var/qmvc/control/filters <== errors=n;trash;;quitasap; # check header for errors subject=y;block; # check for a subject line bodytext=n # check text in the body? filename=n;block; # check file names MIME attachements. mimetype=n;block;notify=r # check Mimetypes in attachments loadertype=n;block;inform=postmaster # dentify executables per loader type string virus=y;block;notify=r,inform=postmaster@mydomain.com # invoke AV Scanner ==> END /var/qmvc/control/filters <== # Activate qmvc for the domain mydomain.com with .qmail-default ( Read man qmvc ) vi /home/vpopmail/domains/mydomain.com/.qmail-default ==> BEGIN /home/vpopmail/domains/mydomain.com/.qmail-default <== |/usr/local/bin/qmvc -v- | spamc | /home/vpopmail/bin/vdelivermail '' bounce-no-mailbox ==> END /home/vpopmail/domains/mydomain.com/.qmail-default <== # Test qmvc: cat /var/qmvc/mails/testmail.body.plain | qmvc #Make cron script: crontabe # 58 23 * * * /usr/local/bin/qmvclog2html -m -c -d fehcom /home/fehcom/qmvc # 58 23 * * * /usr/local/bin/virulator -m -s -c -d fehcom /home/fehcom/qmvc # 59 23 * * * /usr/local/bin/qmvcmonth -a -d fehcom /home/fehcom/qmvc -or- vi /var/qmvc/bin/qmvc_cron.sh ==> BEGIN /var/qmvc/bin/qmvc_cron.sh <== #!/bin/bash cd /var/qmvc/html/ /var/qmvc/bin/qmvclog2html -m -c /var/qmvc/bin/qmvcmonth -a #/var/qmvc/bin/webcalendar # need to install 'ncal' first /var/qmvc/bin/virulator -m -s -c ==> END /var/qmvc/bin/qmvc_cron.sh <== # qmvc_calendar requires ncal, which does not exist on Linux # Apache config: vi /etc/httpd/JohnsConfig_include.conf ==> BEGIN /etc/httpd/JohnsConfig_include.conf <== ################################################# # -BEGIN- Q-Mail Virus Control Alias # ################################################# Alias /qmvc/ "/var/qmvc/html/" Options Indexes AllowOverride AuthConfig Order allow,deny Allow from all ################################################# # -END- Q-Mail Virus Control Alias # ################################################# ==> END /etc/httpd/JohnsConfig_include.conf <== # Restart apache apachectl restart ------------------------------------------ ============================================================