I setup clamav as virus scan server from other device.

Anti Virus
Reading Time: 3 minutes

I found that clamav daemon accept virus scan request from outside as well as from localhost.
This article is how I did.

Let’s see system structure.
Usual server and client.
clamd accepts by TCP 3310 by default.
– You can change port by configuration.

With this structure,

clamd process can be only 1 among network.
-> RAM occupancy will be lower which means cost will be lower!


First let’s see clamonacc.

I build from source code to patch explained by this article.

This is shell script.

# To install packages to be used during build.
sudo apt-get -y install cmake gcc make pkg-config python3 python3-pip python3-pytest valgrind \
	check libbz2-dev libcurl4-openssl-dev libjson-c-dev libmilter-dev \
	libncurses5-dev libpcre2-dev libssl-dev libxml2-dev zlib1g-dev

# Add user/group for clamav.
sudo groupadd clamav
sudo useradd -g clamav -s /bin/false -c "Clam Antivirus" clamav

# Downloading source code and extract.
# This case I used 0.104.0 which is the latest tag at this moment.
wget https://github.com/Cisco-Talos/clamav/archive/refs/tags/clamav-0.104.0.tar.gz
tar zxf clamav-0.104.0.tar.gz

# Change mask for fanotify.
wget https://raw.githubusercontent.com/kurofuku/dotfiles/master/clamav/change_fanotify_mask.diff
patch -p0 < change_fanotify_mask.diff

# Build and install.
cd clamav-clamav-0.104.0
mkdir build && cd build
cmake ..
cmake --build .
sudo cmake --build . --target install

# This is for uninstall.
sudo xargs rm < install_manifest.txt

I include this script to setup.sh.
– This patch cannot be fully guaranteed quality, please use at your own risk.

dotfiles/setup.sh at master · kurofuku/dotfiles
Contribute to kurofuku/dotfiles development by creating an account on GitHub.

This is start script.
clamd sends “PONG” as the reply of “PING” after finishing initialization.



while [ "zPONG" != "z$( echo PING | nc <IP address which clamd runs> 3310 )" ];
        sleep 1;

if [ ! -d ${QUARANTINE_DIR} ]; then
        mkdir -p ${QUARANTINE_DIR}

/usr/local/sbin/clamonacc --fdpass --move=${QUARANTINE_DIR} --config-file=/usr/local/etc/clamonacc.conf

This is clamonacc.conf.
TCPAddr and TCPSocket is parameters to specify which clamd is virus scan server.
OnAccessIncludePath are the directories to be watched by clamonacc.
– You can set more than 1 directory by writing multiple lines.

TCPSocket 3310
TCPAddr <IP address which clamd runs> 
OnAccessIncludePath <Directory to be watched>

That’s it for clamonacc.


I didn’t customize anything to clamd.
You can install from apt/yum or from source code.

I use almost default clamd.conf.

TCPSocket 3310
TCPAddr <IP address which clamd runs> 

To start clamd if you build from source code.

sudo clamd

If you install by apt/yum or other package manager.

sudo service clamd start

Let’s check if clamd listens from outside.
Below is OK because TCP3310 is LISTEN state.

netstat -ta
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 <IP address>:3310*               LISTEN     

That’s it for clamd.
Please make sure you already executed freshclam to up-to-date.


It should work well.
– With Raspberry Pi 4, CPU usage is around 5%.

I found 1 issue to be solved.

Even if you want to notify virus detection by VirusEvent, affected file name is replaced as imstream(IP address@Port number) which doesn’t make sense.

This is caused by this system structure,

The command defined by VirusEvent is executed by clamd.
clamd doesn't know the file path because contents of file was sent by clamonacc.
So clamd has no choise but printing as "instream".

This is sample, we cannot guess which file is affected…

So I created patch to solve by adding function to execute VirusEvent by clamonacc.

Here is patch.
– Please use by your own risk because this patch is not fully quality assured. 

dotfiles/add_OnAccessVirusEvent_functionalty.diff at master · kurofuku/dotfiles
Contribute to kurofuku/dotfiles development by creating an account on GitHub.

Configuration name is “OnAccessVirusEvent”.

You can define command like this.

OnAccessVirusEvent <Command to be run when detecting virus>

This is sample.
Well done!


How was it?

I monitor these directories and works good!

- nextcloud directory
- WordPress directory