ClamAV is an open-source antivirus engine widely used on Linux servers to detect malware in files destined for Windows users — such as email attachments, uploaded documents, and shared network storage. While Linux systems are largely immune to the Windows malware that ClamAV detects, running it is a responsible practice wherever Linux servers act as intermediaries for files that Windows or macOS clients will open. On RHEL 9, ClamAV is available through the EPEL repository and can be configured for both on-demand and real-time scanning. This tutorial covers installation, virus database updates, scheduled scans, and on-access scanning.
Prerequisites
- A RHEL 9 server with root or sudo access
- EPEL repository enabled (
sudo dnf install -y epel-release) - Internet access on the server for downloading virus definitions
Step 1 — Install ClamAV and the Updater
sudo dnf install -y epel-release
sudo dnf install -y clamav clamav-update clamd
Verify the installed versions:
clamscan --version
freshclam --version
Step 2 — Update the Virus Definition Database
ClamAV’s signature database must be current before the first scan. The freshclam utility downloads updates from the ClamAV mirrors. On a freshly installed system, SELinux may need to allow the freshclam service, so temporarily run it manually first:
# Remove the example config comment that blocks freshclam
sudo sed -i 's/^Example$/#Example/' /etc/freshclam.conf
# Run a manual update
sudo freshclam
You should see output confirming that main.cvd, daily.cvd, and bytecode.cvd were downloaded or are up to date. Enable the freshclam service for automatic background updates:
sudo systemctl enable --now clamav-freshclam
sudo systemctl status clamav-freshclam
Step 3 — Run an On-Demand Scan
Use clamscan for immediate, one-off directory scans. The -r flag enables recursive scanning, --infected limits output to infected files only, and --remove automatically deletes detected threats (use with caution — prefer --move=/quarantine in production).
# Scan home directories and report infected files
sudo clamscan -r /home --infected --log=/var/log/clamav/manual-scan.log
# Move infected files to a quarantine directory instead of deleting
sudo mkdir -p /quarantine
sudo clamscan -r /var/www/html --infected --move=/quarantine
--log=/var/log/clamav/webscan.log
Step 4 — Configure and Enable the ClamAV Daemon (clamd)
For higher performance scheduled scans, run clamd as a persistent daemon so signature databases stay loaded in memory. Edit the scan configuration:
sudo sed -i 's/^Example$/#Example/' /etc/clamd.d/scan.conf
# Set the socket path (required)
sudo sed -i 's|^#LocalSocket .*|LocalSocket /run/clamd.scan/clamd.sock|'
/etc/clamd.d/scan.conf
Enable and start the daemon:
sudo systemctl enable --now clamd@scan
sudo systemctl status clamd@scan
Use clamdscan (the daemon client) for faster scans after the daemon is running:
sudo clamdscan -r /home --infected
Step 5 — Schedule Automated Daily Scans
Create a simple shell script and schedule it with a systemd timer (preferred over cron on RHEL 9) or a cron job.
sudo nano /usr/local/bin/clamav-daily-scan.sh
#!/bin/bash
LOGFILE=/var/log/clamav/daily-$(date +%F).log
QUARANTINE=/quarantine
mkdir -p "$QUARANTINE"
/usr/bin/clamdscan -r /home /var/www/html
--infected
--move="$QUARANTINE"
--log="$LOGFILE"
# Email report if infected files were found
if grep -q "Infected files: [^0]" "$LOGFILE"; then
mail -s "ClamAV Alert: Infected files found on $(hostname)"
root < "$LOGFILE"
fi
sudo chmod +x /usr/local/bin/clamav-daily-scan.sh
Add a cron entry to run the scan at 2 AM daily:
echo "0 2 * * * root /usr/local/bin/clamav-daily-scan.sh"
| sudo tee /etc/cron.d/clamav-daily
Step 6 — Enable On-Access Scanning with fanotify
ClamAV supports real-time on-access scanning using the Linux fanotify API. Files are scanned as they are opened or executed. Enable it in the scan config:
sudo nano /etc/clamd.d/scan.conf
Add or uncomment these directives:
ScanOnAccess yes
OnAccessMountPath /home
OnAccessMountPath /var/www/html
OnAccessExcludeUname clamav
OnAccessPrevention yes
Restart the daemon to apply:
sudo systemctl restart clamd@scan
Note: OnAccessPrevention yes blocks access to infected files in real time. Test this carefully in a staging environment before enabling it on production systems, as false positives could block legitimate files.
Conclusion
ClamAV on RHEL 9 provides a layered approach to malware detection: freshclam keeps virus definitions current, clamd offers fast daemon-based scanning, automated cron jobs ensure nothing is missed overnight, and fanotify on-access scanning catches threats in real time. While the Linux malware landscape differs significantly from Windows, any server that handles file uploads, serves email, or acts as a file share for mixed-OS environments benefits from ClamAV’s presence. Regularly review scan logs in /var/log/clamav/ and keep the freshclam service running to maintain up-to-date protection.
Next steps: How to Configure SELinux on RHEL 9, How to Harden SSH on RHEL 9, and How to Configure Postfix for Outbound Email Alerts on RHEL 9.