I have been running ClamAV under daemontools on my server for several months now, with excellent results. This web page explains how I'm doing it.
The "clamd" and "freshclam" programs are designed to run in the background. For security reasons, we don't want these processes to run as root, so we will create a new userid called "clamav" under which these processes will run.
The procedure for doing this is usually specific to your OS and distribution, this example shows how to do it using CentOS Linux.
# useradd -M -d /nohome clamav
If you will be using clamav in conjunction with qmail-scanner, you may wish to make the clamav user a member of the qscand group. This is normally done using a command like this:
# usermod -a -G qscand clamav
If you will be using clamav in conjunction with simscan, you will need to make the clamav user a member of the simscan group. This is normally done using a command like this:
# usermod -a -G simscan clamav
The next step, obviously, is to install clamav. I do this using the instructions which are included in the source code package. The process looks like this:
$ tar xzf clamav-0.91.1.tar.gz
$ cd clamav-0.91.1
$ ./configure
Lots of messages, hopefully no error messages
$ make
Lots of messages, hopefully no error messages
If you are upgrading and already have these services running, you need to
shut them down before continuing.
$ sudo svc -d /service/clamd /service/freshclam
Password: You will not see the password as you type it
$ sudo make install
Lots of messages, hopefully no error messages
If you had shut these services down before, you should start them up again
immediately.
$ sudo svc -u /service/clamd /service/freshclam
The normal procedure to scan a file for viruses is to run the program "clamscan" with the filename(s) on the command line. The problem with this is that when clamscan starts, it has to read the virus definitions into memory, a process which can take several seconds on some machines, and which takes a non-zero amount of time for any machine. For a mail server which is scanning every incoming message, and which may be processing hundreds or thousands of messages per hour, this overhead can seriously slow the machine down.
The "clamd" process runs in the background. When it starts, it reads the virus database into memory one time, and then it listens for commands from clients. The "clamdscan" program is such a client- it passes the filenames from its command line to clamd and has clamd do the actual virus scanning, since it already has the virus definitions in memory. This can make a HUGE difference on a server, whether it's heavily loaded or not.
As a test, I just tried "clamscan" and "clamdscan" against the same file- clamscan took 1.582 seconds, while clamdscan only took 0.187 seconds.
The "clamd" program is configured using a clamd.conf file, which by default is installed in /usr/local/etc. The changes you need to make are as follows (lines in red show the original contents, and the lines in blue show what they need to be changed to.)
You must comment out this line or clamd will not run.
# Comment or remove the line below.
Example
#Example
Log file locking is not necessary under daemontools.
# By default the log file is locked for writing - the lock protects against
# running clamd multiple times (if want to run another clamd, please
# copy the configuration file, change the LogFile variable, and run
# the daemon with --config-file option).
# This option disables log file locking.
# Default: no
#LogFileUnlock yes
LogFileUnlock yes
The multilog program (part of daemontools) takes care of this
automatically.
# Maximum size of the log file.
# Value of 0 disables the limit.
# You may use 'M' or 'm' for megabytes (1M = 1m = 1048576 bytes)
# and 'K' or 'k' for kilobytes (1K = 1k = 1024 bytes). To specify the size
# in bytes just don't use modifiers.
# Default: 1M
#LogFileMaxSize 2M
LogFileMaxSize 0
Again, multilog takes care of this automatically.
# Log time with each message.
# Default: no
#LogTime yes
LogTime no
I like to see log messages whenever files are found to NOT contain
viruses, both because it shows me that clamd is working correctly,
and because it can provide a log of which files were scanned when. You may
not want or need these logs on your own server- if not, then don't make this
change.
# Also log clean files. Useful in debugging but drastically increases the
# log size.
# Default: no
#LogClean yes
LogClean yes
I like to see EVERYTHING that clamd is doing. You may not want
or need to see this much detail on your own server- if not, then don't make
this change.
# Enable verbose logging.
# Default: no
#LogVerbose yes
LogVerbose yes
I like to explicitly document where the virus definitions are stored,
just to prevent confusion later on. You may not want or need to do this on
your own server- if not, then don't make this change. This location,
/usr/local/share/clamav, is where the default installation
procedure puts the files. You will need to know this if you're going to
install simscan.
# Path to the database directory.
# Default: hardcoded (depends on installation options)
#DatabaseDirectory /var/lib/clamav
DatabaseDirectory /usr/local/share/clamav
This is a GOOD thing to do.
# Remove stale socket after unclean shutdown.
# Default: no
#FixStaleSocket yes
FixStaleSocket yes
This option tells clamd what userid it should run as.
# Run as another user (clamd must be started by root to make this option
# working).
# Default: don't drop privileges
#User clamav
User clamav
This allows clamd to access files using any "group" privileges
it may have. Without this, clamd will not try to use any "group"
privileges, and will only access files which are readable by the entire
world.
# Initialize supplementary group access (clamd must be started by root).
# Default: no
#AllowSupplementaryGroups no
AllowSupplementaryGroups yes
THIS IS ABSOLUTELY REQUIRED in order for clamd to run under
daemontools!!!
# Don't fork into background.
# Default: no
#Foreground yes
Foreground yes
The freshclam program checks for updated virus definition files and, if it finds them, downloads and installs them automatically. It then sends a message to clamd, telling it to read the new definitions into memory, and can also call another program that we specify. We will be using this "call another program" capability to inform qmail-scanner and/or simscan to update its version database, so the headers that they add to email messages will have accurate version numbers.
To configure freshclam, we will edit a file called freshclam.conf, which will be found in the same directory where we found the clamd.conf file (above.) This is a list of the changes we need to make:
You must comment out this line or freshclam will not run.
# Comment or remove the line below.
Example
#Example
This must match the DatabaseDirectory line in the
clamd.conf file.
# Path to the database directory.
# WARNING: It must match clamd.conf's directive!
# Default: hardcoded (depends on installation options)
DatabaseDirectory /var/lib/clamav
DatabaseDirectory /usr/local/share/clamav
This tells freshclam what userid it should run as. I normally
un-comment this line, just to make it obvious that it runs as the clamav
user.
# By default when started freshclam drops privileges and switches to the
# "clamav" user. This directive allows you to change the database owner.
# Default: clamav (may depend on installation options)
#DatabaseOwner clamav
DatabaseOwner clamav
This tells freshclam to send the notification to clamd
whenever new virus definitions are downloaded. THIS IS REQUIRED for
clamd to start using the new virus definitions as soon as they are
available, otherwise clamd will only check the files once every 30
minutes to see if they have been updated. This directive actually points to
the clamd.conf file which configured the running clamd
process- freshclam reads the "LocalSocket" (or
"TCPSocket") line in this file in order to contact the
clamd process.
# Send the RELOAD command to clamd.
# Default: no
#NotifyClamd /path/to/clamd.conf
NotifyClamd /usr/local/etc/clamd.conf
This tells freshclam to run an external program whenever new
virus definitions are downloaded. We will be using this to update the
qmail-scanner and simscan version databases.
# Run command after successful database update.
# Default: disabled
#OnUpdateExecute command
OnUpdateExecute /usr/local/sbin/freshclam-good
This tells freshclam to run an external program whenever it
tries to download new virus definitions and encounters an error. I use this
to email myself a notification, so that I can check on things and make sure
any problems are taken care of.
# Run command when database update process fails.
# Default: disabled
#OnErrorExecute command
OnErrorExecute /usr/local/sbin/freshclam-bad
THIS IS ABSOLUTELY REQUIRED in order for freshclam to run under
daemontools!!!
# Don't fork into background.
# Default: no
#Foreground yes
Foreground yes
As you can see, whenever freshclam downloads new virus definitions, or whenever it runs into a problem with the process, it calls a script whose name you specifiy in the freshclam.conf file. I use two scripts, which I call "freshclam-good" and "freshclam-bad", for this purpose.
Below are examples of what my own scripts look like, however you should really write your own scripts because your needs may not be the same as mine (in fact, I'm pretty sure they are not the same as mine.)
My "freshclam-good" script looks something like this: | My "freshclam-bad" script looks something like this: (the email addresses have been changed, of course) |
#!/bin/sh # # freshclam-good # # if you want to be notified whenever the virus # definitions are updated, add some code here to # send yourself an email or whatever. # update qmail-scanner and simscan version files. if [ -e /var/qmail/bin/qmail-scanner-queue.pl ] then /var/qmail/bin/qmail-scanner-queue.pl -z fi if [ -e /usr/local/sbin/update-simscan ] then /usr/local/sbin/update-simscan fi exit 0 | #!/bin/sh # # freshclam-good # # if you want to be notified whenever there is a # problem updating the virus definitions, add some # code here to send yourself an email or whatever. # email notification to phone PATH="/usr/bin:/bin:/var/qmail/bin" cat <<EOF | qmail-inject From: System <postmaster@domain.xyz> To: Phone <1234567890@cell.carrier.xyz> Subject: freshclam error The freshclam program has encountered an error. EOF exit 0 |
And as you can tell from the sample freshclam.conf file, these scripts are in the /usr/local/sbin directory. They are owned by root and have permissions "0755".
The "update-simscan" program you see mentioned is available on my simscan page. It's basically a setuid wrapper which runs the "simscanmk -g" command as root, and is necessary because the scripts you see here will be running as the "clamav" user, which doesn't have write permission to the /var/qmail/control/simversions.cdb file.
We will be setting up two different services- one for clamd and one for freshclam.
I keep the daemontools services on my servers organized with the physical service directories all under /var/service.
# cd /var/service
# mkdir -m 1755 clamd
# mkdir -m 0755 clamd/log
# cd clamd
# wget -O run http://qmail.jms1.net/clamav/service-clamd-run
...
# chmod 755 run
# cd log
# wget -O run http://qmail.jms1.net/scripts/service-any-log-run
...
# chmod 755 run
# cd /var/service
# mkdir -m 1755 freshclam
# mkdir -m 0755 freshclam/log
# cd freshclam
# wget -O run http://qmail.jms1.net/clamav/service-freshclam-run
...
# chmod 755 run
# cd log
# wget -O run http://qmail.jms1.net/scripts/service-any-log-run
...
# chmod 755 run
Here are the download links for the run scripts.
|
|
Starting the services is just like starting any other daemontools services- simply create a symbolic link from the "/service" directory to wherever the physical service directory is.
# cd /service
# ln -s /var/service/clamd .
# ln -s /var/service/freshclam .
Wait a few seconds, and then use svscan to make sure the services are running correctly. You should see up-times of two or more seconds.
# svstat /service/clamd /service/freshclam
/service/clamd: up (pid 7172) 7 seconds
/service/freshclam: up (pid 7190) 7 seconds