What Is ClamAV

ClamAV is a free, open-source antivirus engine designed for detecting malware, viruses, trojans, and other malicious software. It is maintained by Cisco's Talos Intelligence Group and is one of the most widely deployed open-source antivirus solutions in the world.

While Linux systems are generally less targeted by malware than Windows, ClamAV is valuable in several scenarios: scanning files on a mail server before delivery, checking uploads on a web server, auditing shared drives that serve Windows clients, and verifying the integrity of downloaded software.

clamscan The command-line scanner. Loads the virus database each time it runs. Best for on-demand, one-off scans.
clamd The ClamAV daemon. Keeps the virus database loaded in memory for faster scanning. Best for frequent or automated scans.
freshclam The virus definition updater. Downloads the latest signatures from ClamAV's servers so your scanner can detect new threats.
clamdscan A client that sends scan requests to the clamd daemon. Much faster than clamscan because it does not reload the database each time.

Installing ClamAV

ClamAV is available in the default repositories of most major Linux distributions.

Ubuntu / Debian

# Install ClamAV and the daemon
sudo apt update
sudo apt install clamav clamav-daemon

# Verify installation
clamscan --version

Fedora / RHEL

sudo dnf install clamav clamav-update clamd

After installation, the freshclam service typically starts automatically to download the latest virus definitions. You can check its status:

sudo systemctl status clamav-freshclam
💡
First update takes time.

The initial virus database download can take several minutes depending on your connection speed. The database files are stored in /var/lib/clamav/ and total approximately 300-400 MB. Do not run a scan until the first update completes, or your results will be unreliable.

Updating Virus Definitions

An antivirus scanner is only as good as its virus definitions. ClamAV's freshclam tool downloads updated signature databases from ClamAV's content delivery network.

Automatic Updates

The clamav-freshclam service runs automatically and checks for updates multiple times per day. Verify it is running:

sudo systemctl status clamav-freshclam

# If not running, start and enable it
sudo systemctl start clamav-freshclam
sudo systemctl enable clamav-freshclam

Manual Updates

If you need to force an immediate update (for example, after a fresh install), stop the freshclam service first to avoid lock conflicts, then run it manually:

# Stop the service to avoid database lock
sudo systemctl stop clamav-freshclam

# Run freshclam manually
sudo freshclam

# Restart the service
sudo systemctl start clamav-freshclam

Successful output looks like:

ClamAV update process started at Mon Mar  2 10:30:00 2026
daily.cvd database is up-to-date (version: 27250)
main.cvd database is up-to-date (version: 62)
bytecode.cvd database is up-to-date (version: 335)
⚠️
Do not run freshclam while the service is active.

Running freshclam manually while clamav-freshclam.service is running causes a database lock error. Always stop the service first, update manually, then restart the service.

Freshclam Configuration

The freshclam configuration file is located at /etc/clamav/freshclam.conf. Key settings include:

Checks 24 Number of update checks per day. Default is 12 (every 2 hours). Setting to 24 checks every hour.
DatabaseMirror The server to download updates from. Default is database.clamav.net which uses a CDN for fast downloads.
NotifyClamd Path to clamd.conf. When set, freshclam notifies the clamd daemon to reload its database after an update.

Running Scans

The clamscan command is the primary tool for on-demand scanning. It loads the virus database into memory, scans the specified files or directories, and reports any detections.

Scanning a Single File

clamscan /path/to/suspicious-file.zip

Scanning a Directory

# Scan a directory (non-recursive)
clamscan /home/john/Downloads/

# Scan a directory recursively (include subdirectories)
clamscan -r /home/john/Downloads/

Scanning with Useful Options

# Recursive scan, only show infected files, log results
clamscan -r -i --log=/var/log/clamav/scan.log /home/

# Scan and automatically remove infected files
clamscan -r --remove /home/john/Downloads/

# Scan and move infected files to quarantine
clamscan -r --move=/var/quarantine /home/john/Downloads/

# Scan entire system (excluding some directories)
sudo clamscan -r --exclude-dir="^/sys" --exclude-dir="^/proc" \
  --exclude-dir="^/dev" -i /
⚠️
Use --remove with caution.

The --remove flag permanently deletes files that ClamAV identifies as infected. False positives can and do occur. It is safer to use --move=/var/quarantine so you can review the files before deletion and recover any false positives.

Understanding Scan Results

After a scan completes, ClamAV displays a summary:

----------- SCAN SUMMARY -----------
Known viruses: 8702317
Engine version: 1.3.0
Scanned directories: 142
Scanned files: 1893
Infected files: 1
Data scanned: 456.23 MB
Time: 120.456 sec (2 m 0 s)
Known viruses The total number of signatures in your virus database. A higher number means more comprehensive coverage.
Infected files The number of files that matched a malware signature. If this is 0, no threats were found.
Exit code clamscan returns 0 for clean, 1 for infected files found, and 2 for errors. Useful for scripting.

Scheduling Scans with Cron

Running scans manually is fine for spot checks, but for consistent protection you should schedule regular automatic scans using cron.

Creating a Scan Script

First, create a simple script that runs the scan and logs the results:

#!/bin/bash
# /usr/local/bin/clamav-scan.sh
# Scheduled ClamAV scan script

SCAN_DIR="/home"
LOG_FILE="/var/log/clamav/scheduled-scan.log"
QUARANTINE="/var/quarantine"

# Create quarantine directory if it does not exist
mkdir -p "$QUARANTINE"

# Run the scan
echo "=== ClamAV Scan Started: $(date) ===" >> "$LOG_FILE"
clamscan -r -i --move="$QUARANTINE" "$SCAN_DIR" >> "$LOG_FILE" 2>&1
echo "=== ClamAV Scan Finished: $(date) ===" >> "$LOG_FILE"
echo "" >> "$LOG_FILE"
# Make the script executable
sudo chmod +x /usr/local/bin/clamav-scan.sh

# Create the quarantine directory
sudo mkdir -p /var/quarantine

Adding a Cron Job

# Edit the root crontab
sudo crontab -e

# Add this line to run a scan every day at 3:00 AM
0 3 * * * /usr/local/bin/clamav-scan.sh
💡
Schedule scans during off-peak hours.

ClamAV scanning is CPU and I/O intensive. Running a full system scan during working hours can noticeably slow down the system. Schedule scans for late night or early morning when the system is idle.

Checking Scan Logs

# View the latest scan results
sudo tail -50 /var/log/clamav/scheduled-scan.log

# Search for infected files in the log
sudo grep "FOUND" /var/log/clamav/scheduled-scan.log

The clamd Daemon

For environments that require frequent or real-time scanning, the clamd daemon keeps the virus database loaded in memory. This eliminates the startup cost of loading the database for each scan, making individual scans dramatically faster.

Starting clamd

# Start the ClamAV daemon
sudo systemctl start clamav-daemon

# Enable it to start on boot
sudo systemctl enable clamav-daemon

# Check its status
sudo systemctl status clamav-daemon
💡
Memory usage.

The clamd daemon loads the entire virus database into memory, which consumes approximately 1-1.5 GB of RAM. On systems with limited memory, you may prefer to use clamscan on-demand instead of running the daemon continuously.

Scanning with clamdscan

Once clamd is running, use clamdscan instead of clamscan for much faster scanning:

# Scan a directory using the daemon
clamdscan /home/john/Downloads/

# Scan and move infected files
clamdscan --move=/var/quarantine /home/john/Downloads/

# Multi-threaded scan (uses all available threads)
clamdscan --multiscan /home/

The --multiscan flag enables parallel scanning using multiple threads, which can significantly speed up scans of large directories on multi-core systems.

clamd Configuration

The clamd configuration file is at /etc/clamav/clamd.conf. Important settings include:

MaxFileSize Maximum file size to scan. Files larger than this are skipped. Default is 25 MB. Increase for servers handling large uploads.
MaxScanSize Maximum data size scanned within an archive. Default is 100 MB. Prevents denial-of-service from zip bombs.
ExcludePath Regular expression for paths to exclude from scanning. Useful for skipping virtual filesystems like /proc and /sys.

Summary

In this tutorial, you learned how to set up and use ClamAV for malware detection on Linux:

  • Installation -- installing ClamAV and its components on Ubuntu/Debian and Fedora/RHEL
  • Virus definitions -- keeping signatures up to date with freshclam (automatic and manual updates)
  • On-demand scanning -- using clamscan with options for recursive scanning, quarantine, and logging
  • Understanding results -- interpreting scan summaries and exit codes
  • Scheduled scanning -- automating regular scans with a script and cron
  • clamd daemon -- running the daemon for faster, memory-resident scanning with clamdscan
🎉
Your system is now protected!

With ClamAV installed, definitions updating automatically, and scheduled scans configured, you have a solid malware detection layer on your Linux system. Remember to periodically check your scan logs and quarantine directory.