14 December 2016 Roberto Puzzanghera22 comments

Simscan is a simple program that enables the qmail smtpd service to reject viruses, spam, and block attachments during the SMTP conversation so the processing load on the email system is kept to a minimum.


ripMIME's primary purpose is to extract attachments out of a MIME encoded email packages. It is used by simscan. It is a recommended package.

cd /usr/local/src
tar xzf ripmime-
cd ripmime-
chown -R root.root .
make install

Installing simscan

For more informations about the patch applayed, see the J.Simpson site linked above. The applied patch includes a bug fix by Bob Greco (more info here).

cd /usr/local/src
wget -O simscan-1.4.0.tar.gz
tar xzf simscan-1.4.0.tar.gz
cd simscan-1.4.0
chown -R root.root .
patch < ../simscan-1.4.0.patch

./configure \
--enable-user=clamav \
--enable-clamav=y \
--enable-spam=y \
--enable-spam-passthru=y \
--enable-spam-hits=9.5 \
--enable-per-domain=y \
--enable-ripmime \
--enable-attach=y \
--enable-custom-smtp-reject=y \
--enable-spamc-user=y \

make install-strip

Take a look to the README file for an explanation of alla the configuration options.  Concerning spam, I want to reject via smtp the spam with a score greater than 9.5 and pass to the user the spam below this score.

--enable-per-domain=y|n Turn on per domain based checking.
--enable-spam=y|n Turn on spam scanning. default no.
--enable-spam-passthru=y|n Pass spam email thru or reject. Default: disable (reject)
--enable-spam-hits=number Reject spam above this hit level. Default 10.0
--enable-custom-smtp-reject=y Turns custom smtp reject messages on and off.  When enabled simscan will place the virus name in the reject message if a virus is detected. Requires the qmail-queue-custom-error.patch. Enabling dropmsg disables this option (more info here
--enable-spamc-user=y Mandatory option if you want to allow the spamassassin user preferences via SQL.
--enable-received=y Add a Received: line to the message, showing the runned scanners and some stats (you have to patch simscan)


As you know the qmail-queue-custom-error.patch (more info here) that we applyed before enables Simscan to return the appropriate message for each e-mail it refuses to deliver.

Please refer to this page ( to understand how the smtp rejection works with simscan. This guide shortly remainds that:

For virus rejection, the message contains the name of the virus such as :

Your email was rejected because it contains the Worm.Bagle.AU virus

For spam rejection, the message is more generic, merely stating that the message was rejected because it was considered spam :

Your email is considered spam (53.5 spam-hits)

For attachment rejection, the message contains the name of the attachment :

Your email was rejected because it contains a bad attachment: trojan.exe

How to setup simscan to manage the spamming as better as possible

Let's assume that spamassassin is configured with a spam level of 5.0, so that hits above this score are labeled as spam.

Of course, soon or later, spamassassin will label as junk an important email for a customer of yours, and we will never want to reject such a message. On the other hand there will be a score level, say 9.5, above which we can absolutely trust in spamassassin response and let simscan reject those emails without storing them in the user's mailbox.

Therefore we will configure simscan/spamassassin in order to:

  • Reject the emails with a score > 9.5
  • Pass through the emails with a 5.0
  • Consider all the other emails with a score

To accomplish this create a simcontrol like the following:

cat > /var/qmail/control/simcontrol << __EOF__

Remember to update simcontrol.cdb every time you modify simcontrol

# update simcontrol.cdb

Turning on scanning

echo ':allow,CHKUSER_WRONGRCPTLIMIT="3",QMAILQUEUE="/var/qmail/bin/simscan"' >> ~vpopmail/etc/tcp.smtp
qmailctl cdb

Now simscan/chkuser will close the smtp communication after 3 wrong recipient. You may want to add an instruction like CHKUSER_RCPTLIMIT="50" to limit to the number of recipient per SMTP connection. To be honest, these are settings  chkuser (not simscan).

Understanding the simcontrol file

You can setup rules for a specific user, a specific domain and a default rule as follows:

cat > /var/qmail/control/simcontrol << __EOF__,spam=no,,spam=yes,attach=.mp3
  1. The first line sets clam on and spam off for and checks for viruses inside attached file .txt and .com names.
  2. The second line sets clam off and spam on for the domain and disallows .mp3 files for the attachment scanner.
  3. The third line sets the default for the whole machine to enable clam, spam scanning, and sets the reject level for spam hits to 9.5.

Configuring simscan with the DKIM patch

If you want to enable DKIM you have to modify the simscan configuration accordingly as explained in the DKIM page.

Updating simscan

The patch applayed will add a line like this to the header:

Received: by simscan 1.4.0 ppid: 5613, pid: 5684, t: 0.7355s
          scanners: attach: 1.4.0 clamav: 0.98.4/m:55/d:19599 spam: 3.4.0

You have to update the simscan's database if you want to get the current versions of clamav and spamassassin:

# /var/qmail/bin/simscanmk -g
simscan versions cdb file built. /var/qmail/control/simversions.cdb

Since the update has to be done each time you refresh the virus database, you have to adjust you freshclam configutation as follows.

First of all let's download and install the program that will do the update:

wget --no-check-certificate
gcc -s -o /usr/local/sbin/update-simscan update-simscan.c
chown root:clamav /usr/local/sbin/update-simscan
chmod 4110 /usr/local/sbin/update-simscan

Now modify the freshclam configuration file in order to run the update-simscan executable each time the database is changed. You have to edit the file /usr/local/etc/freshclam.conf and modify it in this way:

OnUpdateExecute /usr/local/sbin/update-simscan

/var/qmail/simscan on a ramdisk

On his simscan's information page, John Simpson suggests to mount the work directory of simscan on a ramdisk, in order to speed up the process of file load from the disk.

It is sufficient to mount that directory in this way in your /etc/fstab:

none on /var/qmail/simscan type tmpfs (nodev,noexec,noatime,uid=1010,gid=1004,mode=2750)

Be aware that you have to adjust the uid and gid to the actual clamav user and group numbers respectively.


SPAM DROPPED (7.00/7.00):1.1858s:*****SPAM*****


I have a problem with simscan with rejecting SPAM with less than 9.5 hits:

SPAM DROPPED (7.00/7.00):1.1858s:*****SPAM*****

In /var/qmail/control/simcontrol I have:


In /etc/mail/spamassassin/ I put:

rewrite_header  subject *****SPAM*****

Do you know what could be wrong. 

Thank you a lot.


Reply | Permalink

did you update simcontrol.cdb

did you update simcontrol.cdb?


Reply | Permalink



 I forgot to do that. Problem is solved now.

Thank you,



Reply | Permalink

On simscan 1.4.1

Hi Roberto,

Yes you are right simscan 1.4.1 is essentially the same as 1.4.0 from functionality POfView

However it has some minor improvements:

  1. At line 781 in simscan.c uses  (char *)NULL whitch suppresses some comp warnings
  2. Same for line 1785 where val variable initialized (suppresses comp warns)
  3. Uses the modern autoconf approach to Makefiles

Additionally to further suppress all comp warnings one should:

  1. Edit cdb/conf-cc and append  -fno-builtin-malloc to gcc options
  2. Edit line 1735@simscan.c and replace globally: %d --> %zu

As far as the abnormal behaviour of simascan with spamc is concerned I think the relevant  simscan.c block of code is:

(in v1.4.1)



if ( MaxRcptTo==1 && i<MAX_SPAMC_ARGS-2 && strlen(spamuser) > 0){
    spamc_args[i++] = "-u";
    spamc_args[i++] = spamuser;
  /*  } else if ( MaxRcptTo==1 && i<MAX_SPAMC_ARGS-2 && strlen(spamuser) == 0) {  */
  } else if ( MaxRcptTo>0 && i<MAX_SPAMC_ARGS-2 && strlen(spamuser) == 0) {
    spamc_args[i++] = "-u";
    spamc_args[i++] = RcptTo[0];
  spamc_args[i] = NULL;

  if ( DebugFlag > 0 ) {
    fprintf(stderr, "simscan:[%d]: calling %s ", getppid(), SPAMC);
    while(spamc_args[i] != NULL){
      fprintf(stderr, " %s", spamc_args[i]);
    fprintf(stderr, "\n");
  if ( pipe(pim) == 0 ) {
    /* fork spamc */
    switch(pid = vfork()) {
      case -1:
      case 0:
        execve(SPAMC, spamc_args, 0);


MaxRcptTo always takes value 1 except when email has many recepients @ Cc or To Fields. In such a case MaxRcptTo counts the recepients

and has a positive value. So if we change the if condition

else if (MaxRcptTo==1 && i<MAX_SPAMC_ARGS-2 && strlen(spamuser) == 0


else if (MaxRcptTo>0 && i<MAX_SPAMC_ARGS-2 && strlen(spamuser) == 0

we get a more normal behavior.

I think it would be wise to ask the developers/mainteners of the current  simscan ver for a more formal and/or consistent amendment.



Reply | Permalink

Some thoughts...

Dear Rob

I think before anything else we should somehow unravel the logic of the
simscan developer (or at least give it a shot, since he/she is unreachable).
The presence of MaxRcptTo var in simscan.c indicates the fact that
at smtpd level one expects, in general, more than one recipients.
This fact has two realisations according to the way various MTAs connect to our smtpd.
Some MTAs open only one tcp conn per email msg (sendmail?), others open
one tcp conn per recipient (qmail).


So counting recipients in the 'forward smtp buffer' via MaxRcptTo shows us that
the developer is aware of all these.

So why then imposes a condition with MaxRcptTo == 1 as if he/she expects only one
connection per recipient?

One possible explanation is that he/she wants a somehow "pure" user pref policy ie
   one recipient      --   one local user (RcptTo[0]) --  reliable bayes entries in the SQL backend
   many recipients --                  ?                        --  no entries
                                                                              (Actually, we might get entries for clamd user!
                                                                               So eventually our SQL db gets polluted.
                                                                               Is this simply a real bug?)

So if someone (like me) is willing to impose more flexible policies on his users (eg global blacklists
per domain etc) he can patch the condition to  MaxRcptTo > 0.

I've tested the code and the MaxRcptTo > 0  seems a pretty harmless change that meets my needs without
spoiling the simscan functionality.


Reply | Permalink

It's a bug!

Dear Roberto

After all this is a bug!

It had been pointed out previously by Sossi Andrej (you might know him...)


So feel free to add it to some of your patches for our convenience...



Reply | Permalink

Patch updated, thank you 

Patch updated, thank you

Reply | Permalink

Your patch is working here.

Your patch is working here.

Unfortunately I coudn't find any contact of the author of the current 1.4.1 version

Reply | Permalink

did you test your patch

did you test your patch already?

Anyway, it's not clear to me why this happens only with gmail/hotmail...

Reply | Permalink

simscan 1.4.1

Roberto hi,

FYI there is a newer simscan 'bumdle' 1.4.1 @

However, I've noticed a strange simscan behavior (for both vers). When I send emails from @gmail/hotmail with multiple 'local' recepients [To, Cc] to my new qmail-simscan server the spamc scan is executed as null user!!! [SIMSCAN_DEBUG=4](The normal behaviour accordind to README is to extract the first local recepient.)

Any ideas?


Reply | Permalink

Hi Bob,

Hi Bob,

I have the same strange behaviour when receiving from gmail with CC. Test from other senders made simscan call spamc twice (one for the To address and another for the CC address). At the moment I have no idea... Let me know if youe manage to solve or find a patch.

According to the changelog, the new simscan seems not to add anything important, I'll wait for further development.

Reply | Permalink

Option necessary for centos distributions

Hi, for centos distribution in my case i have to put this option in the configure "--enable-spamc=/usr/bin/spamc".

I hope to be useful

Thanks a lot Roberto for this great manual. 

Reply | Permalink

changing of spam hit


I have been using --enable-spam-hits=9.5 and i would like to lower to 8.0. I had recompile simscan with --enable-spam-hits=8.0, make and make install-strip , still it did not change.

Did i missed out anything?






Reply | Permalink

I think modifing and

I think modifing and  recompiling simcontrol should work

Reply | Permalink

Thanks Roberto.

Thanks Roberto.

I missed out the simcontol.

Reply | Permalink

Simscan update (for gcc 4.1 and up)

It will not compile unless you add the following to the function in "simscanmk.c" where ever it is referenced:


In function ‘open’, inlined from ‘make_cdb’ at simscanmk.c:429:6: /usr/include/x86_64-linux-gnu/bits/fcntl2.h:50:4: error: call to ‘__open_missing_mode’ declared with attribute error: open with O_CREAT in second argument needs 3 arguments


so it looks like:

if ( (fdout = open(CdbTmpFile, O_CREAT | O_TRUNC | O_WRONLY, 0644)) < 0) {

so in this case on line 429, I added "0644" - add it where ever it there's a "open_missing_mode"

Hope it helps someone.

Reply | Permalink

Thanks for your contribution,

Thanks for your contribution, Wlad

Reply | Permalink

I wish there was an

I wish there was an alternative to simscan 1.4.0 - compiling it requires an older version of gcc - which in this case prevents this from building without proper arguments (for security purposes).

Reply | Permalink

which gcc version?

which gcc version? I can compile up to gcc-4.8.2 here

Reply | Permalink

bounce email

Rather then reply to an email stating why the message was blocked can it just be dropped with no reply as spammers will send a fake repy to address and someone will be inundated with these messages.

Reply | Permalink

there are several options

there are several options, depending on the delivery program you use. Look at this for details

I use CHKUSER_WRONGRCPTLIMIT in conjunction with a fail2ban rule

Reply | Permalink

blocking attachment

hello everyone , I have a question related to simscan, may I block all kind of attachment in the mail ? I need just this functionnality, is that possible ?

Reply | Permalink