Submitted by mig5 on
Here's a simple script to iterate over your VMs (and, optionally, your templates) and run clamscan against them.
#
# 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):
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.