ClamAV is the world's most widely deployed open-source antivirus toolkit. Originally created by Tomasz Kojm in 2001, it is now maintained by Cisco Talos. It provides on-access and on-demand scanning, a signature database updated multiple times daily, and deep integration with email gateways including Postfix, Sendmail, and Exim.
Command-line virus scanner. Loads the signature database at startup, scans files/directories, and reports results. Best for one-off scans; use clamdscan for repeated scanning to avoid DB reload overhead.
clamd
On-demand scanning daemon. Keeps signatures loaded in memory and accepts scan requests over a Unix socket or TCP. Required for mail filter integration (clamav-milter, amavisd) and high-throughput scanning.
freshclam
Signature database updater. Runs as a daemon or from cron, pulling incremental CVD/CLD patches from database.clamav.net. Verifies digital signatures on every update.
clamdscan
Client for clamd. Sends file paths to the running daemon via socket — no DB reload, dramatically faster than clamscan for bulk scanning. Supports --multiscan for parallel threads.
sigtool
Signature tool for DB inspection and creation. Unpack CVD files, compute checksums, create custom .ndb/.hdb/.ldb signatures, and test them against samples.
clamav-milter
Sendmail/Postfix milter plugin that hooks into the SMTP conversation. Scans email attachments before delivery and can reject, quarantine, or tag infected messages in real time.
Detection Capabilities
Category
What It Catches
Method
Viruses & Malware
Traditional file-infecting viruses, worms, trojans
Scan a single file, directory, or the whole filesystem. clamscan loads the DB each run.
# Scan a single fileclamscan/path/to/file.exe# Recursively scan a directoryclamscan-r/home/user/downloads# Scan and move infected files to quarantineclamscan-r --move=/quarantine/var/www# Scan only infected, suppress OK linesclamscan-r --infected/home# Scan a stream from stdincatsuspicious.pdf | clamscan--stdin
USEFUL FLAGS
Flag
Description
-r, --recursive
Scan directories recursively
-i, --infected
Print only infected files
--remove
Delete infected files (use with caution)
--move=DIR
Move infected files to DIR
--copy=DIR
Copy infected files to DIR (keep original)
--max-filesize=N
Max file size to scan (MB)
--max-scansize=N
Max data scanned per file (MB)
--bell
Sound alert on detection
--log=FILE
Write scan report to FILE
--no-summary
Suppress scan summary at end
--bytecode=no
Disable bytecode interpreter
--exclude=REGEX
Skip files matching pattern
--include=REGEX
Only scan files matching pattern
--detect-pua
Enable PUA (Potentially Unwanted App) detection
clamdscan — Daemon Client
Sends scan requests to a running clamd instance. Much faster than clamscan — no DB reload per scan.
# Scan file via daemon (clamd must be running)clamdscan/path/to/file# Parallel scan with all available threadsclamdscan--multiscan --fdpass/var/uploads# Reload signatures without restarting clamdclamdscan--reload# Stream to daemon (useful in scripts / pipes)clamdscan--stream/tmp/suspect.zip
freshclam — Database Updater
# Manual updatefreshclam# Verbose update with progressfreshclam-v# Run as daemon (checks every N hours per config)freshclam-d# Show current database versionsigtool--info/var/lib/clamav/main.cvd
clamd — Daemon Management
# Start via systemdsystemctl start clamav-daemon
# Enable on bootsystemctl enable clamav-daemon clamav-freshclam
# Check daemon statussystemctl status clamav-daemon
# Test clamd is responding (PING → PONG)echoPING | nc-U/var/run/clamav/clamd.ctl# Get clamd version over socketechoVERSION | nc-U/var/run/clamav/clamd.ctl
sigtool — Signature Utilities
# Unpack a CVD database filesigtool-udaily.cvd# Show database info (version, sigs, builder)sigtool--infodaily.cvd# List all signatures in a DBsigtool-ldaily.cvd# Generate MD5 hash of a file (for .hdb signatures)sigtool--md5malware_sample.exe# Generate SHA-256 hash (for .hsb signatures)sigtool--sha256malware_sample.exe# Find which signature detected a fileclamscan--debugsample.exe 2>&1 | grep"Detected"
Interactive Scan Demo
# Click "Run Demo Scan" to simulate a clamscan run
Signature Database Files
File
Format
Contents
Size
main.cvd
CVD
Core signature set — stable, rarely changes
~160 MB
daily.cvd
CVD/CLD
Daily incremental updates — new threats
~60 MB
bytecode.cvd
CVD
Bytecode programs for complex detection logic
~400 KB
*.ndb
Text
Hex-pattern signatures (custom)
varies
*.hdb
Text
MD5 file hash signatures
varies
*.hsb
Text
SHA-256 file hash signatures
varies
*.ldb
Text
Logical signatures (boolean rules)
varies
*.yar
YARA
YARA rules (supported natively)
varies
CVD File Format
CVD (ClamAV Virus Database) — tar.gz archive with a 512-byte header
Header (512 B) Metadata: version, sigcount, build date, MD5, signature
# 1. Get hex bytes of a known-bad stringecho-n"eval(base64_decode" | xxd-p# → 6576616c28626173653634_6465636f6465# 2. Create .ndb fileecho"PHP.Obfuscated.Base64Eval:7:*:6576616c28626173653634" > custom.ndb# 3. Test signatureclamscan--database=custom.ndbtestfile.php# 4. Deploy — copy to ClamAV DB dircpcustom.ndb/var/lib/clamav/clamdscan--reload
EICAR Test File
The EICAR standard test string — safe, non-malicious, detected by all AV engines as "EICAR-Test-Signature"
Save as eicar.com and scan — ClamAV should report: Eicar-Test-Signature FOUND
Mail Server Integration
Postfix + amavisd-new
The standard production stack. Amavisd acts as a content filter between Postfix instances, calling ClamAV via clamd socket. Re-injects clean mail at port 10025.
clamav-milter
Native milter — hooks into Sendmail/Postfix smtpd_milters at the protocol level. Simpler than amavisd for AV-only setups; no spam scoring.
Exim + ClamAV
Exim has native malware = clamav condition in ACLs. No helper daemon needed — Exim calls clamd directly via its built-in malware scanner interface.
POSTFIX + AMAVISD FLOW
SMTP in (25)
│
[Postfix smtpd]
│ content_filter = amavis:[127.0.0.1]:10024
▼
[amavisd-new :10024]
│
├── calls clamd → scan for viruses
├── calls spamassassin → spam scoring
│
▼
clean mail re-injected at :10025
│
[Postfix smtpd :10025] → local delivery / relay
# Scan a file via TCP clamd in Dockerclamdscan--config-file=---stream/path/to/file<<EOF
TCPSocket 3310
TCPAddr 127.0.0.1
EOF
REST API Wrappers
Project
Language
Description
clamav-rest
Java
REST wrapper around clamd — POST a file, get JSON result back
python-clamd
Python
Pure Python client for clamd Unix/TCP socket
go-clamav
Go
Go bindings for libclamav + clamd socket client
node-clamscan
Node.js
Async Node.js wrapper — scans buffers, streams, and local paths
PYTHON EXAMPLE
import clamd
# Connect to clamd via Unix socket
cd = clamd.ClamdUnixSocket('/var/run/clamav/clamd.ctl')
# Ping daemonprint(cd.ping()) # → 'PONG'# Scan a file path
result = cd.scan('/tmp/suspect.pdf')
print(result)
# → {'/tmp/suspect.pdf': ('FOUND', 'Win.Trojan.Example-1')}# Scan an in-memory buffer (stream)withopen('file.exe', 'rb') as f:
result = cd.instream(f)
print(result['stream']) # → ('OK', None) or ('FOUND', 'SigName')
clamd.conf — Key Settings
# /etc/clamav/clamd.conf# SocketLocalSocket/var/run/clamav/clamd.ctlLocalSocketMode660TCPSocket3310# enable for TCP (disable for Unix-only)TCPAddr127.0.0.1# listen address# DatabaseDatabaseDirectory/var/lib/clamavDatabaseAutoReloadyes# reload sigs when freshclam updates them# Scan limitsMaxScanSize400M# max data scanned per fileMaxFileSize100M# skip files larger than thisMaxRecursion10# max archive nesting depthMaxFiles10000# max files extracted from archiveMaxEmbeddedPE10M# max PE in HTML/OLE2MaxHTMLNormalize40M# PerformanceMaxThreads4# parallel scan threadsReadTimeout60# seconds to wait for client dataMaxQueue200# max queued connections# Detection optionsScanPEyesScanELFyesScanOLE2yes# MS Office documentsScanPDFyesScanHTMLyesScanMailyesScanArchiveyesDetectPUAno# potentially unwanted applicationsHeuristicAlertsyesBytecodeyes# enable bytecode engine# User/group (must match socket perms)UserclamavAllowSupplementaryGroupsyes
freshclam.conf — Update Settings
# /etc/clamav/freshclam.confDatabaseDirectory/var/lib/clamavDatabaseOwnerclamav# Update servers (round-robin)DatabaseMirrordatabase.clamav.net# Check N times per day (max 12 per policy)Checks12# Notify clamd after updateNotifyClamd/etc/clamav/clamd.conf# LogUpdateLogFile/var/log/clamav/freshclam.logLogVerboseno