Automate your Linux Malware Scans

For any of us running servers it is critical that we keep on top of security. As soon as I provision a new server I receive hundreds of attacks, even before any website or front-facing service is installed on the server. Why? Because there are so many bots scanning IP ranges for machines to compromise. You can view my hardening article to see how I mitigate as many of these attack vectors as I can and reduce the attack surface of the server, but even so some attacks may eventually get through, e.g. via a vulnerability in a CMS website, such as a WordPress or Joomla extension (or any web platform – nothing is entirely secure). These systems, by design, need to provide various functionalities to front-end users that can, inevitably, targeted by attackers, e.g. file uploads. To mitigate damage done under such conditions we should run regular malware checks. Linux comes with a variety of tools to help.

We generally use ClamAV as our AV library. This should be installed on all of our servers – but you see it is not there are instructions below.

  • Ensure clamav is installed using your package manager ( on debian I use dpkg -l | grep clam )
  • If not installed then install with your package manager, e.g. on Jessie I use apt-get install clamav && apt-get install clamav-freshclam
  • Verify version with # freshclam -V (capital V)
  • I would usually now run an update manually to freshen the database.
  • Once done lets have updates done automatically.
  • Open the freshclam conf
  • Ensure it is running once per day ( not once per hour as default ). See the “Checks” flag:

Here’s my config:

# Automatically created by the clamav-freshclam postinst
# Comments will get lost when you reconfigure the clamav-freshclam package
DatabaseOwner clamav
UpdateLogFile /var/log/clamav/freshclam.log
LogVerbose false
LogSyslog false
LogFacility LOG_LOCAL6
LogFileMaxSize 0
LogRotate true
LogTime true
Foreground false
Debug false
MaxAttempts 5
DatabaseDirectory /var/lib/clamav
ConnectTimeout 30
ReceiveTimeout 30
TestDatabases yes
ScriptedUpdates yes
CompressLocalDatabase no
SafeBrowsing false
Bytecode true
NotifyClamd /etc/clamav/clamd.conf
# Check for new database 1 time a day
Checks 1

Start the service

# service clamav-freshclam start

Check that the service is running

# ps -ef | grep clam

You should see something like the following

clamav 31233 1 0 14:50 ? 00:00:00 /usr/bin/freshclam -d --foreground=true
root 31238 31103 0 14:50 pts/0 00:00:00 grep clam

The second entry is just our query.

  • Remember that the services may be names differently based on your distro, so use aptitude, apt-cache, dpkg, yum, rpm, or whatever package manager you use to check. e.g. IIRC the updater is clamav-freshclam on debian based distros and clamav-freshclamd on rhl based distros. I think CentOS is ClamAV-freshclamd – so if you get an error search for the correct spelling of the daemon for your package manager.
  • OK, so we now have clamav updating once per day. We still need to run the program, however. To do this regularly let’s use CRON.
  • We don’t want clamav to just dump reports onto the server where no-one will see them so we need to create a processing script. Something like the following ( I have stored this in /root/ )
  • Here’s a script I use:
LOGFILE="/var/log/clamav/clamav-$(date +'%Y-%m-%d').log";
EMAIL_MSG="Learnspace Malware Report";

for S in ${DIRTOSCAN}; do
DIRSIZE=$(du -sh "$S" 2>/dev/null | cut -f1);

echo "Starting a daily scan of "$S" directory.
Amount of data to be scanned is "$DIRSIZE".";

clamscan -ri "$S" >> "$LOGFILE";

# get the value of "Infected lines"
MALWARE=$(tail "$LOGFILE"|grep Infected|cut -d" " -f3);

# if the value is not equal to zero, send an email with the log file attached
if [ "$MALWARE" -ne "0" ];then
# using heirloom-mailx below
echo "$EMAIL_MSG"|mail -a "$LOGFILE" -s "Malware Found on My Server" -r "$EMAIL_FROM" "$EMAIL_TO";

exit 0
  • Ensure you set the executable bit on the shell script or it won’t be run!
# chmod +x
  • This is in the /root/ folder so your cronjob needs to run as root – the easiest method is to simply add it using the crontab -e or push a simlink to /etc/cron.daily (e.g ln /root/ /etc/cron.daily/clamscan_daily)- I prefer the former because crontab -l will not pick up the latter + one can fine tune the timings.
  • So I’m using this to set the scan starting at 10pm – remember that the backups kick off at around 1am:
0 22 * * * /root/ > /dev/null
  • Obviously first test the cron by running /root/ on a known infected folder, otherwise you’ll only get one chance per day. A full /web/http scan will take some time. You’re not directing to null so output will be displayed for debugging.


Rootkits are not covered by ClamAV let’s use the venerable rkhunter and chkrootkit instead. Instructions to follow – they are very very similar to those for clamav. I believe rkhunter may have been renamed to lynis.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.