How to Install ClamAV Antivirus on RHEL 7
ClamAV is the leading open-source antivirus engine used on Linux servers, primarily for scanning files shared with Windows clients, email attachments passing through mail gateways, and uploaded content on web servers. While RHEL 7 itself is rarely the target of self-propagating malware, compliance frameworks such as PCI-DSS, HIPAA, and SOC 2 often require antivirus software on all servers regardless of platform. This guide covers installing ClamAV and its database updater from EPEL, configuring freshclam for automatic signature updates, setting up the clamd daemon, running on-demand scans, scheduling regular scans via cron, configuring on-access scanning with clamonacc, and handling quarantine of infected files.
Prerequisites
- RHEL 7 server with root or
sudoaccess - EPEL repository enabled
- Internet access to download virus signature databases from
database.clamav.net - Sufficient disk space: the virus database alone is 200–300 MB
- SELinux in enforcing mode — ClamAV has good SELinux support on RHEL 7
Step 1: Install ClamAV from EPEL
Enable EPEL if not already enabled, then install the core packages:
sudo yum install -y epel-release
sudo yum install -y clamav clamav-update clamav-scanner-systemd clamav-server clamav-server-systemd clamav-filesystem
The key packages and their roles:
clamav— theclamscancommand-line scannerclamav-update— thefreshclamdatabase updaterclamav-scanner-systemd— systemd unit for the scannerclamav-server-systemd— systemd unit for the daemon (clamd)clamav-filesystem— creates directory structure and theclamscanuser
Step 2: Configure freshclam for Signature Updates
freshclam downloads and keeps the virus signature databases current. On a fresh EPEL install, it is blocked from running by a comment directive. Remove the block:
sudo sed -i 's/^Example/#Example/' /etc/freshclam.conf
Review and adjust the configuration:
sudo vi /etc/freshclam.conf
Key settings to verify or change:
# Database directory (default is correct on RHEL 7)
DatabaseDirectory /var/lib/clamav
# Log freshclam updates
UpdateLogFile /var/log/freshclam.log
LogVerbose yes
LogTime yes
# Check for updates 12 times per day (every 2 hours)
Checks 12
# Mirror server
DatabaseMirror database.clamav.net
# Notify clamd when the database is updated
NotifyClamd /etc/clamd.d/scan.conf
Run the first manual update to download the databases (this downloads several hundred MB):
sudo freshclam
Expected output will show main.cvd, daily.cvd, and bytecode.cvd being downloaded or updated. Enable freshclam to run as a service:
sudo systemctl enable clamav-freshclam
sudo systemctl start clamav-freshclam
sudo systemctl status clamav-freshclam
Step 3: Configure the clamd Daemon
The clamd daemon runs as a persistent service and scans files much faster than invoking clamscan because it keeps the virus database loaded in memory. The RHEL 7 EPEL package uses a multi-instance model — the configuration lives in /etc/clamd.d/scan.conf:
sudo sed -i 's/^Example/#Example/' /etc/clamd.d/scan.conf
sudo vi /etc/clamd.d/scan.conf
Important directives:
# Daemon user — must match the service unit's User= setting
User clamscan
# Local socket for client connections
LocalSocket /var/run/clamd.scan/clamd.sock
LocalSocketMode 660
# TCP socket (optional, for network scanning)
# TCPSocket 3310
# TCPAddr 127.0.0.1
# Log settings
LogFile /var/log/clamd.scan
LogFileMaxSize 100M
LogTime yes
LogVerbose no
# Scan settings
MaxScanSize 200M
MaxFileSize 100M
MaxRecursion 16
MaxFiles 10000
# Scan inside archives
ScanArchive yes
ScanMail yes
ScanPDF yes
ScanHTML yes
FollowDirectorySymlinks no
FollowFileSymlinks no
# Do not scan network filesystems (avoid performance issues)
# ScanELF yes
Set correct SELinux context on the log file and socket directory:
sudo touch /var/log/clamd.scan
sudo chown clamscan:clamscan /var/log/clamd.scan
sudo setsebool -P antivirus_can_scan_system 1
sudo setsebool -P clamd_use_jit 1
Step 4: Start and Enable clamd
The EPEL systemd unit for this configuration instance is clamd@scan:
sudo systemctl enable clamd@scan
sudo systemctl start clamd@scan
sudo systemctl status clamd@scan
The startup will take 30–60 seconds while clamd loads the signature databases into memory. Confirm the socket exists:
ls -la /var/run/clamd.scan/
Check the startup log for errors:
sudo journalctl -u clamd@scan -n 30 --no-pager
Step 5: On-Demand Scanning with clamscan
clamscan invokes the scanner directly without the daemon. It is slower but useful for one-off scans. Scan a specific directory:
# Scan /home recursively, show infected files, ring bell on find
sudo clamscan -r --bell -i /home
# Scan and log results
sudo clamscan -r -i --log=/var/log/clamav_scan_$(date +%F).log /var/www/html
For faster scanning using the running daemon, use clamdscan:
sudo clamdscan --multiscan --fdpass /var/www/html
The --multiscan flag parallelizes scanning across multiple threads, and --fdpass passes file descriptors to the daemon so it can scan files the clamscan user would not otherwise be able to read.
Step 6: Schedule Automated Scanning with Cron
Set up a nightly scan that logs results and emails a summary if infections are found. Create a cron job:
sudo vi /etc/cron.d/clamav-scan
# Run a full scan of /var/www at 2:30 AM daily
# Mail results to root if any infections are found
30 2 * * * root /usr/bin/clamdscan --multiscan --fdpass --infected
--log=/var/log/clamav-daily-$(date +%F).log /var/www &&
grep -q FOUND /var/log/clamav-daily-$(date +%F).log &&
mail -s "ClamAV: Infected files found on $(hostname)" root
< /var/log/clamav-daily-$(date +%F).log
Alternatively, create a dedicated scan script for more control:
sudo vi /usr/local/bin/clamav-scan.sh
#!/bin/bash
LOGFILE="/var/log/clamav/scan-$(date +%Y%m%d-%H%M%S).log"
SCAN_DIR="/var/www /home /tmp"
QUARANTINE="/var/quarantine"
mkdir -p "$QUARANTINE" /var/log/clamav
/usr/bin/clamdscan --multiscan --fdpass --infected
--move="$QUARANTINE"
--log="$LOGFILE"
$SCAN_DIR
if grep -q "FOUND" "$LOGFILE"; then
mail -s "ClamAV Alert: Infections found on $(hostname -f)" root < "$LOGFILE"
fi
# Remove scan logs older than 30 days
find /var/log/clamav/ -name "scan-*.log" -mtime +30 -delete
sudo chmod 750 /usr/local/bin/clamav-scan.sh
Step 7: Configure On-Access Scanning with clamonacc
On-access scanning intercepts file operations at the kernel level using fanotify and scans files as they are opened or created. This is available in ClamAV 0.102+ which ships in EPEL for RHEL 7:
sudo vi /etc/clamd.d/scan.conf
Add or uncomment these lines:
# Enable on-access scanning
OnAccessMountPath /home
OnAccessMountPath /var/www
OnAccessExcludeUname clamscan
OnAccessExcludeUID 0
OnAccessPrevention yes
OnAccessExtraScanning yes
Restart clamd and launch clamonacc:
sudo systemctl restart clamd@scan
sudo clamonacc --log=/var/log/clamonacc.log --move=/var/quarantine &
Add clamonacc startup to rc.local for persistence, or create a systemd unit for it.
Step 8: Quarantine and Remediation
Create a quarantine directory with restricted permissions:
sudo mkdir -p /var/quarantine
sudo chmod 700 /var/quarantine
sudo chown root:root /var/quarantine
To move infected files automatically during a scan:
sudo clamdscan --fdpass --move=/var/quarantine /path/to/scan
List quarantined files:
sudo ls -la /var/quarantine/
After reviewing a quarantined file to confirm it is malicious, remove it permanently:
sudo rm -f /var/quarantine/infected-filename
Check overall signature database currency:
sudo clamdscan --version
sudo freshclam --version
ClamAV on RHEL 7 provides a solid antivirus layer when properly configured with daily signature updates via freshclam, persistent daemon scanning via clamd@scan, and scheduled full-system scans via cron. The quarantine approach ensures infected files are isolated immediately rather than deleted, giving administrators time to investigate before permanent removal. For mail gateways, integrate ClamAV with Postfix via clamav-milter or Amavisd-new for real-time email scanning. Keep ClamAV updated with yum update clamav* regularly — the scanning engine itself receives security updates, not just the signature databases.