There was some discussion a while back about making SA work with vpopmail. Most solutions I saw used .qmail-username or .qmail-default which wasn't the right method for us. Below is a quick write up on how to use SA+clamscan from a .qmail file in the users maildir. We also pull user preferences for SA from SQL, so the line we use to call SA might not be what you want. Delivery and hand off for scanning is handled by maildrop.
First and foremost, make certain that the user vpopmail has a valid shell... this is very important as vdeliermail will run anything in the .qmail as the user vpopmail, provided the application doesn't do a setuid/setgid, which maildrop does not do. (That alone cost me 3 hours to troubleshoot.) For each user you want to enable SA and virus scanning put the following in a .qmail file in the users directory: | /var/qmail/bin/preline /usr/local/bin/maildrop /usr/home/vpopmail/domains/.mailfilter Make sure that this file has been chmod'ed to 600 (u+rw) and is owned by vpopmail:vchkpw otherwise it will not be run. The .mailfilter listed above contains (some of this script has come from another list member, but I forgot his name, if you contact me I will give credit where credit is due), it must also be chmod'ed to 600 with owner vpopmail:vchkpw : import EXT import HOST VHOME=`/usr/home/vpopmail/bin/vuserinfo -d [EMAIL PROTECTED] # Check for Spam if it is smaller than 250KB if($SIZE < 262144) { xfilter "/usr/local/bin/spamc -d 192.168.1.2 -t 20 -f -u [EMAIL PROTECTED]" } if ((/^X-Spam-Flag:.*YES/)) { `/bin/test -d $VHOME/Maildir/.Spam` if( $RETURNCODE == 1 ) { `/var/qmail/bin/maildirmake $VHOME/Maildir/.Spam; /usr/sbin/chown -R vpopmail:vchkpw $VHOME/Maildir/.Spam` } to "$VHOME/Maildir/.Spam/" } # If it isn't Spam, then we scan for Virus if it is smaller than 2MB in size... anything larger... they are on their own if($SIZE < 2000000) { xfilter "/usr/home/vpopmail/domains/clamscan.sh" } if ((/^X-Virus-Status:.*INFECTED/)) { `/bin/test -d $VHOME/Maildir/.Virus` if ( $RETUNRCODE == 1 ) { `/var/qmail/bin/maildirmake $VHOME/Maildir/.Virus; /usr/sbin/chown -R vpopmail:vchkpw $VHOME/Maildir/.Virus` } to "$VHOME/Maildir/.Virus/" } #If it isn't Spam or Virus, then deliver normally to "$VHOME/Maildir/" The specific lines of interest are the xfilter lines. We use spamc/spamd to offload the very CPU intensive process of spam scanning to another machine on the private network. That is what the -d directive is for which tells SA which IP to connect to for spamd... The clamscan.sh file is a wrapper for the clamscan binary. We need to do this because of the incompatibility between how clamscan operates and how maildrop expects an xfilter program to operate. maildrop expects any message it sends out to an xfilter program to be returned to it via stdout. The problem is that the clamscan binary only returns the results of the scan, not the message, so we have to create a shell script to pass the altered message back to maildrop via stdout, also we use the shell script to alter the exit code of clamscan (0 if clean and 1 if infected) to be compatible with what maildrop expects. maildrop expects the application to return a exit code of 0, so we have to alter it. You will need bash in order to use this. #!/usr/local/bin/bash # Created by Tom Walsh # slim at ala.net MSG=$(/bin/cat /dev/stdin) # Is there a better way to do this? SCAN=$(echo "$MSG" | /usr/local/bin/clamscan - --stdout --disable-summary) EXIT="$?" VIRUS=$(echo "$SCAN" | awk '{print $2}') SUBJECT=$(echo "$MSG" | /usr/local/bin/reformail -x Subject:) if [ "$EXIT" == "1" ]; then SUBJECT="**VIRUS** [$VIRUS] $SUBJECT" MSG=$(echo "$MSG" | /usr/local/bin/reformail -a"X-Virus-Status: INFECTED" -i"Subject: $(echo "$SUBJECT")") else MSG=$(echo "$MSG" | /usr/local/bin/reformail -a"X-Virus-Status: CLEAN") fi echo "$MSG" exit 0 And just for completeness... I have included our spamd config line to let you know how to pull settings from SQL: /usr/local/bin/spamd -a -d -q -x -m 50 -u spamd -i 192.168.1.2 -A 192.168.1.100 -A 192.168.1.101 The -i directive tells spamd to listen on IP 192.168.1.2, by default it only listens on 127.0.0.1 The -A directives tell spamd which IPs to accept connections from. You also need to odify your local.cf file to include the settings for connecting to the SQL server.... All of that is covered in the README for SQL: http://www.spamassassin.org/dist/sql/README I hope that helps somebody... We are going to be ramping up the load on the SA box shortly to see how well it scales... We are considering doing load balancing via two SA boxes and a psuedo-random IP selector script that will feed a variable $IP to the .mailfilter script above... something like: IP=`/path/to/ipscript.sh` xfilter "/usr/local/bin/spamc -d $IP -t 20 -f -u [EMAIL PROTECTED]" If anybody has any comments or suggestions I would be willing to hear them... I am currently writing up a howto to post to the web soon, but it is rather FBSD specific I am afraid... As a side note with regard to spamd reading the settings from SQL... spamd makes a lookup on the [EMAIL PROTECTED], but also makes a lookup on GLOBAL and @GLOBAL, so you can have a global preference for anybody that doesn't have an entry in the SQL table... A very nice feature. HTH, Tom Walsh Network Administrator http://www.ala.net/