I wanted to install an anti-virus scanner to work with my smtp server (exim) and since I couldn’t find a centos repository that included clamav and didn’t want to spend hours searching I just downloaded the source and installed from scratch. To do this you will need to have a compiler and development libraries installed. The steps I followed were:

  • Create the clamav user and group

    sudo groupadd clamav
    sudo useradd -g clamav -c "clamav user" -d /var/clamav -s /sbin/nologin -m clamav

  • Download the source from http://www.clamav.net into a working directory and unpack (eg. tar zxvf clamav-0.93.tar.gz) which will create a source code directory called clamav-0.93 under your working directory.
  • cd into the source code directory and execute ./configure in my case I didn’t want to change any of the defaults and wanted to install clamav into /usr/local which is the default location. The output will tell you if there are any missing prerequisites such as zlib. If there are any missing prerequisites then I recommend that you install them first and then start to build and install clamav.
  • Execute make which will compile the clamav source with the configuration options from above.
  • Install clamav

    sudo make install

  • Edit the clamd.conf file in /usr/local/etc and set appropriate values for the various configuration items. My clamd.conf has the following settings:

    LogFile /tmp/clamd.log
    LogFileUnlock yes
    LogFileMaxSize 2M
    LogTime yes
    LogClean yes
    LogSyslog yes
    PidFile /var/run/clamd.pid
    LocalSocket /var/run/clamd.exim/clamd.sock
    FixStaleSocket yes
    MaxRecursion 128
    MaxFileSize 15M
    MaxFiles 1500

    for all other settings I accepted the defaults.

  • Configure /usr/local/etc/fresclam.conf - the settings I changed in my freshclam.conf were:

    UpdateLogFile /var/log/freshclam.log
    LogTime yes
    LogSyslog yes
    PidFile /var/run/freshclam.pid
    DatabaseMirror database.clamav.net
    NotifyClamd /usr/local/etc/clamd.conf

    all other settings were at their default values

  • Run freshclam once manually to seed the virus signatures in the database. Execute /usr/local/bin/freshclam
  • For normal operations I also set freshclam to run once per hour by adding it to my crontab

    8 0-23 * * * /usr/local/bin/freshclam 2>&1

  • Create a script to automatically start clamd on a system reboot in /etc/init.d. My /etc/init.d/clamd script is:


    #! /bin/sh
    #
    ### BEGIN INIT INFO
    # Provides: clamd
    # Required-Start: $syslog $network clamd
    # X-UnitedLinux-Should-Start:
    # Required-Stop: $syslog $network clamd
    # X-UnitedLinux-Should-Stop:
    # Default-Start: 3 5
    # Default-Stop: 0 1 2 6
    # Short-Description: anti virus scan mails
    # Description: Start clamd
    ### END INIT INFO
    #

    # Check for missing binaries (stale symlinks should not happen)
    # Note: Special treatment of stop for LSB conformance
    CLAMD_BIN=/usr/local/sbin/clamd
    CLAMD_CONFIG=/usr/local/etc/clamd.conf
    CLAMD_PID_FILE=/var/run/clamd.pid

    test -x $CLAMD_BIN || { echo "$CLAMD_BIN not installed";
    if [ "$1" = "stop" ]; then exit 0;
    else exit 5; fi; }

    # Check for existence of needed config file and read it
    test -r $CLAMD_CONFIG || { echo “$CLAMD_CONFIG not existing”;
    if [ "$1" = "stop" ]; then exit 0;
    else exit 6; fi; }

    # Shell functions sourced from /etc/rc.status:
    # rc_check check and set local and overall rc status
    # rc_status check and set local and overall rc status
    # rc_status -v be verbose in local rc status and clear it afterwards
    # rc_status -v -r ditto and clear both the local and overall rc status
    # rc_status -s display “skipped” and exit with status 3
    # rc_status -u display “unused” and exit with status 3
    # rc_failed set local and overall rc status to failed
    # rc_failed set local and overall rc status to
    # rc_reset clear both the local and overall rc status
    # rc_exit exit appropriate to overall rc status
    # rc_active checks whether a service is activated by symlinks
    # rc_splash arg sets the boot splash screen to arg (if active)
    . /etc/rc.status

    # Reset status of this service
    rc_reset

    # Return values acc. to LSB for all commands but status:
    # 0 - success
    # 1 - generic or unspecified error
    # 2 - invalid or excess argument(s)
    # 3 - unimplemented feature (e.g. “reload”)
    # 4 - user had insufficient privileges
    # 5 - program is not installed
    # 6 - program is not configured
    # 7 - program is not running
    # 8–199 - reserved (8–99 LSB, 100–149 distrib, 150–199 appl)
    #
    # Note that starting an already running service, stopping
    # or restarting a not-running service as well as the restart
    # with force-reload (in case signaling is not supported) are
    # considered a success.

    case “$1″ in
    start)
    echo -n “Starting clamd”
    $CLAMD_BIN 2>&1

    # Remember status and be verbose
    rc_status -v
    ;;
    stop)
    echo -n “Shutting down clamd”
    CLAMD_PID=`/usr/bin/head -n 1 ${CLAMD_PID_FILE}`
    kill -TERM ${CLAMD_PID}

    # Remember status and be verbose
    rc_status -v
    ;;
    restart)
    ## Stop the service and regardless of whether it was
    ## running or not, start it again.
    $0 stop
    $0 start

    # Remember status and be quiet
    rc_status -v
    ;;
    reload)
    echo -n “Reload service clamd”
    $CLAMD_PID=`head -n 1 ${CLAMD_PID_FILEi}`
    kill -HUP ${CLAMD_PID}
    rc_status -v

    ## Otherwise:
    #$0 stop && $0 start
    #rc_status
    ;;
    *)
    echo “Usage: $0 {start|stop|restart|reload}”
    exit 1
    ;;
    esac
    rc_exit

  • Now make a link from the /etc/init.d/clamd script to the runlevel startup directories. Try

    chkconfig clamd on

    or possibly

    ln -s /etc/init.d/clamd /etc/rc3.d/S99clamd
    ln -s /etc/init.d/clamd /etc/rc5.d/S99clamd

  • Now start clamd

    /etc/init.d/clamd start