Threat Sentinel -- ClamAV

Slide 1 of 33  |  Week 2  |  Advanced Linux Administration
Threat Sentinel
ClamAV Antivirus
Architecture  •  Installation  •  Signatures  •  On-Access Scanning  •  Scheduled Scans  •  Quarantine
Operational directive: deploy automated threat detection inside your cell. Files transit your server. Users upload content. Malware rides inside archives, documents, and executables. ClamAV is the open-source sentinel that watches for them.
33 Slides Week 2 Topic 3 Ubuntu 22.04 ClamAV 0.103+
Slide 2 of 33
Why Antivirus on Linux?
Linux systems are not malware-immune. The threat model differs -- the need is real.
Linux Malware Exists
Ransomware targeting Linux servers (RansomEXX, HelloKitty). Cryptomining malware (XMRig variants). Rootkits. Web shells dropped after web application exploits. Botnets running on compromised Linux hosts. The threat surface is smaller than Windows but the stakes are higher -- servers hold data.
File Transit Scanning
Your Linux mail server, file server, or web upload handler processes files from Windows and macOS clients. A Windows user sends a malware-infected attachment through your mail server. The Linux box is fine -- but every Windows recipient is a victim. Linux AV catches it in transit.
Compliance Requirement
PCI DSS Requirement 5: deploy antivirus on all systems. HIPAA, SOC 2, FedRAMP, and most corporate security policies require AV on all hosts. "We run Linux" is not an accepted compliance exemption. ClamAV satisfies the requirement and is free.
ClamAV Position in Your Stack
ClamAV is detection, not prevention. It finds malware that has already arrived. It works with your firewall (which stops unwanted connections), fail2ban (which stops brute force), and file integrity monitoring (which detects file changes) as complementary layers.
Slide 3 of 33
ClamAV Architecture
Two scanning modes, one signature database. Understand the difference before deploying.
clamscan
Command-line scanner. Spawns a new process for each scan job. Loads the entire signature database into memory every run. Simple and scriptable. Suitable for scheduled scans and one-off checks. Resource cost: memory for database load on every invocation.
clamd
The ClamAV daemon. Loads signature database once at startup, stays resident in memory. Clients (clamdscan, Milter, fanotify) connect to clamd via socket to request scans. Much faster for repeated scans. Required for on-access scanning and mail gateway integration.
freshclam
The signature update daemon. Downloads new definitions from ClamAV's mirror network. Runs as a daemon or via cron. Checks for updates multiple times per day. Without regular updates, your AV is effectively blind to new threats. This is a critical service.
FILE SCAN ENGINE SIGNATURE DATABASE OK FOUND
clamdscan
A client for the clamd daemon. Sends scan requests to the already-running clamd process rather than loading the database itself. Result: near-instant scans because database load already happened at daemon start. Use clamdscan instead of clamscan when clamd is running.
clamav-milter
A mail filter that integrates ClamAV with Postfix or Sendmail via the milter protocol. Every incoming email is scanned before delivery. Infected attachments are rejected at the MTA level. Essential for mail servers -- covered in the Mail Server module.
Slide 4 of 33
Installation: ClamAV on Ubuntu 22.04
Install both the scanner and the daemon, then perform the initial signature download.
# Install ClamAV packages $ apt update $ apt install clamav clamav-daemon # Package breakdown: # clamav -- clamscan CLI scanner + freshclam updater # clamav-daemon -- clamd service + clamdscan client # Ubuntu ships ClamAV with freshclam running as a service # Stop freshclam service before doing manual database update $ systemctl stop clamav-freshclam # Download initial signature database manually $ freshclam ClamAV update process started at Thu Apr 9 10:00:00 2026 main.cvd is up-to-date (version: 62, sigs: 6647427) Downloading daily.cvd... daily.cvd updated (version: 27234, sigs: 2085920) bytecode.cvd updated (version: 334, sigs: 89) # Restart freshclam daemon (keeps signatures updated automatically) $ systemctl start clamav-freshclam $ systemctl enable clamav-freshclam # Verify installed version $ clamscan --version ClamAV 0.103.8/27234/Thu Apr 9 08:00:00 2026
Slide 5 of 33
Signature Database: main, daily, and bytecode
Three database files with different update frequencies and detection capabilities.
main.cvd
The core database. Contains the bulk of historical signatures for known malware families. Updated infrequently (major releases). Downloaded as a complete file, roughly 160 MB. This is the baseline detection foundation -- stable, comprehensive, rarely changes.
daily.cvd
Updated multiple times per day with new signatures for emerging threats. This is the database you keep current through freshclam. When a new malware campaign hits, signatures appear here within hours. The delta files (.cld) replace the full .cvd after the first full download.
bytecode.cvd
Contains bytecode programs that run inside ClamAV's safe execution engine. Used for heuristic and behavioral detection that signature files cannot express. Enables detection of obfuscated or polymorphic malware. Small file, updates frequently.
main.cvd 6.6M sigs ~162 MB daily.cld 2M+ sigs ~67 MB bytecode.cvd 89 sigs ~243 KB /var/lib/clamav/
# Database file locations $ ls -lh /var/lib/clamav/ -rw-r--r-- 1 clamav clamav 162M Apr 9 08:00 main.cvd -rw-r--r-- 1 clamav clamav 67M Apr 9 08:00 daily.cld -rw-r--r-- 1 clamav clamav 243K Apr 9 08:00 bytecode.cld # View database statistics $ sigtool --info /var/lib/clamav/main.cvd # Check freshclam configuration $ cat /etc/clamav/freshclam.conf
Slide 6 of 33
freshclam: Signature Update Configuration
Configure how often signatures update and where they come from.
freshclam DNS lookup MIRROR database .clamav.net LOCAL DB /var/lib/ clamav/ NotifyClamd every 2h
# /etc/clamav/freshclam.conf -- key settings # Number of update checks per day (default 24 = hourly) Checks 12 # check every 2 hours # Mirror to download from (use the official CDN) DatabaseMirror database.clamav.net # Use DNS to find the best mirror automatically DNSDatabaseInfo current.cvd.clamav.net # Log freshclam activity UpdateLogFile /var/log/clamav/freshclam.log LogRotate true # Notify clamd when the database is updated (daemon reloads signatures) NotifyClamd /etc/clamav/clamd.conf # Run freshclam manually and watch output $ freshclam --verbose # Check freshclam log $ tail -20 /var/log/clamav/freshclam.log # freshclam systemd service status $ systemctl status clamav-freshclam
Slide 7 of 33
clamscan: Basic Scanning
Manual scanning from the command line. Know the options before scripting them.
# Scan a single file $ clamscan /tmp/suspicious-file.zip /tmp/suspicious-file.zip: OK ----------- SCAN SUMMARY ----------- Known viruses: 8733347 Scanned files: 1 Infected files: 0 # Scan a directory recursively $ clamscan -r /home/ubuntu/uploads # Useful flags $ clamscan -r # recursive (scan subdirectories) $ clamscan -i # only print infected files (suppress clean results) $ clamscan --remove # delete infected files (DESTRUCTIVE -- use with caution) $ clamscan --move=/quarantine # move infected files to quarantine directory $ clamscan --log=/var/log/clamav/scan.log # write results to log file # Scan only specific file extensions $ clamscan -r --include="*.exe" --include="*.dll" /srv/files # Test detection with the EICAR test string (not real malware) $ echo 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*' > /tmp/eicar.txt $ clamscan /tmp/eicar.txt /tmp/eicar.txt: Eicar-Signature FOUND
Slide 8 of 33
clamd: The Resident Daemon
Configure and start clamd for faster repeated scans and on-access scanning support.
# /etc/clamav/clamd.conf -- key settings # Path to the Unix socket (used by clamdscan and fanotify) LocalSocket /var/run/clamav/clamd.ctl # Allow connections on a TCP port (for network scanning) # TCPSocket 3310 # TCPAddr 127.0.0.1 # Log file for clamd events LogFile /var/log/clamav/clamav.log LogRotate yes LogFileMaxSize 10M # Run as the clamav user User clamav # Maximum file size to scan (files larger than this are skipped) MaxFileSize 25M # Maximum scan size for archives MaxScanSize 100M # Start and enable clamd $ systemctl start clamav-daemon $ systemctl enable clamav-daemon $ systemctl status clamav-daemon # Scan using clamdscan (connects to clamd socket) $ clamdscan /home/ubuntu/uploads
Slide 9 of 33
EICAR Test File: Verifying Detection Works
A standardized test string that all AV products must detect without causing harm.
What EICAR Is
The EICAR Standard Anti-Virus Test File is a 68-character ASCII string agreed upon by the AV industry. It is not malware -- it does nothing harmful. Every AV product detects it as a threat. Use it to verify your scanner is working without creating or using real malware samples.
Detection Signature Name
ClamAV detects it as Eicar-Signature. The exit code when clamscan finds infected files is 1. Exit code 0 means clean. Exit code 2 means error. Your scripts should check exit codes, not just console output.
# Create an EICAR test file (these characters are the actual test string) $ printf 'X5O!P%%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*' > /tmp/eicar.com # Test clamscan detection $ clamscan /tmp/eicar.com /tmp/eicar.com: Eicar-Signature FOUND ----------- SCAN SUMMARY ----------- Infected files: 1 # Test clamdscan detection (daemon must be running) $ clamdscan /tmp/eicar.com /tmp/eicar.com: Eicar-Signature FOUND # Test EICAR inside a zip archive (should still detect) $ zip /tmp/eicar.zip /tmp/eicar.com $ clamscan /tmp/eicar.zip /tmp/eicar.zip: Eicar-Signature FOUND # Clean up test files after verification $ rm /tmp/eicar.com /tmp/eicar.zip
Slide 10 of 33
Scheduled Scans: Cron-Based Automation
Run nightly scans automatically and email results if threats are found.
#!/bin/bash # /usr/local/bin/clamav-nightly-scan.sh # Run a scheduled ClamAV scan with alerting SCAN_DIR="/" QUARANTINE="/var/quarantine" LOG_FILE="/var/log/clamav/nightly-$(date +%Y%m%d).log" ALERT_EMAIL="secops@example.com" EXCLUDE_DIRS="--exclude-dir=/proc --exclude-dir=/sys --exclude-dir=/dev --exclude-dir=/run" # Ensure quarantine directory exists mkdir -p "$QUARANTINE" # Run the scan clamscan -r -i \ --move="$QUARANTINE" \ --log="$LOG_FILE" \ $EXCLUDE_DIRS \ "$SCAN_DIR" RESULT=$? # Exit code 1 = infected files found if [ $RESULT -eq 1 ]; then mail -s "ALERT: ClamAV found threats on $(hostname)" "$ALERT_EMAIL" < "$LOG_FILE" fi
# Schedule in root's crontab: daily at 02:30 $ crontab -e 30 2 * * * /usr/local/bin/clamav-nightly-scan.sh # Make script executable $ chmod 750 /usr/local/bin/clamav-nightly-scan.sh
Slide 11 of 33
Scheduled Scans: systemd Timer Alternative
systemd timers are the modern replacement for cron -- better logging and dependency management.
Why systemd Timers?
Cron has no dependency management, minimal logging, and no resource controls. systemd timers integrate with journald for logging, can depend on network or filesystem mounts, support resource limits via cgroups, and can use calendar expressions or monotonic intervals.
Timer + Service Pair
A systemd timer activates a paired service unit. The timer specifies when. The service specifies what to run. Both files go in /etc/systemd/system/. Enable the timer unit, not the service unit directly.
# /etc/systemd/system/clamav-scan.service [Unit] Description=ClamAV nightly filesystem scan After=clamav-freshclam.service [Service] Type=oneshot User=root ExecStart=/usr/local/bin/clamav-nightly-scan.sh StandardOutput=journal StandardError=journal # /etc/systemd/system/clamav-scan.timer [Unit] Description=ClamAV nightly scan timer [Timer] OnCalendar=*-*-* 02:30:00 # daily at 02:30 Persistent=true # run missed jobs after reboot [Install] WantedBy=timers.target # Enable and start the timer $ systemctl daemon-reload $ systemctl enable --now clamav-scan.timer $ systemctl list-timers | grep clamav
Slide 12 of 33
On-Access Scanning: Real-Time Detection
Scan files the moment they are opened or written -- not just on a schedule.
ON-ACCESS (real-time) open() fanotify kernel API clamd ON-DEMAND (scheduled) cron clamscan files blocks before exec detects after arrival
What On-Access Scanning Does
Intercepts file open and close events at the kernel level using the fanotify Linux kernel API. Every file access is checked against signatures before the application can read it. Threats are blocked before they can execute -- not detected after the fact in a nightly scan.
Performance Trade-off
Every file open on the monitored path triggers a scan. On busy servers with many small file reads (web servers, databases), this adds latency and CPU overhead. Scope on-access scanning carefully -- target high-risk directories (uploads, home directories, /tmp) not the entire filesystem.
fanotify Requirement
On-access scanning requires the fanotify kernel API (Linux 3.8+, Ubuntu 22.04 has 5.15) and clamd running with sufficient permissions. The ClamAV daemon needs access to the directories being watched. The OnAccessExcludePath option prevents recursive loops.
Slide 13 of 33
On-Access Configuration: clamd.conf Settings
Enable on-access scanning and configure which directories to monitor.
# /etc/clamav/clamd.conf -- on-access scanning settings # Enable on-access scanning OnAccessPrevention yes # block (not just alert) on detection OnAccessExtraScanning yes # scan file writes as well as opens # Directories to monitor (can specify multiple) OnAccessIncludePath /var/www/html/uploads OnAccessIncludePath /home OnAccessIncludePath /tmp # Exclude specific paths within monitored directories OnAccessExcludePath /home/clamav # Exclude certain UIDs from scanning (e.g., backup processes) OnAccessExcludeUID 0 # exclude root (prevents clamd from watching itself) # Mount point for on-access monitoring OnAccessMountPath / # monitor the whole filesystem (use with care) # Restart clamd after configuration change $ systemctl restart clamav-daemon $ systemctl status clamav-daemon # Check clamd log for on-access events $ tail -f /var/log/clamav/clamav.log
Slide 14 of 33
Quarantine: Isolating Detected Threats
Move infected files to a secured location rather than deleting them immediately.
INFECTED file ClamAV FOUND --move QUARANTINE chmod 700 root:root ANALYZE PURGE 30d
Why Quarantine vs Delete?
Deleting eliminates evidence needed for forensic analysis. Quarantine preserves the file in an inaccessible location. Security teams can analyze the sample to understand the infection vector. False positives can be recovered from quarantine. Compliance frameworks often require evidence retention.
Quarantine Directory Security
The quarantine directory must be owned by root, not executable by other users, and ideally mounted on a separate filesystem. Malware in quarantine is still malware -- restrict permissions aggressively. The directory should not be world-readable or accessible to the web server.
# Create a secure quarantine directory $ mkdir -p /var/quarantine $ chown root:root /var/quarantine $ chmod 700 /var/quarantine # only root can access # Scan and move infected files to quarantine $ clamscan -r -i --move=/var/quarantine /var/www/uploads # List quarantined files with timestamps $ ls -lah /var/quarantine/ # ClamAV renames moved files to prevent accidental execution # Example: malware.exe becomes malware.exe (no execution permission) $ chmod -x /var/quarantine/* # belt-and-suspenders: strip execute # Remove quarantined files older than 30 days $ find /var/quarantine -mtime +30 -delete
Slide 15 of 33
Alert Scripting: Automated Threat Notification
Parse ClamAV output and send alerts through email, Slack, or syslog when threats are found.
#!/bin/bash # /usr/local/bin/clamav-alert-scan.sh # Scan a directory and alert via multiple channels if threats are found SCAN_TARGET="${1:-/var/www/uploads}" QUARANTINE="/var/quarantine" LOG="/var/log/clamav/alert-$(date +%Y%m%d-%H%M).log" ALERT_EMAIL="secops@example.com" SLACK_WEBHOOK="https://hooks.slack.com/services/YOUR/WEBHOOK/URL" HOSTNAME=$(hostname -f) # Run scan, capture exit code clamscan -r -i --move="$QUARANTINE" --log="$LOG" "$SCAN_TARGET" > /dev/null 2>&1 EXIT_CODE=$? if [ $EXIT_CODE -eq 1 ]; then INFECTED=$(grep "FOUND" "$LOG") COUNT=$(grep -c "FOUND" "$LOG") # Email alert echo "$INFECTED" | mail -s "THREAT: $COUNT malware found on $HOSTNAME" "$ALERT_EMAIL" # Slack webhook alert curl -s -X POST -H 'Content-type: application/json' \ --data "{\"text\":\"THREAT on $HOSTNAME: $COUNT file(s) quarantined\"}" \ "$SLACK_WEBHOOK" # Log to syslog logger -t clamav -p security.crit "$COUNT threats quarantined on $HOSTNAME" fi
Slide 16 of 33
Scan Exclusions: Performance and False Positives
Exclude paths that produce false positives or that should never be scanned.
# Exclude virtual filesystems (scanning these causes errors and waste) $ clamscan -r \ --exclude-dir=^/proc \ --exclude-dir=^/sys \ --exclude-dir=^/dev \ --exclude-dir=^/run \ --exclude-dir=^/snap \ --exclude-dir=^/var/lib/clamav \ --exclude-dir=^/var/quarantine \ / # Exclude specific file extensions (e.g., database files that trigger false positives) $ clamscan -r --exclude="\.db$" --exclude="\.sqlite$" /var/lib # clamd.conf -- exclude directories from on-access scanning OnAccessExcludePath /proc OnAccessExcludePath /sys OnAccessExcludePath /var/lib/clamav OnAccessExcludePath /var/quarantine # Whitelist a false-positive signature (use with extreme care) # Create /etc/clamav/local.ign2 echo "PUA.Win.Tool.Packed-7" > /etc/clamav/local.ign2 # Reload clamd: systemctl reload clamav-daemon
Slide 17 of 33
Interpreting Scan Results
Read the summary report and understand exit codes before building automation on top of them.
# Sample clamscan output with a detection $ clamscan -r /tmp/testdir/ /tmp/testdir/eicar.com: Eicar-Signature FOUND /tmp/testdir/clean.txt: OK /tmp/testdir/readme.pdf: OK ----------- SCAN SUMMARY ----------- Known viruses: 8733347 Engine version: 0.103.8 Scanned directories: 1 Scanned files: 3 Infected files: 1 Data scanned: 0.01 MB Data read: 0.01 MB (ratio 1.00:1) Time: 1.234 sec (0 m 1 s) Start Date: 2026:04:09 10:00:00 End Date: 2026:04:09 10:00:01 # Exit codes # 0 = no infections found, no errors # 1 = virus(es) found # 2 = an error occurred (permissions, corrupt database, etc.) # Use exit codes in scripts clamscan -r /upload; if [ $? -eq 1 ]; then echo "INFECTED"; fi
Slide 18 of 33
ClamAV Log Monitoring
Track detection events, update activity, and errors through the ClamAV log files.
# Log files # /var/log/clamav/clamav.log -- clamd daemon events # /var/log/clamav/freshclam.log -- signature update events # Watch clamd log for real-time detections $ tail -f /var/log/clamav/clamav.log # Sample log entries # Normal operation: # Thu Apr 9 08:00:01 2026 -> ClamAV 0.103.8 loaded # Thu Apr 9 08:00:05 2026 -> ScanOnAccess: Starting scan thread # Detection event: # Thu Apr 9 10:15:03 2026 -> /var/www/uploads/shell.php: Php.Webshell.Generic-1 FOUND # Database update event: # Thu Apr 9 10:30:00 2026 -> ClamAV database updated (sigs: 8733347 -> 8733512) # Extract all FOUND events from the log $ grep "FOUND" /var/log/clamav/clamav.log # Set up logrotate for ClamAV logs # /etc/logrotate.d/clamav-daemon (already provided by package) $ cat /etc/logrotate.d/clamav-daemon
Slide 19 of 33
Web Upload Scanning: Protecting File Upload Endpoints
Integrate ClamAV into your web application upload pipeline to scan files before storage.
A user uploads a ZIP file containing a PHP webshell disguised as an image. Your web app stores it in /var/www/uploads. The attacker navigates to the file URL and now has remote code execution. ClamAV scanning on the upload directory catches the webshell before it can be executed.
USER upload /tmp/ staging clamdscan --quiet CLEAN /var/www/uploads INFECTED /var/quarantine exit 0 exit 1
#!/bin/bash # /usr/local/bin/scan-upload.sh # Called by web app after file upload -- scan before final storage UPLOAD_FILE="$1" FINAL_DIR="$2" QUARANTINE="/var/quarantine" if [ -z "$UPLOAD_FILE" ]; then echo "Usage: scan-upload.sh " exit 2 fi # Scan with clamdscan (fast -- uses running daemon) clamdscan --quiet "$UPLOAD_FILE" SCAN_RESULT=$? if [ $SCAN_RESULT -eq 0 ]; then # Clean -- move to final storage location mv "$UPLOAD_FILE" "$FINAL_DIR/" echo "CLEAN: file stored" exit 0 elif [ $SCAN_RESULT -eq 1 ]; then # Infected -- quarantine and alert mv "$UPLOAD_FILE" "$QUARANTINE/" logger -t clamav -p security.crit "Infected upload quarantined: $UPLOAD_FILE" echo "INFECTED: file quarantined" exit 1 fi
Slide 20 of 33
Custom Signatures: Writing Your Own Detection Rules
Create signatures for threats specific to your environment that official databases do not cover.
Signature Database Files
ClamAV supports several custom database formats: .ndb (extended signatures, hex patterns), .hdb (MD5 file hashes), .ldb (logical signatures with conditions), .yara (YARA rules -- powerful pattern matching). Place in /var/lib/clamav/.
YARA Integration
ClamAV natively supports YARA rules (when compiled with YARA support). YARA is the industry standard for malware signature writing. Rules can match on strings, hex patterns, regular expressions, and boolean combinations. The security community publishes extensive YARA rule collections.
# Create a simple MD5 hash signature database (.hdb format) # Format: MD5:FileSize:SignatureName $ md5sum /path/to/known-bad-file 44d88612fea8a8f36de82e1278abb02f known-bad-file echo "44d88612fea8a8f36de82e1278abb02f:68:My-Custom-Sig.EICAR-Test" \ >> /var/lib/clamav/custom.hdb # Create a simple hex pattern signature (.ndb format) # Detect PHP webshells containing eval(base64_decode( echo "PHP.Webshell.EvalBase64:0:*:6576616c286261736536345f6465636f6465" \ >> /var/lib/clamav/custom.ndb # Verify the database is valid $ sigtool --validate /var/lib/clamav/custom.hdb # Reload clamd to pick up new signatures $ clamdscan --reload
Slide 21 of 33
Third-Party Signatures: Extending Detection Coverage
Supplement official ClamAV signatures with community databases for better detection rates.
Securiteinfo
Community-maintained signature databases covering phishing, potentially unwanted applications, and malware not yet in the official database. Free and commercial tiers. Add to /var/lib/clamav/ and keep updated with a script or cron job.
MalwarePatrol
Threat intelligence feeds including known malware hashes and C2 indicators. Integrates with ClamAV as a database. Commercial service with a limited free tier. Particularly useful for environments processing user-uploaded content.
clamav-unofficial-sigs
An open-source project and script that automates downloading, verifying, and installing multiple third-party signature databases for ClamAV. Includes databases from Sanesecurity, SecuriteInfo, and others. Available as a package or from GitHub.
# Install clamav-unofficial-sigs (automates third-party signature management) $ apt install clamav-unofficial-sigs # Configure which databases to download $ nano /etc/clamav-unofficial-sigs/user.conf # Run the update script $ clamav-unofficial-sigs.sh # Schedule updates in cron $ crontab -e 0 */4 * * * /usr/sbin/clamav-unofficial-sigs.sh
Slide 22 of 33
Performance Tuning: Balancing Coverage and Speed
Configure ClamAV to scan thoroughly without consuming excessive resources.
# clamd.conf -- performance settings # Number of parallel scanning threads (match to CPU cores) MaxThreads 4 # Maximum scan time per file in seconds (prevents hanging on large files) MaxScanTime 120000 # Maximum recursion depth in archives MaxRecursion 16 # Max files in an archive to scan MaxFiles 10000 # Memory for scan buffering (MB) StreamMaxLength 25M # Disable scanning inside certain archive types (improves speed, reduces coverage) # ScanOLE2 no -- disable scanning inside MS Office files # ScanMail no -- disable email scanning # Use clamdscan with --multiscan to scan multiple files in parallel $ clamdscan -r --multiscan /var/www # Run clamscan with ionice to reduce disk I/O priority (avoids impacting other services) $ ionice -c 3 nice -n 19 clamscan -r /
Slide 23 of 33
Syslog Integration: Centralized Threat Logging
Forward ClamAV detection events to syslog for centralized log management and SIEM ingestion.
# clamd.conf -- enable syslog output LogSyslog yes LogFacility LOG_LOCAL6 # use local6 facility to separate from other apps LogVerbose no # verbose logging floods syslog -- keep off in production # /etc/rsyslog.d/clamav.conf -- capture LOCAL6 to dedicated file local6.* /var/log/clamav/clamav-syslog.log local6.* @logserver.example.com:514 # forward to centralized log server (UDP) # Restart rsyslog $ systemctl restart rsyslog # Restart clamd $ systemctl restart clamav-daemon # Verify syslog entries appear $ logger -p local6.info "test message" $ grep "test message" /var/log/clamav/clamav-syslog.log # View ClamAV events in journald (Ubuntu 22.04 default) $ journalctl -u clamav-daemon -f
Slide 24 of 33
inotifywait: Event-Driven Scanning
Trigger scans immediately when new files appear in monitored directories.
On-access scanning requires clamd with fanotify. An alternative for directories where clamd cannot run with required permissions: use inotifywait to detect file creation events and immediately spawn a clamdscan of the new file. This gives near-real-time detection without the daemon overhead.
# Install inotify-tools $ apt install inotify-tools #!/bin/bash # /usr/local/bin/watch-uploads.sh # Monitor upload directory and scan new files immediately WATCH_DIR="/var/www/uploads" QUARANTINE="/var/quarantine" inotifywait -m -r -e close_write --format "%w%f" "$WATCH_DIR" \ | while read NEWFILE; do clamdscan --quiet "$NEWFILE" if [ $? -eq 1 ]; then mv "$NEWFILE" "$QUARANTINE/" logger -t clamav -p security.crit \ "Infected file quarantined: $NEWFILE" fi done
Slide 25 of 33
clamonacc: The On-Access Scanning Service
ClamAV 0.102+ ships clamonacc as a separate process for on-access scanning via fanotify.
# clamonacc requires clamd to be running and configured for on-access # It is a separate process that uses fanotify and communicates with clamd # Ensure clamd.conf has required settings: # User root (required for fanotify access) # OnAccessPrevention yes # OnAccessIncludePath /home # Start clamonacc (it runs as a separate daemon) $ clamonacc -F # foreground for testing (Ctrl+C to stop) $ clamonacc # daemonize # Enable via systemd (Ubuntu ships clamonacc as a service) $ systemctl enable clamav-clamonacc $ systemctl start clamav-clamonacc $ systemctl status clamav-clamonacc # Test: attempt to access the EICAR file in a monitored directory $ cp /tmp/eicar.com /home/ubuntu/ $ cat /home/ubuntu/eicar.com # Should be BLOCKED if OnAccessPrevention is enabled # Check logs for on-access detection event $ grep "FOUND" /var/log/clamav/clamav.log
Slide 26 of 33
clamdscan vs clamscan: When to Use Each
The right tool based on what you are doing and whether clamd is running.
Use clamscan When...
clamd is not running. You want a quick one-off scan without starting the daemon. You are in a minimal environment without the daemon installed. You need to scan from a non-root user that cannot connect to the clamd socket. Incident response on an unknown system.
Use clamdscan When...
clamd is running (always preferred when available). Repeated scans of many files -- database is already loaded. Triggered by inotify or web app. Integration with mail gateway or file server. Scan time matters -- clamdscan is significantly faster than clamscan for repeated scans.
clamscan DB load (~7.8s) scan 8.2s clamdscan scan 0.4s DB already in clamd memory ~20x faster
# Timing comparison: clamscan vs clamdscan on the same directory # clamscan (loads database from disk every time) $ time clamscan -r /var/www real 0m8.234s # ~8 seconds (mostly database load time) # clamdscan (database already in clamd memory) $ time clamdscan -r /var/www real 0m0.412s # ~0.4 seconds (no database load overhead) # The difference is entirely database load time (~230 MB loaded fresh vs cached) # For hourly scans of large directories, clamdscan is the only practical choice # clamdscan with file list input (efficient for custom target lists) $ find /var/www -name "*.php" > /tmp/php-files.txt $ clamdscan --file-list=/tmp/php-files.txt
Slide 27 of 33
What ClamAV Detects
The threat categories covered by ClamAV signatures -- and what falls outside its scope.
Detects
Known malware (trojans, ransomware, worms)
Web shells (PHP, ASP, JSP variants)
Windows PE executables with malicious code
Office macros with embedded malware
Infected archives (ZIP, RAR, 7z, tar)
PDF files with embedded exploits
Email attachments with known malware
Does Not Detect
Zero-day malware (no signature yet)
Fileless malware (no file to scan)
Memory-resident code injection
Unknown polymorphic malware
Malicious behavior (only behavioral AV handles this)
Rootkits hiding files from the filesystem
Partial Coverage
Potentially Unwanted Applications (PUAs) -- needs PUA scanning enabled
Obfuscated scripts -- bytecode engine helps
Encrypted archives -- cannot scan without password
Network traffic -- needs a proxy integration
Kernel rootkits -- use rkhunter or chkrootkit instead
Slide 28 of 33
rkhunter: Rootkit Detection
ClamAV does not detect kernel rootkits. rkhunter fills that gap.
What Is a Rootkit?
A rootkit hides an attacker's presence by intercepting and manipulating kernel calls. A hidden process does not appear in ps. Hidden files do not appear in ls. Hidden network connections do not appear in ss. Traditional AV cannot detect what the filesystem claims does not exist.
How rkhunter Works
Checks for known rootkit signatures. Compares system binary hashes against a baseline. Detects suspicious SUID files. Checks for hidden files and processes using multiple detection methods (comparing /proc with ps, cross-checking port lists). Runs from a baseline established on a known-clean system.
rkhunter detection layers FILE INTEGRITY hash baseline check PROCESS HIDING /proc vs ps diff KERNEL MODULES LKM rootkit sigs SUID scan suspicious perms hidden files dot-dir check network ports backdoor check string scan binary analysis
# Install rkhunter $ apt install rkhunter # Update the properties database (baseline of system binaries) $ rkhunter --update $ rkhunter --propupd # establish baseline hashes of system files # Run a full check $ rkhunter --check # Check without prompts (for cron) $ rkhunter --cronjob --report-warnings-only # Schedule in cron $ crontab -e 0 3 * * * rkhunter --cronjob --report-warnings-only | mail -s "rkhunter report" admin@example.com # View last rkhunter log $ cat /var/log/rkhunter.log
Slide 29 of 33
AIDE: File Integrity Monitoring
Detect unauthorized file modifications -- the complementary layer to AV scanning.
ClamAV catches known malware by signature. But what if the attacker uploads a custom tool that no signature database covers? AIDE (Advanced Intrusion Detection Environment) detects that any file changed -- including files that are not malware in the signature database but should never change.
aide --init baseline aide.db md5+sha256 perms+mtime aide --check compare live vs baseline NO CHANGES MODIFIED
# Install AIDE $ apt install aide # /etc/aide/aide.conf -- what to monitor # CONTENT_EX = md5+sha256+size+mtime+ctime+inode+uid+gid+perms /etc CONTENT_EX /bin CONTENT_EX /sbin CONTENT_EX /usr/bin CONTENT_EX /var/www/html CONTENT_EX !/var/www/html/uploads # exclude upload directory (files change legitimately) # Initialize the baseline database (on a KNOWN CLEAN system) $ aide --init $ mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db # Check for changes against baseline $ aide --check # Schedule daily check with cron 0 4 * * * aide --check 2>&1 | mail -s "AIDE report $(hostname)" admin@example.com
Slide 30 of 33
Full Defense Stack: Layered Detection
How ClamAV, rkhunter, AIDE, and the firewall stack together to cover different threat vectors.
THREAT FIREWALL iptables L3/L4 ClamAV signatures file AV AIDE integrity hashes rkhunter rootkits kernel LOG audit 5 layers -- each catches what the others miss
Layer 1: Network (firewall)
iptables / UFW. Controls what reaches your services. Stops unauthorized connections before any file can be delivered. Does not inspect file content.
Layer 2: File Content (ClamAV)
Scans files for known malware signatures. Catches malicious uploads and email attachments. Does not detect rootkits or unauthorized modifications to system files.
Layer 3: Integrity (AIDE)
Detects any change to monitored files. Catches a compromised binary even if ClamAV has no signature for it. Requires a known-clean baseline to be useful.
Layer 4: Rootkit Detection (rkhunter)
Specifically targets kernel and binary-level rootkits. Catches hiding techniques that fool the filesystem layer. Complements AIDE which can be deceived by a sophisticated rootkit.
Layer 5: Behavior (auditd)
Audit daemon records security-relevant system calls: file opens, privilege escalation, network connections. Post-compromise forensics layer -- everything the attacker did is in the audit log.
Slide 31 of 33
Troubleshooting ClamAV
Common issues and their diagnostic procedures.
# Issue: clamd fails to start $ systemctl status clamav-daemon $ journalctl -u clamav-daemon -n 50 # Common cause: database not yet downloaded $ ls -la /var/lib/clamav/ # should have main.cvd, daily.cld, bytecode.cld $ freshclam # download if missing # Issue: clamdscan reports "connection refused" $ systemctl status clamav-daemon $ ls -la /var/run/clamav/ # check socket file exists # Issue: clamscan "LibClamAV Warning: ***** This version outdated!" $ apt update && apt upgrade clamav clamav-daemon # Issue: freshclam fails to update $ freshclam --verbose # see exact error # Common causes: network connectivity, DNS resolution, double-running freshclam instances $ systemctl stop clamav-freshclam && freshclam && systemctl start clamav-freshclam # Issue: high CPU from clamav during scheduled scan $ nice -n 19 ionice -c 3 clamscan -r / # deprioritize the scan process
Slide 32 of 33
Key Vocabulary
Terms from this session used in security documentation, job descriptions, and audits.
ClamAV Components
clamscan -- one-shot command-line scanner, loads database each run.
clamd -- resident daemon, keeps database in memory for fast scans.
clamdscan -- client that submits scan requests to clamd.
freshclam -- signature update daemon, syncs databases from mirrors.
clamonacc -- on-access scanning process using fanotify.
Detection and Database
signature -- a pattern that identifies known malware.
main.cvd -- core signature database.
daily.cld -- daily-updated signature delta file.
EICAR -- standardized AV test string, not real malware.
false positive -- a clean file incorrectly flagged as malware.
Security Concepts
on-access scanning -- scanning files as they are opened, using fanotify.
fanotify -- Linux kernel API used for on-access file monitoring.
quarantine -- isolated storage for detected threats pending analysis.
YARA -- industry-standard rule language for malware signature writing.
rootkit -- malware that hides itself by manipulating kernel functions.
Slide 33 of 33  |  Week 2 Topic 3
Threat Sentinel: Key Takeaways
The sentinel is active. ClamAV is scanning. freshclam is keeping signatures current. On-access scanning watches the upload directory. The nightly scan covers the rest of the filesystem. AIDE monitors for unauthorized changes. A threat that slips past the firewall hits four detection layers before it can cause damage.
1 ClamAV has two scanning modes: clamscan (loads database fresh each run) and clamdscan (submits to running clamd). Use clamdscan for repeated or automated scans.
2 freshclam must run continuously (or on a schedule) or your signatures become stale. Outdated signatures = missed threats.
3 Use the EICAR test string to verify ClamAV is working. Never use real malware samples on production systems.
4 Exit codes: 0 = clean, 1 = infected found, 2 = error. Always check exit codes in scripts -- do not rely on parsing text output.
5 On-access scanning uses fanotify + clamonacc. Scope it carefully -- monitoring the entire filesystem on a busy server has significant performance cost.
6 Quarantine is better than delete. Preserved samples enable forensic analysis. False positives can be recovered. Compliance frameworks often require evidence retention.
7 ClamAV does not detect rootkits. Use rkhunter for rootkit detection and AIDE for file integrity monitoring as complementary layers.
8 Exclude virtual filesystems (/proc, /sys, /dev) from all scans. Scanning these causes errors, wastes time, and finds nothing useful.