Virus scanning your Qubes VMs and Templates with ClamAV

Here's a simple script to iterate over your VMs (and, optionally, your templates) and run clamscan against them.

#!/bin/bash
#
# Script to scan VMs and optionally
# templates with clamscan, batch style
#
usage()
{
cat << EOF
usage: $0

This script will power up VMs (by default) or templates
and run clamscan on them.

ARGS:
 -h  This help message
 -t  Scan templates instead ( full / disk instead of just /rw like on VMs)  
EOF
}

SCANTEMPLATE=0

# Parse arguments
while getopts ":th" OPTION
do
  case $OPTION in
    h)
      usage
      exit
      ;;
    t)
      SCANTEMPLATE=1
      ;;
    ?)
      usage
      exit 1
      ;;
  esac
done

if [ $SCANTEMPLATE -eq 1 ]; then
  VMS=$(qvm-ls --raw-data name | grep "\\[" | tr -d {}[]=\>)
  DIR="--exclude-dir=^/sys --exclude-dir=^/dev --exclude-dir=^/proc /"
else
  VMS=$(qvm-ls --raw-data name | egrep -v "\\[|dvm|dom0" | tr -d {})
  DIR="/rw"
fi

for vm in ${VMS[@]}; do
  echo "Attempting to run clamscan -ri $DIR inside $vm"
  # First check if the VM is running, so we know if we should shut it down after
 qvm-check --quiet --running $vm
  if [ $? -eq 1 ]; then
    RUNNING=1
  else
    RUNNING=0
  fi

  qvm-run -u root -a --nogui -p $vm "clamscan -ri $DIR"

  # Shut down the VM if it wasn't running to begin with
 if [ $RUNNING -eq 1 ]; then
    qvm-shutdown $vm
  fi
done

For templates we scan the full disk /, whereas for the AppVMs we just scan the writable dir /rw

The script will start any VMs it needs to, and remember if it had to, so that it shuts down just the VMs that weren't already running.

There are a couple of caveats to this approach:

1) The AppVMs ClamAV databases are potentially out of date, since they are in /var/lib/clamav and therefore inherited by the TemplateVM. I recommend occasionally powering up your TemplateVM and ensure that ClamAV is starting and downloading fresh signatures. Certainly it is necessary the first time you install clamav on the templates.

2) In order for the TemplateVMs to download those signatures are all, they need to be able to reach the ClamAV db repositories via HTTP. Templates can't connect to most outbound HTTP servers except for APT, Yum repos etc, via the Qubes Updates Proxy service. This means that you need to tell Freshclam that there is a proxy server. To do this, add the following two lines to /etc/clamav/freshclam.conf (on Debian based templates - Fedora is probably similar):

HTTPProxyServer 10.137.255.254
HTTPProxyPort 8082

You could add this script to a cron in dom0 or just have a cron that uses notify-send to remind you to run a weekly scan.

Tags: