15%

Save 15% on All Hosting Services

Test your skills and get Discount on any hosting plan

Use code:

Skills
Get Started
24.10.2024

How to Install ClamAV on Linux: A Complete Technical Guide

ClamAV is an open-source, cross-platform antivirus engine maintained by Cisco Talos that detects viruses, trojans, rootkits, malware, and other malicious threats. It operates using a signature-based detection model backed by a continuously updated database (/var/lib/clamav/), and it is the de facto standard antivirus solution for Linux servers, mail gateways, and web hosting environments.

This guide covers the full installation lifecycle: system preparation, package installation across major distributions, virus database management with freshclam, daemon configuration, scanning strategies, quarantine handling, cron automation, and real-time scanning via clamonacc — including production-grade pitfalls that most tutorials omit.

Why ClamAV Matters on Linux Servers

Linux systems are not immune to malware. While Linux-targeting exploits are less common than Windows threats, servers running web applications, mail relays, or file-sharing services are active vectors for malware distribution — even when the Linux host itself is not the primary target. A compromised VPS Hosting environment can silently redistribute infected files to end users, trigger blacklisting by spam databases, or serve as a pivot point in a larger attack chain.

ClamAV addresses this by providing:

  • On-demand scanning for scheduled or triggered analysis
  • Daemon-mode scanning (clamd) for high-throughput, low-latency checks
  • Mail gateway integration via clamsmtp, amavisd-new, or Milter
  • Real-time file system monitoring via clamonacc (Linux kernel fanotify)
  • Bytecode signatures for heuristic detection beyond static pattern matching

Step 1: Prepare and Update Your System

Before installing any package, synchronize your package index and apply pending security patches. Running outdated system libraries alongside a security tool creates a false sense of protection.

For Debian/Ubuntu:

sudo apt update && sudo apt upgrade -y

For CentOS/RHEL 7:

sudo yum update -y

For Rocky Linux / AlmaLinux / RHEL 8+:

sudo dnf update -y

For Fedora:

sudo dnf update -y

Confirm your kernel and glibc versions are current, as clamonacc (real-time scanning) requires kernel 5.1+ for stable fanotify support.

Step 2: Install ClamAV

ClamAV is available in the default repositories of all major distributions. The key distinction is whether you install only the scanner (clamav) or also the background daemon (clamav-daemon / clamd), which is strongly recommended for any production server.

For Debian/Ubuntu:

sudo apt install clamav clamav-daemon -y
  • clamav — installs clamscan and freshclam
  • clamav-daemon — installs clamd, the persistent scanning daemon that keeps the virus database loaded in memory, dramatically reducing per-scan overhead
    
    For CentOS/RHEL 7 (requires EPEL):
    sudo yum install epel-release -y
    sudo yum install clamav clamav-update clamav-scanner-systemd clamd -y
    For Rocky Linux / AlmaLinux / RHEL 8+ (requires EPEL):
    sudo dnf install epel-release -y
    sudo dnf install clamav clamav-update clamd -y
    For Fedora:
    sudo dnf install clamav clamav-update clamd -y
    Post-install binary locations to verify:
    
    
    
    
    Binary
    Path
    Purpose
    
    
    
    
    clamscan
    /usr/bin/clamscan
    On-demand CLI scanner
    
    
    clamd
    /usr/sbin/clamd
    Background scanning daemon
    
    
    freshclam
    /usr/bin/freshclam
    Virus database updater
    
    
    clamdscan
    /usr/bin/clamdscan
    Client that delegates to clamd
    
    
    clamonacc
    /usr/sbin/clamonacc
    Real-time on-access scanner
    
    
    
    
    Step 3: Update the Virus Signature Database
    ClamAV's detection capability is entirely dependent on the currency of its signature database. The database lives in /var/lib/clamav/ and consists of several files: main.cvd, daily.cvd (or .cld), and bytecode.cvd.
    Stop the Daemon Before the First Update (Debian/Ubuntu)
    On Debian/Ubuntu systems, clamav-freshclam.service runs automatically after installation and locks the database directory. If you attempt to run freshclam manually while this service is active, you will encounter a lock conflict. Stop it first:
    sudo systemctl stop clamav-freshclam
    sudo freshclam
    sudo systemctl start clamav-freshclam
    On CentOS/RHEL/Rocky/Alma:
    sudo freshclam
    Expected output on a successful update:
    ClamAV update process started at ...
    daily.cvd updated (version: 27xxx, sigs: xxxxxxx, ...)
    main.cvd is up to date
    bytecode.cvd is up to date
    Configure Automatic Database Updates
    freshclam is controlled by /etc/clamav/freshclam.conf. Key directives to review:
    sudo nano /etc/clamav/freshclam.conf
    Critical parameters:
    
    Checks 24 — number of update checks per day (default: 12 on some distros)
    DatabaseMirror database.clamav.net — official mirror; do not change unless using a private mirror
    NotifyClamd /etc/clamav/clamd.conf — instructs freshclam to signal clamd after an update so the daemon reloads signatures without restarting
    
    Step 4: Configure and Start the ClamAV Daemon
    The clamd daemon keeps the full virus database resident in RAM (typically 500 MB–1.2 GB depending on database version). This eliminates the multi-second startup cost of clamscan, making it essential for any environment that performs frequent or concurrent scans.
    Debian/Ubuntu
    sudo systemctl start clamav-daemon
    sudo systemctl enable clamav-daemon
    sudo systemctl status clamav-daemon
    CentOS/RHEL 7
    On RHEL 7, the service unit is named clamd@scan, referencing the configuration file /etc/clamd.d/scan.conf:
    sudo systemctl start clamd@scan
    sudo systemctl enable clamd@scan
    Rocky Linux / AlmaLinux / RHEL 8+
    sudo systemctl start clamd@scan
    sudo systemctl enable clamd@scan
    Key clamd.conf Parameters
    The daemon configuration lives at /etc/clamav/clamd.conf (Debian/Ubuntu) or /etc/clamd.d/scan.conf (RHEL family). Review these directives:
    sudo nano /etc/clamav/clamd.conf
    Important settings:
    
    LocalSocket /run/clamav/clamd.ctl — Unix socket path used by clamdscan; ensure this matches your client configuration
    MaxFileSize 100M — maximum file size to scan; increase for mail servers handling large attachments
    MaxScanSize 400M — maximum data scanned per file after decompression
    StreamMaxLength 100M — relevant for milter/stream-based scanning
    User clamav — daemon runs as the clamav user; ensure this user has read access to directories you intend to scan
    LogFile /var/log/clamav/clamd.log — enable persistent logging for audit trails
    
    Critical pitfall: If clamd runs as user clamav and you scan /home/user/uploads/, the clamav user must have read permissions on that path. Forgetting this results in silent scan failures — clamd will report "Access denied" errors in its log rather than returning a clean/infected verdict.
    Step 5: Running Scans with clamscan and clamdscan
    On-Demand Scanning with clamscan
    clamscan is the standalone scanner. It loads the database from disk on each invocation, making it slower but independent of the daemon.
    Scan a specific directory recursively:
    clamscan -r /path/to/directory
    Scan and display only infected files:
    clamscan -r --infected /path/to/directory
    Scan with verbose output and log results:
    sudo clamscan -r --infected --log=/var/log/clamav/manual_scan.log /var/www/html
    Move infected files to a quarantine directory:
    sudo clamscan -r --move=/var/quarantine /path/to/directory
    Remove infected files automatically (use with caution in production):
    sudo clamscan -r --remove /path/to/directory
    Scan the entire filesystem (expect significant runtime on large disks):
    sudo clamscan -r --infected --exclude-dir="^/sys" --exclude-dir="^/proc" --exclude-dir="^/dev" /
    Excluding /sys, /proc, and /dev is mandatory — scanning these pseudo-filesystems produces false errors and can cause hangs.
    High-Performance Scanning with clamdscan
    When clamd is running, use clamdscan instead of clamscan. It submits scan requests to the already-loaded daemon over the Unix socket, making it orders of magnitude faster for repeated or bulk scans.
    clamdscan --fdpass /path/to/directory
    The --fdpass flag passes the file descriptor directly to clamd, bypassing permission issues that arise when the daemon's user cannot read the target path directly.
    Multi-threaded scanning with clamdscan:
    clamdscan --multiscan --fdpass /var/www/html
    --multiscan instructs clamd to scan files in parallel using its thread pool, significantly reducing wall-clock time on multi-core systems.
    clamscan vs. clamdscan: Performance Comparison
    
    
    
    
    Attribute
    `clamscan`
    `clamdscan`
    
    
    
    
    Database load per scan
    Yes (slow startup)
    No (daemon keeps DB in RAM)
    
    
    Typical startup time
    5–30 seconds
    Under 1 second
    
    
    Requires clamd running
    No
    Yes
    
    
    Parallel scanning
    No
    Yes (--multiscan)
    
    
    Best use case
    One-off manual scans
    Automated, frequent, or bulk scans
    
    
    Permission model
    Runs as invoking user
    Runs as clamav user (use --fdpass)
    
    
    
    
    Step 6: Automate Scanning with Cron
    For continuous protection, schedule regular scans using cron. The following example scans the web root daily at 02:00 AM and logs results with a timestamp.
    sudo crontab -e
    Add the following entry:
    0 2 * * * /usr/bin/clamdscan --multiscan --fdpass --log=/var/log/clamav/daily_scan_$(date +%Y%m%d).log /var/www/html
    Production-grade cron with email alerting on infection:
    0 2 * * * /usr/bin/clamscan -r --infected /var/www/html 2>&1 | grep -v "^$" | mail -s "ClamAV Daily Scan Report - $(hostname)" admin@yourdomain.com
    This pipes non-empty output directly to a mail recipient, ensuring you only receive alerts when something is found or an error occurs. Ensure mailutils or postfix is configured on the server.
    Rotate scan logs to prevent unbounded disk growth:
    sudo nano /etc/logrotate.d/clamav-scan
    /var/log/clamav/daily_scan_*.log {
        weekly
        rotate 4
        compress
        missingok
        notifempty
    }
    Step 7: Real-Time On-Access Scanning with clamonacc
    clamonacc is ClamAV's on-access scanning component, introduced as a stable feature in ClamAV 0.102. It hooks into the Linux kernel's fanotify subsystem to intercept file open and close events, scanning files before they are accessed.
    Requirements:
    
    Linux kernel 5.1 or later (for fanotify with FAN_OPEN_EXEC_PERM)
    ClamAV 0.102+
    clamd must be running
    Root privileges
    
    Enable On-Access Scanning in clamd.conf
    sudo nano /etc/clamav/clamd.conf
    Add or uncomment:
    OnAccessIncludePath /home
    OnAccessIncludePath /var/www/html
    OnAccessPrevention yes
    OnAccessExcludeUname clamav
    
    OnAccessPrevention yes — blocks access to infected files in real time (deny mode); set to no for detection-only mode
    OnAccessExcludeUname clamav — prevents clamd itself from triggering recursive scan loops
    
    Start clamonacc
    sudo clamonacc --log=/var/log/clamav/clamonacc.log --daemonize
    To run it as a systemd service, create a unit file:
    sudo nano /etc/systemd/system/clamonacc.service
    [Unit]
    Description=ClamAV On-Access Scanner
    Requires=clamav-daemon.service
    After=clamav-daemon.service
    
    [Service]
    Type=simple
    ExecStart=/usr/sbin/clamonacc --log=/var/log/clamav/clamonacc.log --foreground
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target
    sudo systemctl daemon-reload
    sudo systemctl enable --now clamonacc
    Known pitfall: On high-throughput servers (e.g., busy file upload endpoints), OnAccessPrevention yes can introduce measurable I/O latency. Benchmark your workload before enabling prevention mode in production. Consider scoping OnAccessIncludePath to the narrowest necessary path rather than broad directories like /.
    Step 8: Integrating ClamAV with Mail Servers
    ClamAV's most widespread production use case is mail gateway scanning. If you are running a mail server on your VPS Hosting or Dedicated Servers infrastructure, integrating ClamAV with your MTA is a critical security layer.
    Common integration stacks:
    
    Postfix + amavisd-new + ClamAV — amavisd-new acts as a content filter between Postfix and ClamAV, also handling SpamAssassin
    Postfix + clamsmtp — lightweight milter-style proxy
    Exim + ClamAV — native Exim av_scanner directive supports clamd directly via socket
    
    Example: Exim clamd integration in /etc/exim4/exim4.conf:
    av_scanner = clamd:/run/clamav/clamd.ctl
    This single directive routes all message content through the running clamd instance before delivery. Pair this with proper Email Hosting configuration to ensure your mail infrastructure is fully protected.
    Troubleshooting Common ClamAV Issues
    freshclam Fails with "locked by another process"
    sudo systemctl stop clamav-freshclam
    sudo rm -f /var/lock/clamav/freshclam.lock
    sudo freshclam
    sudo systemctl start clamav-freshclam
    clamd Fails to Start: "ERROR: Can't open/parse the config file"
    Verify the configuration file path and syntax:
    sudo clamd --config-file=/etc/clamav/clamd.conf --debug 2>&1 | head -50
    High Memory Usage
    clamd typically consumes 500 MB–1.2 GB of RAM with the full database loaded. On memory-constrained systems, consider:
    
    Setting MaxThreads 2 in clamd.conf to limit concurrency
    Using clamscan without the daemon for infrequent scans
    Upgrading to a plan with sufficient RAM — a VPS Hosting plan with at least 2 GB RAM is the practical minimum for running clamd alongside a web stack
    
    Scan Returns "Access denied" for Files
    The clamd daemon runs as the clamav user. Grant read access:
    sudo setfacl -R -m u:clamav:rX /path/to/scan
    Or use clamdscan --fdpass to pass file descriptors from the invoking user's context.
    False Positives
    ClamAV occasionally flags legitimate files, particularly compressed archives or certain PHP frameworks. To whitelist a known-safe file by hash:
    sigtool --md5 /path/to/legitimate/file >> /var/lib/clamav/whitelist.fp
    Restart clamd after modifying .fp files.
    ClamAV on Shared Hosting vs. VPS vs. Dedicated Server
    The deployment model significantly affects how ClamAV should be configured:
    
    
    
    
    Environment
    Recommended Mode
    Notes
    
    
    
    
    Shared Web Hosting
    On-demand clamscan via cron
    No root access; daemon mode unavailable
    
    
    VPS (2–4 GB RAM)
    clamd daemon + cron clamdscan
    Balance performance with memory constraints
    
    
    Dedicated Server
    clamd + clamonacc + mail integration
    Full feature set; no resource compromise
    
    
    GPU/High-compute node
    clamd daemon only
    Avoid clamonacc I/O overhead on data pipelines
    
    
    
    
    For environments requiring maximum throughput and full control over security tooling, Dedicated Servers provide the hardware headroom to run clamd, clamonacc, and mail scanning simultaneously without resource contention.
    Technical Decision Matrix and Key Takeaways
    Before deploying ClamAV, validate each of the following:
    
    Kernel version — run uname -r; confirm 5.1+ if clamonacc is required
    Available RAM — clamd needs 1–1.5 GB; plan accordingly before enabling the daemon
    freshclam automation — confirm clamav-freshclam.service is enabled and NotifyClamd is set in freshclam.conf
  • Socket permissions — verify clamav user can read all scan targets; use --fdpass with clamdscan where ACLs are impractical
  • Exclusion paths — always exclude /proc, /sys, /dev from recursive scans
  • Log rotation — implement logrotate for all ClamAV log files before enabling daily cron jobs
  • OnAccessPrevention — test in detection-only mode (no) before switching to blocking mode (yes) on production systems
  • Mail integration — if running a mail server, integrate via amavisd-new or native MTA av_scanner directive, not just periodic file scans
  • Quarantine directory — pre-create /var/quarantine with appropriate ownership before using --move; clamscan will not create it automatically
  • False positive management — maintain a .fp whitelist file and review scan logs after each database update for regressions

Frequently Asked Questions

Does ClamAV provide real-time protection on Linux by default?

No. After installation, ClamAV operates in on-demand mode only. Real-time protection requires explicitly enabling clamonacc with OnAccessIncludePath and OnAccessPrevention directives in clamd.conf, plus a kernel that supports fanotify (5.1+).

What is the difference between clamscan and clamdscan?

clamscan is a standalone binary that loads the virus database from disk on every invocation, resulting in a 5–30 second startup delay. clamdscan is a thin client that submits scan jobs to the already-running clamd daemon, which keeps the database in RAM — making it significantly faster for repeated or automated scans.

How much RAM does ClamAV's daemon require?

clamd with the current full database (main + daily + bytecode) typically requires between 700 MB and 1.2 GB of resident memory. On systems with less than 2 GB total RAM, running the daemon alongside a web server or database can cause memory pressure. Use clamscan without the daemon on memory-constrained instances.

Can ClamAV scan compressed archives and email attachments?

Yes. ClamAV natively unpacks and scans ZIP, RAR, 7z, TAR, GZIP, BZIP2, CAB, and many other archive formats, as well as OLE2 documents (Microsoft Office), PDF files, and ELF/PE executables. The MaxScanSize and MaxFileSize directives in clamd.conf control the depth and size limits for archive scanning.

Why does freshclam report "locked by another process" immediately after installation?

On Debian/Ubuntu, the clamav-freshclam systemd service starts automatically after package installation and holds an exclusive lock on the database directory. Running freshclam manually while this service is active causes a lock conflict. Stop the service with sudo systemctl stop clamav-freshclam, run the manual update, then restart the service.

15%

Save 15% on All Hosting Services

Test your skills and get Discount on any hosting plan

Use code:

Skills
Get Started