Install ClamAV on Debian 11

Last Updated:

In this tutorial, we are going to learn how to Install ClamAV on Debian 11. ClamAV is an open source antivirus engine for detecting trojans, viruses, malware, adwares, rootkits and other malicious threats.

Some of the features of ClamAV include;

  • built-in support for various archive formats, including Zip, Tar, Gzip, Bzip2, OLE2, Cabinet, CHM, BinHex, SIS and others.
  • built-in support for almost all mail file formats
  • built-in support for ELF executables and Portable Executable files compressed with UPX, FSG, Petite, NsPack, wwpack32, MEW, Upack and obfuscated with SUE, Y0da Cryptor and others;
  • built-in support for popular document formats including Microsoft Office and Mac Office files, HTML, RTF and PDF.
  • support multiple signature languages such as hash-based signature matching, wildcards, boolean logic and any custom rules written in Bytecode language.

ClamAV includes a multi-threaded scanner daemon, command line utilities for on demand file scanning and automatic signature updates. One of its main uses is on mail servers as a server-side email virus scanner.

Installing ClamAV on Debian 11

Update System Package Cache

To begin with, update system package cache.

apt update

Install ClamAV

As of this writing, the default Debian 11 repositories provides ClamAV version: 0.103.2.

apt-cache policy clamav clamav-daemon

  Installed: 0.103.2+dfsg-2
  Candidate: 0.103.2+dfsg-2
  Version table:
 *** 0.103.2+dfsg-2 500
        500 bullseye/main amd64 Packages
        100 /var/lib/dpkg/status
  Installed: 0.103.2+dfsg-2
  Candidate: 0.103.2+dfsg-2
  Version table:
 *** 0.103.2+dfsg-2 500
        500 bullseye/main amd64 Packages
        100 /var/lib/dpkg/status

The current stable release is version 0.104.0.

Thus, in order to ensure that you are running the latest version of ClamAV, you need to build and install from sources.

Install ClamAV from Sources on Debian 11

Install required package dependencies and build tools.

apt install -y gcc make pkg-config python3 python3-pip python3-pytest valgrind \
check libbz2-dev libcurl4-openssl-dev libjson-c-dev libmilter-dev sudo \
libncurses5-dev libpcre2-dev libssl-dev libxml2-dev zlib1g-dev cmake

Create ClamAV  service account;

useradd -r -M -d /var/lib/clamav -s /bin/false -c "Clam Antivirus" clamav

Navigate to downloads page and download source code. You can run the command below to download it the current stable release version as of this writing.


Extract the source code, compile and install ClamAV.

tar xzf clamav-$VER.tar.gz

Build and install ClamAV;

cd clamav-$VER
mkdir build && cd build
cmake .. \
    -D APP_CONFIG_DIRECTORY=/etc/clamav \
    -D DATABASE_DIRECTORY=/var/lib/clamav \
cmake --build .

Sample output;

Test project /root/clamav-0.104.0/build
      Start  1: libclamav
 1/10 Test  #1: libclamav ........................   Passed    8.22 sec
      Start  2: libclamav_valgrind
 2/10 Test  #2: libclamav_valgrind ...............   Passed   67.93 sec
      Start  3: clamscan
 3/10 Test  #3: clamscan .........................   Passed    2.64 sec
      Start  4: clamscan_valgrind
 4/10 Test  #4: clamscan_valgrind ................   Passed   35.01 sec
      Start  5: clamd
 5/10 Test  #5: clamd ............................   Passed   10.02 sec
      Start  6: clamd_valgrind
 6/10 Test  #6: clamd_valgrind ...................   Passed   46.44 sec
      Start  7: freshclam
 7/10 Test  #7: freshclam ........................   Passed    2.03 sec
      Start  8: freshclam_valgrind
 8/10 Test  #8: freshclam_valgrind ...............   Passed   20.16 sec
      Start  9: sigtool
 9/10 Test  #9: sigtool ..........................   Passed    0.46 sec
      Start 10: sigtool_valgrind
10/10 Test #10: sigtool_valgrind .................   Passed    1.23 sec

100% tests passed, 0 tests failed out of 10

Total Test time (real) = 194.14 sec
cmake --build . --target install

Configuring ClamAV

Once the installation is done, you need to configure ClamAV.

There are three main configs;

  • freshclam.conf required for FreshClam
  •  clamd.conf required by ClamD
  •  clamav-milter.conf required by ClamAV-Milter if you enabled ClamAV support for mail filtering (we didnt do that in this setup).

From our installation, we set ClamAV to store the configs on /etc/clamav.

ls -1 /etc/clamav/

Update these configs as follows;

cat > /etc/clamav/freshclam.conf << 'EOL'
DatabaseOwner clamav
UpdateLogFile /var/log/clamav/freshclam.log
LogVerbose false
LogSyslog false
LogFacility LOG_LOCAL6
LogFileMaxSize 0
LogRotate true
LogTime true
Foreground false
Debug false
MaxAttempts 5
DatabaseDirectory /var/lib/clamav
ConnectTimeout 30
ReceiveTimeout 0
TestDatabases yes
ScriptedUpdates yes
CompressLocalDatabase no
Bytecode true
NotifyClamd /etc/clamav/clamd.conf
Checks 24

cat > /etc/clamav/clamd.conf << 'EOL'
LocalSocket /var/run/clamav/clamd.ctl
FixStaleSocket true
LocalSocketGroup clamav
LocalSocketMode 666
User clamav
ScanMail true
ScanArchive true
ArchiveBlockEncrypted false
MaxDirectoryRecursion 15
FollowDirectorySymlinks false
FollowFileSymlinks false
ReadTimeout 180
MaxThreads 12
MaxConnectionQueueLength 15
LogSyslog false
LogRotate true
LogFacility LOG_LOCAL6
LogClean false
LogVerbose false
PreludeEnable no
PreludeAnalyzerName ClamAV
DatabaseDirectory /var/lib/clamav
OfficialDatabaseOnly false
SelfCheck 3600
Foreground false
Debug false
ScanPE true
MaxEmbeddedPE 10M
ScanOLE2 true
ScanPDF true
ScanHTML true
MaxHTMLNormalize 10M
MaxHTMLNoTags 2M
MaxScriptNormalize 5M
MaxZipTypeRcg 1M
ScanSWF true
ExitOnOOM false
LeaveTemporaryFiles false
AlgorithmicDetection true
ScanELF true
IdleTimeout 30
CrossFilesystems true
PhishingSignatures true
PhishingScanURLs true
PhishingAlwaysBlockSSLMismatch false
PhishingAlwaysBlockCloak false
PartitionIntersection false
DetectPUA false
ScanPartialMessages false
HeuristicScanPrecedence false
StructuredDataDetection false
CommandReadTimeout 30
SendBufTimeout 200
MaxQueue 100
ExtendedDetectionInfo true
OLE2BlockMacros false
AllowAllMatchScan true
ForceToDisk false
DisableCertCheck false
DisableCache false
MaxScanTime 120000
MaxScanSize 100M
MaxFileSize 25M
MaxRecursion 16
MaxFiles 10000
MaxPartitions 50
MaxIconsPE 100
PCREMatchLimit 10000
PCRERecMatchLimit 5000
PCREMaxFileSize 25M
ScanXMLDOCS true
ScanHWP3 true
MaxRecHWP3 16
StreamMaxLength 25M
LogFile /var/log/clamav/clamav.log
LogTime true
LogFileUnlock false
LogFileMaxSize 0
Bytecode true
BytecodeSecurity TrustSigned
BytecodeTimeout 60000
OnAccessMaxFileSize 5M

Since we didn't compile ClamAV with mail filtering support, then the configs above are enough.

Create the log, database and socket directories for FreshClam.

mkdir /var/log/clamav/ /var/lib/clamav /var/run/clamav/

Set the ownership of the log, database and socket directories to clamav user.

chown clamav: /var/log/clamav/ /var/lib/clamav /var/run/clamav/

Update the ClamAV Signature Database

For scanning to work, you need am updated virus database. There are two options for updating ClamAV database:

  • clamav-freshclam: updates the database from Internet. This is recommended with Internet access.
  • Offline update for systems with no direct internet access.

Update Signature Database with clamav-freshclam

If you have internet access, you can use clamav-freshclam to update the ClamAV virus signature database.

Then update the virus database;

sudo -u clamav freshclam

The command will pull database updates and you might get an output similar to below.

Tue Sep 14 22:29:35 2021 -> ClamAV update process started at Tue Sep 14 22:29:35 2021
Tue Sep 14 22:29:35 2021 -> daily database available for download (remote version: 26294)
Time:  1m 18s, ETA:    0.0s [========================>]   55.56MiB/55.56MiB
Tue Sep 14 22:30:55 2021 -> Testing database: '/var/lib/clamav/tmp.6d40b4137a/clamav-ec762c472f7babc64cd6617646a05aa9.tmp-daily.cvd' ...
Tue Sep 14 22:31:02 2021 -> Database test passed.
Tue Sep 14 22:31:02 2021 -> daily.cvd updated (version: 26294, sigs: 1972718, f-level: 90, builder: raynman)
Tue Sep 14 22:31:02 2021 -> main database available for download (remote version: 61)
Time:  4m 00s, ETA:    0.0s [========================>]  160.41MiB/160.41MiB
Tue Sep 14 22:35:05 2021 -> Testing database: '/var/lib/clamav/tmp.6d40b4137a/clamav-f2c7c5efaa09e11ebb5085cbd4abe3f3.tmp-main.cvd' ...
Tue Sep 14 22:35:13 2021 -> Database test passed.
Tue Sep 14 22:35:13 2021 -> main.cvd updated (version: 61, sigs: 6607162, f-level: 90, builder: sigmgr)
Tue Sep 14 22:35:13 2021 -> bytecode database available for download (remote version: 333)
Time:    2.0s, ETA:    0.0s [========================>]  286.79KiB/286.79KiB
Tue Sep 14 22:35:15 2021 -> Testing database: '/var/lib/clamav/tmp.6d40b4137a/clamav-60d878c5920160c4068f0a9a43fc214e.tmp-bytecode.cvd' ...
Tue Sep 14 22:35:15 2021 -> Database test passed.
Tue Sep 14 22:35:15 2021 -> bytecode.cvd updated (version: 333, sigs: 92, f-level: 63, builder: awillia2)
Tue Sep 14 22:35:15 2021 -> ^Clamd was NOT notified: Can't connect to clamd through /var/run/clamav/clamd.ctl: No such file or directory

freshclam downloads the ClamAV databases, CVDs, and place them on under, /var/lib/clamav/.

ls -1 /var/lib/clamav/

Create FreshClam service;

cat > /etc/systemd/system/clamav-freshclam.service << EOL
Description=ClamAV virus database updater
Documentation=man:freshclam(1) man:freshclam.conf(5)
# If user wants it run from cron, don't start the daemon.

ExecStart=/usr/bin/freshclam -d --foreground=true


Create and start ClamAV daemon service;

cat > /etc/systemd/system/clamav-daemon.service << EOL
Description=Clam AntiVirus userspace daemon
Documentation=man:clamd(8) man:clamd.conf(5)
# Check for database existence

ExecStart=/usr/sbin/clamd --foreground=true
# Reload the database
ExecReload=/bin/kill -USR2 $MAINPID


Reload systemd daemon and ensure the services are enabled to run on system boot;

systemctl daemon-reload
systemctl enable --now clamav-daemon
systemctl enable --now clamav-freshclam

ClamAV Scanning

Clamscan CLI Options and Example Usage

Clamscan is used to scan files and directories for viruses. From the man pages, the clamscan command syntax is:

clamscan [options] [file/directory/-]

Some of the clamscan command options and their example usage is illustrated below;

Print help information using -h or --help option.

clamscan -h

Note: Options marked with [=yes/no(*)] can be optionally followed by =yes or =no. If they get called without the boolean argument the scanner will assume ‘yes’. The asterisk marks the default internal setting for a given option.

Scan specific directory or file;

clamscan /home/

Sample results

Loading:    16s, ETA:   0s [========================>]    8.56M/8.56M sigs       
Compiling:   3s, ETA:   0s [========================>]       41/41 tasks 

----------- SCAN SUMMARY -----------
Known viruses: 8564637
Engine version: 0.104.0
Scanned directories: 1
Scanned files: 0
Infected files: 0
Data scanned: 0.00 MB
Data read: 0.00 MB (ratio 0.00:1)
Time: 20.375 sec (0 m 20 s)
Start Date: 2021:09:14 23:14:15
End Date:   2021:09:14 23:14:35
clamscan /home/filename.docx

Do not display summary at the end of scanning.

clamscan --no-summary /home/

Print infected files only (-i--infected);

clamscan -i /

Skip printing OK files (-o--suppress-ok-results);

clamscan -o /home/

Sound a bell on virus detection (--bell);

clamscan --bell -i /home

Scan directories recursively (-r--recursive).

clamscan --bell -i -r /home

Save scan report to FILE (-l FILE--log=FILE);

clamscan --bell -i -r /home -l home-scan.txt

Scan files listed line by line in FILE (-f FILE, --file-list=FILE).

clamscan -i -f /tmp/scan

Remove infected files (--remove[=yes/no(*)]). Be careful as this removes file completely.

 clamscan -r --remove /home/USER

Move infected files into DIRECTORY (--move=DIRECTORY). Directory must be writable for the user or unprivileged user running clamscan.

clamscan -r -i --move=/home/USER/infected /home/

Copy infected files into DIRECTORY (–copy=DIRECTORY). Directory must be writable for the user or unprivileged user running clamscan.

clamscan -r -i --copy=/home/USER/infected /home/

There is quite long list of options for various usage of clamscan. Consult man clamscan for more details.

ClamAV Return Codes

The following are the exit return codes for ClamAV.

  • 0 : No virus found.
  • 1 : Virus(es) found.
  • 2 : Some error(s) occurred.

Limiting Clamscan CPU Usage

clamscan can be CPU intensive especially if it scanning a large directory.

To limit the clamscan CPU time to certain levels, you can use two tools;

  • nice: lowers the priority of clamscan (limits relative cpu time).
  • cpulimit: limits absolute cpu time.

To use nice command,

nice -n 15 clamscan && clamscan -ir /

As long as no other process requires cputime, clamscan will maximize it. But as soon as another process with a higher priority needs cputime, clamscan will lost it.

Using cpulimit;

cpulimit -z -e clamscan -l 20 & clamscan -ir /

Limits clamscan cpu time to 15% when scanning the entire root directory.

Further Reading

ClamAV User Manual

Related Tutorials

Install GVM 21.04 on Debian 11/Debian 10

Install Modsecurity with Nginx on Rocky Linux 8


We're passionate about sharing our knowledge and experiences with you through our blog. If you appreciate our efforts, consider buying us a virtual coffee. Your support keeps us motivated and enables us to continually improve, ensuring that we can provide you with the best content possible. Thank you for being a coffee-fueled champion of our work!

Photo of author
I am the Co-founder of, Linux and the whole FOSS enthusiast, Linux System Admin and a Blue Teamer who loves to share technological tips and hacks with others as a way of sharing knowledge as: "In vain have you acquired knowledge if you have not imparted it to others".

Leave a Comment