QMAILSCANNER

Qmail-Scanner (aka QMS), is an add-on that enables a Qmail email server to scan gatewayed email for certain characteristics (i.e. a content scanner). It is typically used for its anti-virus and anti-spam protection functions, in which case it is used in conjunction with external scanners. It also enables a site (at a server/site level) to create “Policy blocks”: i.e. react to email that contains specific strings in particular headers, or particular attachment filenames or types (e.g. *.VBS attachments).

A list of features and other information about it can be checked from the Qmail-Scanner homepage at: http://qmail-scanner.sourceforge.net/ .

The following are the requirements of Qmail-Scanner, as mentioned on the website.

  • Netqmail 1.05 (or qmail-1.03 with patches)

  • Create a separate account under which to run Qmail-Scanner: defaults to username and groupname “qscand”. For extra security, create it with a normal home directory (e.g. “/home/qscand”), but with a “fake” shell (e.g. “/bin/false”) - as it’s never logged into directly.

  • daemontools-0.76+

  • reformime from Maildrop 1.3.8+

  • Perl 5.005_03+

  • Perl module Time::HiRes

  • Perl module DB_File (most distributions come with it pre-installed, although the latest Perl doesn’t)

  • Perl module Sys::Syslog (most distributions come with it pre-installed)

  • Perl module MIME::Base64 (most distributions come with it pre-installed)

  • Optional: Mark Simpson’s TNEF unpacker. Can decode those annoying MS-TNEF MIME attachments that Microsoft mail servers just love to use. If you don’t have this, there are several classes of email that Qmail-Scanner basically won’t be able to extract attachments in. However, your AV might very well be able to handle them

  • Optional: uudecode (part of sharutils on Redhat-style systems)

  • Optional: unzip

QMR package provides qmail-scanner-1.25.tgz. Latest is 2.06 which is download-able from http://qmail-scanner.sourceforge.net/

TNEF

Mark Simpson’s TNEF unpacker. Can decode those annoying M$-TNEF MIME attachments that Microsoft mail servers just love to use. If you don’t have this, there are several classes of email that Qmail-Scanner basically won’t be able to extract attachments in. However, your AV might very well be able to handle them. Latest version of TNEF is 1.4.5. Available at http://sourceforge.net/projects/tnef/ .

Pre-requisites

yum -y install db4-devel
perl -MCPAN -e "install DB_File"

Install TNEF first

cd /downloads/
wget <http://internap.dl.sourceforge.net/sourceforge/tnef/tnef-1.4.5.tar.gz>
tar xzf tnef-1.4.5.tar.gz
cd /downloads/tnef-1.4.5
./configure && make && make install

Lets install latest version of QMS

cd /downloads/
wget <http://garr.dl.sourceforge.net/sourceforge/qmail-scanner/qmail-scanner-2.06.tgz>
tar xzf qmail-scanner-2.06.tgz
cd /downloads/qmail-scanner-2.06

Configuration

📝Note: You can use the ./configure command directly with all the options specified below. Creating the qms-config file is specific to QMR . For some strange reason, people have been following it blindly [including myself 🙁 ]

vi qms-config

#!/bin/sh

# Was the "install" option given?
if [ "$1" != "install" ]; then
INSTALL=
else
INSTALL="--install"
fi
# Qmail Scanner 2.06 configuration:
./configure --domain example.com
--admin postmaster
--local-domains "example.com"
--add-dscr-hdrs yes
--ignore-eol-check yes
--notify admin
--redundant yes
"$INSTALL"

Next, adjust permissions and run the script in test mode (i.e. without the –install option):

chmod 755 qms-config
./qms-config
...
...

Or, you can directly use the ./configure command as shown below (without the $INSTALL variable):

# ./configure –domain example.com –admin postmaster --local-domains “example.com” –add-dscr-hdrs yes --ignore-eol-check yes --notify admin --redundant yes

You will get the following output when you use either of the method. Note that without “–install” , the script just tests the existence of various files and functionality.

[root@www qmail-scanner-2.06]# ./qms-config
Building Qmail-Scanner 2.06...
. . .
. . .
It will then generate qmail-scanner-queue.pl - it is up to you to install it correctly.
Continue? ([Y]/N)
Y
Found tnef on your system! That means we'll be able to decode stupid M$ attachments :-)
The following binaries and scanners were found on your system:
mimeunpacker=/usr/bin/reformime
tnef=/usr/local/bin/tnef
Content/Virus Scanners installed on your System
max-scan-size=100000000
clamdscan=/usr/bin/clamdscan (which means clamscan won't be used as clamdscan is better) fast_spamassassin=/usr/bin/spamc
Qmail-Scanner details.
log-details=syslog
...
scanners="clamdscan","fast_spamassassin"
If that looks correct, I will now generate qmail-scanner-queue.pl for your system...
Continue? ([Y]/N)
Y
Testing suid nature of /usr/bin/perl...
Looks OK...
Finished. Please read README(.html) and then go over the script to check paths/etc, and then install as you see fit.
. . .
. . .
[root@www qmail-scanner-2.06]#

Installation

That was test mode. Now run it in install mode. Note that QMS will get installed in /var/spool/qscan, not in /var/spool/qmailscan.

[root@www qmail-scanner-2.06]# ./qms-config install
or
[root@www qmail-scanner-2.06]# ./configure --domain example.com --admin postmaster
--local-domains "example.com" --add-dscr-hdrs yes
--ignore-eol-check yes
--notify admin
--redundant yes
--install

Building Qmail-Scanner 2.06...
Continue? ([Y]/N)
Y
Found tnef on your system! That means we'll be able to decode stupid M$ attachments :-)
The following binaries and scanners were found on your system:
mimeunpacker=/usr/bin/reformime
tnef=/usr/local/bin/tnef
Content/Virus Scanners installed on your System
max-scan-size=100000000
clamdscan=/usr/bin/clamdscan (which means clamscan won't be used as clamdscan is better)
fast_spamassassin=/usr/bin/spamc
Qmail-Scanner details.
log-details=syslog
...
scanners="clamdscan","fast_spamassassin"
If that looks correct, I will now generate qmail-scanner-queue.pl
for your system...
Continue? ([Y]/N)
Y
Testing suid nature of /usr/bin/perl...
Looks OK...
Hit RETURN to create initial directory structure under /var/spool/qscan,
...
Finished installation of initial directory structure for Qmail-Scanner
under /var/spool/qscan and qmail-scanner-queue.pl under /var/qmail/bin.
...
[root@www qmail-scanner-2.06]#

Check the newly installed scanner location:

ls -l /var/qmail/bin/qmail-scanner-queue.pl
-rwsr-sr-x 1 qscand qscand 111710 May 9 17:36 /var/qmail/bin/qmail-scanner-queue.pl

Time to perform the test suggested by qmail-scanner :

Logon as user kamran and execute the following command:

# su - kamran
[kamran@www ~]$ /var/qmail/bin/qmail-scanner-queue.pl -g
perlscanner: generate new DB file from /var/spool/qscan/quarantine-events.txt
perlscanner: total of 12 entries.
[kamran@www ~]$

Successful! Time to exit from user kamran’s shell.

Now run the following as root.

setuidgid qscand /var/qmail/bin/qmail-scanner-queue.pl -z
setuidgid qscand /var/qmail/bin/qmail-scanner-queue.pl -g

Also add them to cron to run once a day.

crontab -e
. . .
0 1 * * * /usr/local/bin/setuidgid qscand /var/qmail/bin/qmail-scanner-queue.pl -z
0 1 * * * /usr/local/bin/setuidgid qscand /var/qmail/bin/qmail-scanner-queue.pl -g

Make sure the ownership of /var/spool/qscan is correct. The qmail-scanner install option creates the directories and binaries with correct ownership. However, if that changes, for some reason, adjust that using the following:

chown -R qscand:qscand /var/spool/qscan # if needed

📝Note: Newer version of qmail-scanner and spamassasssin and clam used together, needs more memory. You need to increase the softlimit in the qmail-smtpd/run file from 40MB to say, 80 MB:

vi /var/qmail/supervise/qmail-smtpd/run
QMAILQUEUE="/var/qmail/bin/qmail-scanner-queue.pl" ; export QMAILQUEUE
...
(change softlimit to **80000000**)
...
...

test_installation.sh script

Try to the test_installation.sh script in contrib directory. This will send four emails to «postmaster@example.com» . One would be normal mail. Once would be spam and two would be virus infected. You should get two mails in your mail box. One spam and one non-spam. The other two should get blocked by qmail-scanner , as they contain virus in them.

[root@www contrib]# /downloads/qmailnew/qmail-scanner-2.06/contrib/test_installation.sh -doit
Sending standard test message - no viruses...
done!
Sending eicar test virus - should be caught by perlscanner module...
done!
Sending eicar test virus with altered filename - should only be caught by commercial anti-virus modules (if you have any)...
Sending bad spam message for anti-spam testing - In case you are using SpamAssassin...
Done!

Finished test. Now go and check Email sent to «postmaster@example.com»

At this time, you should have 2 messages in the postmaster’s mail box, one clean message and the other marked as *****SPAM***** . You should also have output similar to following, in your /var/log/maillog.

# tail -f /var/log/maillog

May 9 17:53:34 www qmail-scanner[8149]: Clear:RC:1(127.0.0.1): 0.022018 313 postmaster@example.com postmaster@example.com Qmail-Scanner_test_(1/4):_inoffensive_message 20080509125334.8148.qmail@www.example.com orig-www.example.com12103376145628149:313 1210337614.8151-0.www.example.com:68

May 9 17:53:34 www spamd[31043]: spamd: connection from localhost.localdomain [127.0.0.1] at port 37141

20080509125334.8148.qmail@www.example.com for postmaster@example.com:711

May 9 17:53:34 www qmail-scanner[8162]: Perlscan:EICAR_Test_Virus:RC:1(127.0.0.1): 0.027297 961 postmaster@example.com postmaster@example.com Qmail-Scanner_viral_test_(2/4):_checking_perlscanner…

May 9 17:55:18 www spamd[31044]: spamd: result: Y 1008 - AWL,DK_POLICY_TESTING, EXCUSE_4,FORGED_YAHOO_RCVD,GTUBE,INVALID_MSGID, MSGID_SHORT,NORMAL_HTTP_TO_IP, RAZOR2_CF_RANGE_51_100, RAZOR2_CF_RANGE_E8_51_100, RAZOR2_CHECK,UNPARSEABLE_RELAY scantime=1.5,size=2384,user=postmaster@example.com,uid=711,required_score=5.0,rhost=localhost.localdomain,raddr=127.0.0.1,rport=43427,mid=<9PS291LhupY>,autolearn=no,shortcircuit=no

May 9 17:55:18 www spamd[31040]: prefork: child states: II

If this is the case, you have installed a correctly functional qmail-scanner. Good! Congratulations!

In case of problems check the following log files

/var/log/messages /var/log/maillog /var/spool/qscan/qmail-queue.log # This is qmail-scanner’s log file.

qmail-scanner and maildrop 2.1.0 problem

There is a known bug when working with qmail-scanner and maildrop 2.1.0. When you execute qms-config script, or the ./configure command, it gives you the following stupid error:

************************** You have a known bad version of maildrop (1.0). It is buggy and doesn’t work! Please upgrade to a later release: http://download.sourceforge.net/courier/

When I first saw this error, I quickly reverted to using an older version of maildrop on my server, though it didn’t make sense. However, later, when I investigated further, I found that a check condition inside the configure script of qmail-scanner is incorrectly recognizing maildrop 2.1.0 as maildrop 1.0. I removed the problematic section from the qmail-scanner’s configure script and ran it again against my latest maildrop 2.1.0 . All was well. Here is the detail:

The QS configure file (main culprit)

Looking inside the code of configure file provided with qmail-scanner-2.06 , I found the code:

qmail-scanner-2.06]# vi configure
...

# Check version of maildrop to ensure it's not the buggy version

DD="`$MAILDROP_BINARY -v 2>&1|grep '^maildrop'|grep '1.0'`"
if [ "$DD" != "" ]; then
cat<<EOF
**************************
You have a known bad version of maildrop (1.0). It is buggy and doesn't
work!
Please upgrade to a later release:
<http://download.sourceforge.net/courier/>
**************************
EOF
fi
...

The fix

The grep check is checking for existence of “1.0” in the text returned by the maildrop -v command. If it exists, it shows the error message and exits. Since co-incidently maildrop-2.1.0 also as “1.0” in it. This test fires up and the program exits. I have changed this code to the following so it works for every version of maildrop. And of-course in present time we have version higher than maildrop-1.3.8, which satisfies the requirements of qmail-scanner by default. Here is the updated code from qmail-scanner configure file, just for reference. This will be covered in more detail in Qmail-Scanner article:

if [ "$MIME_UNPACKER" = "reformime" ]; then
DD="`$MAILDROP_BINARY -v 2>&1 | grep '^maildrop'`"
if [ "$DD" != "" ]; then
echo "$DD found on this system."
else
echo "Maildrop was not found on this system. Please install and run Qmail-Scanner again."
exit
fi

The problem of spam-emails not getting marked as spam

When spamassassin is installed and tested, it correctly marks spam emails as “*****SPAM*****”, or whatever value / string you choose for rewrite_header subject in spamassassin’s local.cf file . However, when you install qmail-scanner (newer versions), you don’t see spam emails marked with your defined string. The problem is that in earlier versions of qmail-scanner, when it gets configured and installed, it uses “verbose_spamassassin” . Verbose spamassasin is just another name for normal spamassassin program. When email is checked with verbose_spamassassin, it takes email, checks it, if found as spam, rewrites the X-Spam headers and Subject header as defined in local.cf, and hands back the whole email back to qmail-scanner.

In newer versions of qmail-scanner, it tries to use the “spamc” program, available by default in spamassassin’s RPM, and checks the mail with it, and calls this “fast_spamassassin” . When this is used, by qmail-scanner, the email is handed over to spamassassin’s spamc program, which checks it, and if found as spam, simple tells qmail-scanner that it is spam, and that is it. Qmail scanner then hands over the mail to the underlying mail deliver agent to be delivered to mailbox. You see, even if the email is correctly identified as spam, it does not get “marked” or “tagged” as spam. There are two solutions to this. Both are done at qmail-scanner install time, passed as an argument to the ./configure script.

a) use –scanners=verbose_spamassassin , as additional argument, when running the qmail-scanner’s configure script.

b) use –scanners=fast_spamassassin=*****SPAM***** , as an additional argument, when running the qmail-scanner’s configure script.

This is explained here on apache /spamassassin website: http://wiki.apache.org/spamassassin/SubjectRewrite

SubjectRewrite in 3.0.x

The syntax for enabling Subject rewriting has changed in 3.0.x, it is now a more generic rewrite_header option.

This is documented in the UPGRADE file:

- The “rewrite_subject” an “subject_tag” configuration options were deprecated and are now removed. Instead, using “rewrite_header Subject [your desired setting]”. e.g.

  • rewrite_subject 1 subject_tag ****SPAM(_SCORE_)****

  • becomes

    • rewrite_header Subject ****SPAM(_SCORE_)****

⚠️Warning: if you are running SA through amavisd or qmail-scanner, those apps do their own message rewriting and SpamAssassin cannot perform these rewrites. And here on Qmail-Scanner FAQ page: http://qmail-scanner.sourceforge.net/FAQ.php

  • What’s this fast_spamassassin vs verbose_spamassassin?. Quick intro to SpamAssassin: The spamc clien makes a NETWORK connection to the spamd daemon. It has to send the message over that network link to t daemon, and wait for it’s reply. In fast mode, “spamc -c” is used: this means the daemon just tells t client the status of the message - it doesn’t transmit the message with all those added SpamAssassin heade back to the client. In verbose mode, the spamc client receives the entire message back again - with t added SpamAssassin headers. Sending and receiving a mail message from the daemon is twice as slow as ju sending it - hence “verbose” vs “fast”. I recommend “fast” - it will scale better.

  • I want “fast_spamassassin” for performance - but I want the Subject: header tagged as “SPAM” too! Boy - y don’t want much do you! :-) Anyway - you can. Simply change the “–scanner” option t “fast_spamassassin=STRING” and “STRING” (“SPAM:” is a good value) will be prepended to the Subject line every message marked as Spam. If you want all that cool extra detail from SA (e.g. the reasons for particular score), then there is no option but to use “verbose_spamassassin”