ClamAV is a free, open-source antivirus engine. On a Linux server its job is mostly to find malicious files that arrive through uploads, compromised plugins or email attachments — web shells in a WordPress uploads folder, phishing kits, infected documents. This guide installs it, keeps its signatures current, runs and schedules scans, and covers what to do when it finds something.
Before You Start: Memory
ClamAV loads its whole signature database into memory, which takes roughly 1 GB or more of RAM on its own, during each scan or for as long as the daemon runs. On a small plan, run scheduled scans with clamscan instead of keeping the daemon running, and scan at a quiet hour. If you want the daemon running all the time alongside a web stack, choose a plan with more memory — compare them on the hardware specifications page.
Step 1 — Install
# Ubuntu / Debian
sudo apt update
sudo apt install clamav clamav-daemon -y
# AlmaLinux / Rocky Linux
sudo dnf install epel-release -y
sudo dnf install clamav clamav-update clamd -y
Step 2 — Download Signatures and Keep Them Current
# Ubuntu / Debian: freshclam runs as a service; stop it for the first manual update
sudo systemctl stop clamav-freshclam
sudo freshclam
sudo systemctl enable --now clamav-freshclam
# AlmaLinux / Rocky
sudo freshclam
sudo systemctl enable --now clamav-freshclam
freshclam then checks for new signatures several times a day by itself. A scanner with old signatures misses new threats, so make sure the service stays enabled.
Step 3 — Run a First Scan
sudo clamscan -r --infected /var/www
-r scans subdirectories; --infected prints only what it finds, instead of every clean file. Scan wherever untrusted files arrive: web roots, upload directories, /home, and /tmp.
Quarantine Instead of Delete
ClamAV can delete what it finds with --remove, but false positives happen — and a deleted file is evidence you can no longer examine. Move detections aside instead:
sudo mkdir -p /root/quarantine
sudo chmod 700 /root/quarantine
sudo clamscan -r --infected --move=/root/quarantine --log=/var/log/clamav/scan.log /var/www
Faster Repeated Scans with the Daemon
If memory allows, keep clamd running so the signatures load once, and scan with clamdscan:
# Ubuntu / Debian
sudo systemctl enable --now clamav-daemon
sudo clamdscan --multiscan --fdpass --infected /var/www
--fdpass lets the daemon read files it would otherwise not have permission to open. On AlmaLinux and Rocky the daemon is configured through /etc/clamd.d/scan.conf and runs as the clamd@scan service.
Excluding Directories
sudo clamscan -r --infected --exclude-dir='^/var/www/[^/]+/node_modules' /var/www
--exclude-dir takes a regular expression. Exclude large dependency or cache folders that you rebuild from source, never the upload directories — those are where malware lands.
Schedule Regular Scans
sudo crontab -e
30 3 * * * clamscan -r --infected --move=/root/quarantine --log=/var/log/clamav/daily.log /var/www /home
Check the log, or have cron email you only when something is found.
Scanning Mail on a Mail Server
If the server runs Postfix, scan attachments as mail arrives with clamav-milter (or through Amavis or rspamd). It rejects or tags infected messages before they reach a mailbox. Follow the integration guide for your MTA, and size the server for the daemon’s memory use. More on running mail on a VPS in SMTP VPS.
When ClamAV Finds Something
- Do not just delete and move on. Look at the file, its path, owner and timestamps:
ls -laandstat. - Find how it got there. Match the timestamp against web server access logs — an upload form, a vulnerable plugin or a stolen account.
- Fix the entry point, update the application and change the credentials involved.
- Look for persistence: unknown cron jobs, new users, modified system binaries. If you find any, treat the server as compromised — see How to Recover from a Compromised VPS.
What ClamAV Is Not
It finds known malicious files. It does not stop someone exploiting an unpatched application, and it rarely catches a fresh, hand-written web shell. Treat it as one layer alongside updates, a firewall, Fail2Ban and file integrity monitoring — the full list is in How to Conduct a Security Audit of Your VPS.
Common Problems
“Can't open file or directory” — a permissions issue. Run clamscan with sudo, or use clamdscan --fdpass.
freshclam: “Failed to lock the log file” — the freshclam service is already running. Stop it before a manual update, or just let it run.
The server slows down or the scan is killed — ClamAV ran out of memory. Stop the daemon and use scheduled clamscan runs, add swap, or move to a plan with more RAM.
A legitimate file is flagged — restore it from quarantine and report the false positive to the ClamAV project.
Continue Reading
- How to Detect and Remove Rootkits on a Linux VPS
- How to Set Up File Integrity Monitoring with AIDE
- VPS Security Checklist for Beginners
Browse more articles in Advanced Security & Compliance.