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 DNSDatabaseInfo current.cvd.clamav.net 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 DatabaseMirror db.local.clamav.net DatabaseMirror database.clamav.net
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/ClamByDay.sh )
- Here’s a script I use:
#!/bin/bash LOGFILE="/var/log/clamav/clamav-$(date +'%Y-%m-%d').log"; EMAIL_MSG="Learnspace Malware Report"; EMAIL_FROM="clamav-daily@myserver.com"; EMAIL_TO="notification@emailaddress.com"; DIRTOSCAN="/web/http"; 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"; fi done 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/clamscan_daily.sh /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/CronByDay.sh > /dev/null
- Obviously first test the cron by running /root/CronByDay.sh 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
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.