Set up ClamAV daemon for real-time malware detection with automated scanning schedules, email notifications for threats, and optimized performance settings for production servers.
Prerequisites
- Root or sudo access
- Mail server (Postfix) for notifications
- Minimum 2GB RAM for optimal performance
- Network connectivity for virus definition updates
What this solves
ClamAV provides enterprise-grade antivirus protection for Linux servers, detecting malware, viruses, and suspicious files through signature-based scanning. This tutorial configures the ClamAV daemon with automated scanning schedules using systemd timers, email notifications for threat detection, and performance optimizations for production environments. You'll establish comprehensive malware protection that runs continuously in the background while maintaining system performance.
Step-by-step installation
Update system packages
Start by updating your package manager to ensure you get the latest security patches and ClamAV version.
sudo apt update && sudo apt upgrade -y
Install ClamAV and components
Install ClamAV daemon, command-line scanner, and update utilities for comprehensive antivirus protection.
sudo apt install -y clamav clamav-daemon clamav-freshclam clamav-unofficial-sigs
Install mail utilities for alerts
Install mail transfer agent and utilities to send email notifications when threats are detected.
sudo apt install -y postfix mailutils
Stop services for initial configuration
Stop ClamAV services to perform initial configuration and virus database updates safely.
sudo systemctl stop clamav-freshclam
sudo systemctl stop clamav-daemon
Update virus definitions
Download the latest virus signatures and malware definitions before starting the daemon.
sudo freshclam
Configure ClamAV daemon settings
Optimize ClamAV daemon configuration for performance and security scanning capabilities.
# Logging configuration
LogFile /var/log/clamav/clamav.log
LogTime yes
LogFileMaxSize 100M
LogRotate yes
LogVerbose yes
Network configuration
TCPSocket 3310
TCPAddr 127.0.0.1
Performance settings
MaxThreads 4
MaxQueue 200
IdleTimeout 120
Scanning options
ScanPDF yes
ScanSWF yes
ScanXMLDOCS yes
ScanHWP3 yes
ScanOLE2 yes
ScanHTML yes
ScanArchive yes
ArchiveBlockEncrypted no
Size limits
MaxScanSize 150M
MaxFileSize 50M
MaxRecursion 10
MaxFiles 15000
MaxEmbeddedPE 40M
MaxHTMLNormalize 40M
MaxHTMLNoTags 8M
MaxScriptNormalize 20M
MaxZipTypeRcg 1M
Threat detection
DetectPUA yes
DetectBrokenExecutables yes
HeuristicScanPrecedence yes
StructuredDataDetection yes
Exclude common false positives
ExcludePath ^/proc/
ExcludePath ^/sys/
ExcludePath ^/dev/
ExcludePath ^/var/lib/clamav/
User and permissions
User clamav
AllowAllMatchScan yes
Foreground no
PidFile /run/clamav/clamd.pid
LocalSocket /run/clamav/clamd.ctl
Configure automatic updates
Set up freshclam to automatically update virus definitions with optimized scheduling.
# Database mirror configuration
DatabaseMirror db.local.clamav.net
DatabaseMirror database.clamav.net
Update frequency (24 checks per day)
Checks 24
UpdateLogFile /var/log/clamav/freshclam.log
LogVerbose yes
LogTime yes
LogFileMaxSize 50M
LogRotate yes
Notification settings
OnUpdateExecute /usr/local/bin/clamav-notify-update.sh
OnErrorExecute /usr/local/bin/clamav-error-notify.sh
Download settings
MaxAttempts 3
DNSDatabaseInfo current.cvd.clamav.net
ConnectTimeout 60
ReceiveTimeout 60
Run as user
DatabaseOwner clamav
PidFile /run/clamav/freshclam.pid
Create notification scripts
Set up email notification scripts for virus database updates and scanning alerts.
sudo mkdir -p /usr/local/bin
sudo chmod 755 /usr/local/bin
#!/bin/bash
echo "ClamAV virus database updated successfully at $(date)" | \
mail -s "[$(hostname)] ClamAV Database Update" admin@example.com
#!/bin/bash
echo "ClamAV database update failed at $(date). Please check /var/log/clamav/freshclam.log" | \
mail -s "[$(hostname)] ClamAV Update ERROR" admin@example.com
sudo chmod 755 /usr/local/bin/clamav-notify-update.sh
sudo chmod 755 /usr/local/bin/clamav-error-notify.sh
Create scanning script with threat alerts
Develop a comprehensive scanning script that sends detailed email notifications when threats are detected.
#!/bin/bash
Configuration
EMAIL="admin@example.com"
LOGFILE="/var/log/clamav/scan.log"
SCAN_DIRS=("/home" "/var/www" "/opt" "/srv")
QUARANTINE_DIR="/var/quarantine/clamav"
Create quarantine directory
mkdir -p "$QUARANTINE_DIR"
chmod 700 "$QUARANTINE_DIR"
chown clamav:clamav "$QUARANTINE_DIR"
Start scan log entry
echo "[$(date)] Starting ClamAV system scan" >> "$LOGFILE"
Scan each directory
INFECTED_FILES=()
for dir in "${SCAN_DIRS[@]}"; do
if [[ -d "$dir" ]]; then
echo "[$(date)] Scanning $dir" >> "$LOGFILE"
SCAN_OUTPUT=$(clamdscan --multiscan --fdpass "$dir" 2>&1)
echo "$SCAN_OUTPUT" >> "$LOGFILE"
# Check for infections
INFECTED=$(echo "$SCAN_OUTPUT" | grep " FOUND" | awk '{print $1}')
if [[ -n "$INFECTED" ]]; then
while IFS= read -r file; do
INFECTED_FILES+=("$file")
done <<< "$INFECTED"
fi
fi
done
Handle infected files
if [[ ${#INFECTED_FILES[@]} -gt 0 ]]; then
echo "[$(date)] THREAT DETECTED: ${#INFECTED_FILES[@]} infected files found" >> "$LOGFILE"
# Quarantine infected files
for file in "${INFECTED_FILES[@]}"; do
if [[ -f "$file" ]]; then
BASENAME=$(basename "$file")
QUARANTINE_FILE="$QUARANTINE_DIR/${BASENAME}.$(date +%Y%m%d-%H%M%S)"
mv "$file" "$QUARANTINE_FILE" 2>/dev/null
echo "[$(date)] Quarantined: $file -> $QUARANTINE_FILE" >> "$LOGFILE"
fi
done
# Send threat notification email
{
echo "SECURITY ALERT: ClamAV detected malware on $(hostname)"
echo ""
echo "Date: $(date)"
echo "Infected files found: ${#INFECTED_FILES[@]}"
echo ""
echo "Infected files (now quarantined):"
printf '%s\n' "${INFECTED_FILES[@]}"
echo ""
echo "Files have been moved to: $QUARANTINE_DIR"
echo ""
echo "Full scan log: $LOGFILE"
echo ""
echo "Please investigate immediately and run additional security checks."
} | mail -s "[SECURITY] Malware detected on $(hostname)" "$EMAIL"
else
echo "[$(date)] Scan completed - no threats detected" >> "$LOGFILE"
fi
sudo chmod 755 /usr/local/bin/clamav-scan.sh
Set up log rotation
Configure logrotate to manage ClamAV log files and prevent disk space issues.
/var/log/clamav/*.log {
daily
missingok
rotate 14
compress
delaycompress
copytruncate
create 644 clamav clamav
postrotate
/bin/kill -HUP cat /run/clamav/clamd.pid 2>/dev/null 2>/dev/null || true
endscript
}
Create systemd timer for automated scanning
Set up systemd service and timer units for automated daily malware scanning.
[Unit]
Description=ClamAV System Scan
Requires=clamav-daemon.service
After=clamav-daemon.service
[Service]
Type=oneshot
User=root
ExecStart=/usr/local/bin/clamav-scan.sh
StandardOutput=journal
StandardError=journal
[Unit]
Description=Run ClamAV scan daily at 2 AM
Requires=clamav-scan.service
[Timer]
OnCalendar=daily
AccuracySec=1h
Persistent=true
RandomizedDelaySec=1800
[Install]
WantedBy=timers.target
Create log directories and set permissions
Ensure proper log directory structure with correct ownership for ClamAV operations.
sudo mkdir -p /var/log/clamav
sudo mkdir -p /var/quarantine/clamav
sudo chown clamav:clamav /var/log/clamav
sudo chown clamav:clamav /var/quarantine/clamav
sudo chmod 755 /var/log/clamav
sudo chmod 700 /var/quarantine/clamav
Enable and start ClamAV services
Start ClamAV daemon and freshclam services, then enable the automated scanning timer.
sudo systemctl enable --now clamav-freshclam
sudo systemctl enable --now clamav-daemon
sudo systemctl enable --now clamav-scan.timer
sudo systemctl daemon-reload
Configure firewall rules
Set up firewall rules to allow ClamAV daemon access while maintaining security. Similar to network security hardening discussed in our Linux firewall configuration tutorial.
sudo ufw allow from 127.0.0.1 to any port 3310
sudo ufw reload
Performance optimization and exclusions
Configure performance-based exclusions
Add directory exclusions for system paths and high-I/O areas to improve scanning performance.
# Add these exclusions to the existing configuration
Temporary and cache directories
ExcludePath ^/tmp/
ExcludePath ^/var/tmp/
ExcludePath ^/var/cache/
Database directories (if applicable)
ExcludePath ^/var/lib/mysql/
ExcludePath ^/var/lib/postgresql/
ExcludePath ^/var/lib/redis/
Log directories
ExcludePath ^/var/log/
Container runtime directories
ExcludePath ^/var/lib/docker/
ExcludePath ^/var/lib/containerd/
Backup directories (scan separately if needed)
ExcludePath ^/backup/
ExcludePath ^/var/backups/
Optimize memory usage
Configure memory limits and threading for optimal performance on your system resources.
# Check available memory
free -h
Adjust MaxThreads based on CPU cores
nproc
# Memory optimization (adjust based on available RAM)
For systems with 4GB+ RAM
MaxThreads 4
MaxQueue 200
For systems with 2GB RAM
MaxThreads 2
MaxQueue 100
For systems with 8GB+ RAM
MaxThreads 8
MaxQueue 400
Verify your setup
# Check ClamAV daemon status
sudo systemctl status clamav-daemon
Check freshclam update service
sudo systemctl status clamav-freshclam
Verify scanning timer is active
sudo systemctl status clamav-scan.timer
sudo systemctl list-timers clamav-scan.timer
Test daemon connectivity
clamdscan --version
echo "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*" > /tmp/eicar.txt
clamdscan /tmp/eicar.txt
rm -f /tmp/eicar.txt
Check recent logs
sudo tail -f /var/log/clamav/clamav.log
sudo tail -f /var/log/clamav/freshclam.log
Verify quarantine directory
ls -la /var/quarantine/clamav/
Monitor scan logs and quarantine management
Set up log monitoring script
Create a monitoring script to track scanning statistics and system health.
#!/bin/bash
echo "=== ClamAV System Status ==="
echo "Date: $(date)"
echo ""
echo "Service Status:"
systemctl is-active clamav-daemon
systemctl is-active clamav-freshclam
systemctl is-active clamav-scan.timer
echo ""
echo "Database Information:"
sigtool --info /var/lib/clamav/main.cvd | head -5
sigtool --info /var/lib/clamav/daily.cvd | head -5
echo ""
echo "Recent Scan Activity (last 10 entries):"
tail -10 /var/log/clamav/scan.log | grep "\[.*\]"
echo ""
echo "Quarantined Files:"
ls -la /var/quarantine/clamav/ | wc -l
echo "files in quarantine"
echo ""
echo "Memory Usage:"
ps aux | grep -E "(clamd|freshclam)" | grep -v grep
sudo chmod 755 /usr/local/bin/clamav-status.sh
Create quarantine management script
Develop a script for safely managing quarantined files and reviewing threats.
#!/bin/bash
QUARANTINE_DIR="/var/quarantine/clamav"
LOG_FILE="/var/log/clamav/quarantine.log"
case "$1" in
list)
echo "Quarantined files:"
ls -la "$QUARANTINE_DIR"
;;
clean)
echo "Cleaning quarantine older than 30 days..."
find "$QUARANTINE_DIR" -type f -mtime +30 -exec rm {} \;
echo "[$(date)] Cleaned old quarantine files" >> "$LOG_FILE"
;;
restore)
if [[ -z "$2" ]]; then
echo "Usage: $0 restore "
exit 1
fi
RESTORE_FILE="$QUARANTINE_DIR/$2"
if [[ -f "$RESTORE_FILE" ]]; then
echo "Restoring $2 to /tmp/ for analysis"
cp "$RESTORE_FILE" "/tmp/$2.restored"
echo "[$(date)] Restored $2 to /tmp/ for analysis" >> "$LOG_FILE"
else
echo "File not found in quarantine"
fi
;;
*)
echo "Usage: $0 {list|clean|restore }"
echo " list - Show quarantined files"
echo " clean - Remove files older than 30 days"
echo " restore - Copy file to /tmp for analysis"
;;
esac
sudo chmod 755 /usr/local/bin/clamav-quarantine.sh
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Daemon won't start | Configuration syntax error | sudo clamconf -n to check config validity |
| Database update fails | Network connectivity or mirror issues | Check /var/log/clamav/freshclam.log and test ping database.clamav.net |
| High CPU usage during scan | Too many scan threads for system | Reduce MaxThreads in /etc/clamav/clamd.conf |
| Permission denied errors | Incorrect file ownership | sudo chown -R clamav:clamav /var/log/clamav |
| Email notifications not working | Postfix not configured properly | Test with echo "test" | mail -s "test" admin@example.com |
| Large files not scanned | Size limits too restrictive | Increase MaxScanSize and MaxFileSize in config |
| Scan taking too long | No exclusions for system directories | Add appropriate ExcludePath entries for system dirs |
| Socket connection refused | ClamAV daemon not running | sudo systemctl restart clamav-daemon |
Next steps
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Global variables
ADMIN_EMAIL=""
SCRIPT_DIR="/usr/local/bin"
CLAMAV_LOG_DIR="/var/log/clamav"
# Print colored output
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Usage function
usage() {
echo "Usage: $0 <admin_email>"
echo "Example: $0 admin@example.com"
exit 1
}
# Cleanup function
cleanup() {
print_error "Script failed. Attempting cleanup..."
systemctl stop clamav-daemon 2>/dev/null || true
systemctl stop clamav-freshclam 2>/dev/null || true
exit 1
}
# Set error trap
trap cleanup ERR
# Check arguments
if [ $# -ne 1 ]; then
usage
fi
ADMIN_EMAIL="$1"
# Validate email format
if ! echo "$ADMIN_EMAIL" | grep -qE '^[^@]+@[^@]+\.[^@]+$'; then
print_error "Invalid email format: $ADMIN_EMAIL"
exit 1
fi
# Check if running as root
if [ "$EUID" -ne 0 ]; then
print_error "This script must be run as root"
exit 1
fi
# Detect distribution
echo "[1/12] Detecting distribution..."
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_UPDATE="apt update"
PKG_INSTALL="apt install -y"
PKG_UPGRADE="apt upgrade -y"
FRESHCLAM_SERVICE="clamav-freshclam"
DAEMON_SERVICE="clamav-daemon"
CLAMD_CONF="/etc/clamav/clamd.conf"
FRESHCLAM_CONF="/etc/clamav/freshclam.conf"
MAIL_PKG="postfix mailutils"
CLAMAV_PKGS="clamav clamav-daemon clamav-freshclam"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_UPDATE="dnf update -y"
PKG_INSTALL="dnf install -y"
PKG_UPGRADE="dnf upgrade -y"
FRESHCLAM_SERVICE="clamav-freshclam"
DAEMON_SERVICE="clamd@scan"
CLAMD_CONF="/etc/clamd.d/scan.conf"
FRESHCLAM_CONF="/etc/freshclam.conf"
MAIL_PKG="postfix mailx"
CLAMAV_PKGS="clamav clamav-update clamd"
# Enable EPEL for additional packages
$PKG_INSTALL epel-release
;;
amzn)
PKG_MGR="yum"
PKG_UPDATE="yum update -y"
PKG_INSTALL="yum install -y"
PKG_UPGRADE="yum upgrade -y"
FRESHCLAM_SERVICE="clamav-freshclam"
DAEMON_SERVICE="clamd@scan"
CLAMD_CONF="/etc/clamd.d/scan.conf"
FRESHCLAM_CONF="/etc/freshclam.conf"
MAIL_PKG="postfix mailx"
CLAMAV_PKGS="clamav clamav-update clamd"
;;
*)
print_error "Unsupported distribution: $ID"
exit 1
;;
esac
print_status "Detected: $PRETTY_NAME"
else
print_error "Cannot detect distribution"
exit 1
fi
# Update system packages
echo "[2/12] Updating system packages..."
$PKG_UPDATE
$PKG_UPGRADE
# Install ClamAV packages
echo "[3/12] Installing ClamAV packages..."
$PKG_INSTALL $CLAMAV_PKGS
# Install mail utilities
echo "[4/12] Installing mail utilities..."
$PKG_INSTALL $MAIL_PKG
# Stop services for configuration
echo "[5/12] Stopping ClamAV services..."
systemctl stop $FRESHCLAM_SERVICE 2>/dev/null || true
systemctl stop $DAEMON_SERVICE 2>/dev/null || true
# Create log directory
echo "[6/12] Creating log directories..."
mkdir -p $CLAMAV_LOG_DIR
chown clamav:clamav $CLAMAV_LOG_DIR
chmod 755 $CLAMAV_LOG_DIR
# Update virus definitions
echo "[7/12] Updating virus definitions (this may take several minutes)..."
freshclam
# Configure ClamAV daemon
echo "[8/12] Configuring ClamAV daemon..."
if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then
# Remove Comment lines for Debian/Ubuntu
sed -i 's/^Example/#Example/' $CLAMD_CONF
fi
cat > $CLAMD_CONF << EOF
LogFile $CLAMAV_LOG_DIR/clamav.log
LogTime yes
LogFileMaxSize 100M
LogRotate yes
LogVerbose yes
TCPSocket 3310
TCPAddr 127.0.0.1
MaxThreads 4
MaxQueue 200
IdleTimeout 120
ScanPDF yes
ScanSWF yes
ScanXMLDOCS yes
ScanHWP3 yes
ScanOLE2 yes
ScanHTML yes
ScanArchive yes
ArchiveBlockEncrypted no
MaxScanSize 150M
MaxFileSize 50M
MaxRecursion 10
MaxFiles 15000
MaxEmbeddedPE 40M
MaxHTMLNormalize 40M
MaxHTMLNoTags 8M
MaxScriptNormalize 20M
MaxZipTypeRcg 1M
DetectPUA yes
DetectBrokenExecutables yes
HeuristicScanPrecedence yes
StructuredDataDetection yes
ExcludePath ^/proc/
ExcludePath ^/sys/
ExcludePath ^/dev/
ExcludePath ^/var/lib/clamav/
User clamav
AllowAllMatchScan yes
Foreground no
EOF
if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then
echo "PidFile /run/clamav/clamd.pid" >> $CLAMD_CONF
echo "LocalSocket /run/clamav/clamd.ctl" >> $CLAMD_CONF
else
echo "PidFile /run/clamd.scan/clamd.pid" >> $CLAMD_CONF
echo "LocalSocket /run/clamd.scan/clamd.sock" >> $CLAMD_CONF
fi
# Configure freshclam
echo "[9/12] Configuring automatic updates..."
if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then
sed -i 's/^Example/#Example/' $FRESHCLAM_CONF
fi
cat > $FRESHCLAM_CONF << EOF
DatabaseMirror db.local.clamav.net
DatabaseMirror database.clamav.net
Checks 24
UpdateLogFile $CLAMAV_LOG_DIR/freshclam.log
LogVerbose yes
LogTime yes
LogFileMaxSize 50M
LogRotate yes
OnUpdateExecute $SCRIPT_DIR/clamav-notify-update.sh
OnErrorExecute $SCRIPT_DIR/clamav-error-notify.sh
MaxAttempts 3
DNSDatabaseInfo current.cvd.clamav.net
ConnectTimeout 60
ReceiveTimeout 60
DatabaseOwner clamav
PidFile /run/clamav/freshclam.pid
EOF
# Create notification scripts
echo "[10/12] Creating notification scripts..."
mkdir -p $SCRIPT_DIR
cat > $SCRIPT_DIR/clamav-notify-update.sh << EOF
#!/bin/bash
echo "ClamAV virus database updated successfully at \$(date)" | \\
mail -s "[\$(hostname)] ClamAV Database Update" $ADMIN_EMAIL
EOF
cat > $SCRIPT_DIR/clamav-error-notify.sh << EOF
#!/bin/bash
echo "ClamAV error occurred at \$(date). Check logs at $CLAMAV_LOG_DIR/" | \\
mail -s "[\$(hostname)] ClamAV ERROR" $ADMIN_EMAIL
EOF
cat > $SCRIPT_DIR/clamav-scan-alert.sh << EOF
#!/bin/bash
LOGFILE="$CLAMAV_LOG_DIR/scan.log"
if [ -f "\$LOGFILE" ]; then
THREATS=\$(tail -100 "\$LOGFILE" | grep "FOUND" | tail -10)
if [ ! -z "\$THREATS" ]; then
echo -e "Threats detected on \$(hostname) at \$(date):\\n\\n\$THREATS" | \\
mail -s "[\$(hostname)] VIRUS ALERT" $ADMIN_EMAIL
fi
fi
EOF
chmod 755 $SCRIPT_DIR/clamav-*.sh
chown root:root $SCRIPT_DIR/clamav-*.sh
# Start and enable services
echo "[11/12] Starting and enabling ClamAV services..."
systemctl enable $FRESHCLAM_SERVICE
systemctl enable $DAEMON_SERVICE
systemctl start $FRESHCLAM_SERVICE
systemctl start $DAEMON_SERVICE
# Create systemd timer for regular scans
cat > /etc/systemd/system/clamav-scan.service << EOF
[Unit]
Description=ClamAV virus scan
After=network.target
[Service]
Type=oneshot
ExecStart=/bin/bash -c 'clamscan -r --bell -i / --exclude-dir=^/sys --exclude-dir=^/proc --exclude-dir=^/dev --log=$CLAMAV_LOG_DIR/scan.log && $SCRIPT_DIR/clamav-scan-alert.sh'
User=root
EOF
cat > /etc/systemd/system/clamav-scan.timer << EOF
[Unit]
Description=Run ClamAV scan daily
Requires=clamav-scan.service
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl enable clamav-scan.timer
systemctl start clamav-scan.timer
# Verification
echo "[12/12] Verifying installation..."
sleep 5
if systemctl is-active --quiet $DAEMON_SERVICE; then
print_status "ClamAV daemon is running"
else
print_error "ClamAV daemon failed to start"
exit 1
fi
if systemctl is-active --quiet $FRESHCLAM_SERVICE; then
print_status "ClamAV freshclam service is running"
else
print_error "ClamAV freshclam service failed to start"
exit 1
fi
if systemctl is-active --quiet clamav-scan.timer; then
print_status "ClamAV scan timer is active"
else
print_error "ClamAV scan timer failed to start"
exit 1
fi
# Test virus scanning
echo "Testing virus signature detection..."
echo 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*' > /tmp/eicar.com
if clamscan /tmp/eicar.com | grep -q "FOUND"; then
print_status "Virus detection test passed"
rm -f /tmp/eicar.com
else
print_warning "Virus detection test failed"
fi
print_status "ClamAV installation completed successfully!"
print_status "Email notifications will be sent to: $ADMIN_EMAIL"
print_status "Daily scans scheduled via systemd timer"
print_status "Log files location: $CLAMAV_LOG_DIR"
Review the script before running. Execute with: bash install.sh