Hardened Antivirus

Mar. 20, 2024 [hardening] [guides] [privacy-security] [libre] [technology]

Currently only one substantially complete antivirus kit casts itself among FOSS, ClamAV. It actually consists of several different programs. Clamscan, an independent CLI scan utility; Freshclam, a database updater; Clamdscan, a multithreaded scanning daemon; and Clamonacc, a realtime on-access file checker that feeds items into Clamdscan. Most guides to be found online only really ever cover the first two.

Installing the clamav-daemon package will pull in the rest of clamav as dependencies.

apt install clamav-daemon

freshclam

The Debian package has freshclam service configured to check for updates hourly. It is probably a good idea to leave this as is, but if you would like to adjust update frequency, edit freshclam.conf:

chmod 644 /etc/clamav/freshclam.conf
vi /etc/clamav/freshclam.conf

Adjust the line as desired:
Checks 24

The number represents one day divided by N. Return freshclam.conf to read-only.

chmod 444 /etc/clamav/freshclam.conf

And restart clamav-freshclam daemon.

systemctl restart clamav-freshclam

Different databases are available and formatted as db.$LOCALE_ABBREVIATION.clamav.net. The default abstracts this as db.local.clamav.net, however all the official databases I could find are all behind cloudflare. But that doesn’t mean we must be solely dependent on Cisco and their choice of cloudflare. Sanesecurity maintains lists of third party clamav databases.

Edit /etc/clamav/freshclam.conf and specify a few with DatabaseCustomURL that fit the scope of our filtering:

DatabaseCustomURL https://mirror.rollernet.us/sanesecurity/badmacro.ndb
DatabaseCustomURL https://mirror.rollernet.us/sanesecurity/blurl.ndb

Not only does this diversify our signature sources, but also improves the detection rate that some in the tech scene like to bludgeon ClamAV over in side-by-side AV comparisons.

You can check that custom databases and signatures are getting updated from freshclam.log:

grep -e sigs /var/log/clamav/freshclam.log

clamscan

Individual files and directories can be scanned manually with clamscan. The -i switch indicates to only report infected items and the -r switch instructs clamscan to iterate recursively through directories.

clamscan -ir /path/to/scan

The output prints a brief report indicating if any of the scanned files match known infected signatures from the database.

----------- SCAN SUMMARY -----------
Known viruses: 8694987
Engine version: 1.0.3
Scanned directories: 1
Scanned files: 5
Infected files: 0
Data scanned: 0.01 MB
Data read: 0.00 MB (ratio 2.00:1)
Time: 18.876 sec (0 m 18 s)
Start Date: 2024:03:20 13:47:32
End Date:   2024:03:20 13:47:50

Clamscan should be setup to run a daily system scan on most or all of your directories. First create a shell script:

vi daily-scan.sh

And populate it with something like:

#!/bin/bash
clamscan -ir / \
--exclude=/home/user/Directory_that_I_trust \
--exclude=/usr \
--exclude=/var \
--exclude=/lib \
--exclude=/etc \
--exclude=/sbin \
--exclude=/bin \
--exclude=/lost+found \
--exclude=/media \
--exclude=/srv \
--exclude=/lib64 \
--exclude=/sys \
--exclude=/dev \
--exclude=/proc \
--exclude=/net \
--exclude=/mnt \
--log=/var/log/clamav/clamscan.log \
--move=/home/user/.quarantine

–exclude instructs clamscan to ignore a particular directory. This is necessary in the case of some system directories, and so that clamav does not end up inadvertently scanning itself and locking up. There are probably also user directories that you trust are very low risk which don’t warrant a pass from the active daily scan.

This will also send output logs to /var/log/clamav/clamscan.log. And any detected items will automatically be moved to a hidden “quarantine” directory.

Create the hidden quarantine, then set a cron job to run the script.

mkdir /home/user/.quarantine
crontab -e

Append:

15 12 * * * /path/to/daily-scan.sh

This will scan the entire system every day around noon.

clamdscan

Clamdscan is intended to tag team with Clamonacc, but can also be used to run scans manually. Being multithreaded, it is much faster than clamscan. But the default settings have clamdscan omit files larger than 5MB and relax other checks.

clamdscan --multiscan --fdpass /path/to/target

–fdpass is necessary, as of clamav v.0.103, in order for clamdscan to read files owned by other users besides user “clamav”. It might be possible to use this as your full system daily scan instead, but you would want to consider raising that file size limit up from 5MB in /etc/clamav/clamd.conf.

While clamdscan is performing a check, its progress can be monitored through clamdtop. clamdtop opens a textmode viewer that shows all active scan queues along with available threads and memory.

clamdtop readout

clamonacc

The component that only very few online guides desire to cover. And even those feel inexhaustive. I’m not sure if it’s just poorly documented or just laziness from tech journalists. clamonacc is not automatically configured, at least not in Debian packaging, and needs to be setup manually. However, it is the way to utilize clamav to its fullest potential to protect your system.

Edit /etc/clamd.conf and add options for on-access scanning. Select directories known for handling foreign files from over the network. Here are some general suggestions for a system running Firefox browser:

OnAccessIncludePath /home/user/Downloads
OnAccessIncludePath /home/user/.mozilla/firefox/$YOUR_PROFILE_STRING.default-esr
OnAccessIncludePath /home/user/.cache
OnAccessIncludePath /var/tmp
OnAccessIncludePath /dev/shm
OnAccessPrevention yes
OnAccessExcludeUname clamav

Debian uses clamav user to run clamdscan, so we exclude that username. OnAccessPrevention withholds file access from the system until it has been cleared as safe by clamdscan. Restart clamav-daemon to apply these new settings:

systemctl restart clamav-daemon

Next, we want to create a systemd unit file for running clamonacc.

vi /etc/systemd/system/clamonacc.service

Populate it with:

[Unit]
Description=ClamAV On Access Scanner
Requires=clamd@service
After=clamav-daemon.service syslog.target network-online.target

[Service]
Type=simple
User=root
ExecStart=/usr/sbin/clamonacc -F --fdpass --log=/var/log/clamav/clamonacc.log --move=/home/user/.quarantine
Restart=on-failure
RestartSec=7s

[Install]
WantedBy=multi-user.target

The official documentation wants us to use “Requires=clamav-daemon @service” but since the Debian package does things its own way, we substitute “clamd@service”. Enable and start the new service:

systemctl daemon-reload
systemctl enable clamonacc.service
systemctl start clamonacc

We can check that it is working by dropping a test file into one of the protected directories, and then trying to access it.

cd /path/to/eicar.com.txt /home/user/Downloads/
cat /home/user/Downloads/eicar.com.txt

If it’s working, it should either immediately get moved to ~/.quarantine or you should get a warning “cat: Downloads/eicar.com.txt: Operation not permitted” before it then moves to ~/.quarantine.

On most computers, clamonacc should be pretty quick to scan and detect anything. You may notice a bit of a slowdown in some instances. For example, if one chooses to monitor the entire .mozilla directory, the right click menu in Firefox may take a few hundred milliseconds longer to open. Latency like this will probably be more pronounced on older computers but the tradeoff should be worth it to implement “exception deny” behavior around incoming files.