Hi,
Recently I decided to finally sort out Linux antivirus options for my personal laptop. What started as a quick weekend test of ClamAV turned into a full-blown adventure through GUI glitches, kernel modules, hanging processes, trial versions, and… a realization that I was relying a bit too much on ChatGPT. 🙃
Here’s my full journey, lessons learned, screenshots, and configs — and how I ended up coming back full circle, but better equipped.
Stage 1 — ClamAV: The (Too) Basic Classic
Let’s start from the beginning. Everyone knows ClamAV — the default open-source AV for Linux. It’s available in every repo and is super easy to install.
sudo apt update
sudo apt install clamav clamav-daemon -y
sudo systemctl stop clamav-freshclam
sudo freshclam
sudo systemctl start clamav-daemon
Scan with:
clamscan -r -i --log=clam.log /home/user/Downloads
So far so good. But…
- No real-time protection by default
- Slow full scans – in my case one folder with 3 GB in size was scanned almost 3 hours
- No GUI that actually works properly (yes, I tried)
And it felt too manual. I wanted something better.
Stage 2 — Bitdefender: Fast, Modern… and Buggy?
Next up — Bitdefender. It looked impressive from the beginning:
- Real-time protection by default
- Centralized management
- Client-Server architecture
- Web panel with live stats
- Great documentation






How It Works Under the Hood:
You need to prepare installation package, which is quite configurable. After package with agent installed, it is connected to Cloud management server.
On Linux (Ubuntu), Bitdefender uses a kernel module or FUSE-based method to hook into file system operations (depending on the integration). When a file is accessed:
- It’s intercepted.
- A hash or signature check is performed.
- If the file matches a known malware pattern or behavior, it’s blocked/quarantined.
Under the hood Biddefender use s inotify / fanotify (Linux APIs)
You may also turn on regular scanning and configure what should be scanned from panel, or run many different commands using already preinstalled cli tool:
sudo /opt/bitdefender-security-tools/bin/bduitool scan -s -f custom /home/user/Downloads/
Install was smooth. Scan was blazing fast compared to ClamAV: some several minutes relatively to several clamav hours. And then…
My laptop started hanging randomly.
Opening terminal — freeze.
Starting apps — freeze.
I thought my SSD was dying. It wasn’t. 😡
Turns out: Bitdefender hooks deeply into the filesystem using fanotify, and this can stall apps waiting for file scans. If Bitdefender:
- Takes too long to respond, or
- Encounters a large file, or
- Has performance issues (e.g., high I/O load)
→ the calling application hangs, waiting for permission to proceed.
Apps that are latency-sensitive or I/O-intensive can experience serious slowdowns or deadlocks.
Examples:
- Browsers trying to load a lot of small files quickly.
- Package managers or software updaters (like apt).
- Office apps, IDEs, or custom dev tools.
- Network services reading configuration or certificate files at startup.
Big fail for daily use. I uninstalled it completely. Maybe it is possible to achieve some stable work by excluding some folders and additional configuration adjustments – but my intuition said me that such a solution already “smells” bad.
Stage 3 — ESET NOD32: Confusing, Powerful, Risky
ESET looked promising — enterprise-level tool with centralized cloud control via ESET PROTECT Hub. The architecture – quite similar to the Bitdefender has.
But the experience? Let’s say… bumpy.
Agent does not have cli management. Here ESET went step far – only remote control.
Product naming is a reals mess (EFS vs EEA vs Protect Hub?). In that case, at the top, we have ESET PROTECT Hub – Online portal to access/manage your cloud console and services.

Then there is ESET PROTECT – Console to manage devices, agents, policies, and reports. Hard to say what is for to create 2 services, which can be combined at one to not confuse clients. Anyway to be used – it should be initially turn on and configured.


Meanwhile I found that there is another product – EEA (Endpoint Antivirus for Linux) is still supported somehow, but surprise, it is absent at ESET PROTECT, and likely to be deprecated (despite, as for me, it was indeed good solution).
Instead of EEA, ESET promotes ESET Server Security (EFS), which oriented more at servers, rather then personal laptop. But OK, I decide to go to the end.


Finally agent was connected to the system

But happiness was not too long, as in 5 min I’ve noticed next: Web filtering and real-time scan not working.

Eventually I found out why: ESET tries to compile and insert custom kernel modules for full protection.
ESET support told me to install gcc-12 – so their agent could compile modules. By the way – I had to wait 23 hours for answer 🙂
The deal is that for real-time protection and web access filtering, ESET needs to:
- Hook into the kernel using kernel modules.
- These modules require compilation against your running kernel.
This is why gcc-12 is mentioned — it’s a compiler version compatible with their modules.
Let me explain main risks in simple words:
- Kernel modules run with high privileges (they’re part of the OS kernel).
- Allowing a third-party application to insert its modules increases your attack surface.
- Bugs in the module, or a compromised ESET agent, could impact kernel-level security.
Now… compiling kernel modules from a closed-source AV vendor? On my daily dev laptop? That’s a red flag. Even if it’s ESET. I didn’t feel comfortable giving root-level access to proprietary code inside my kernel space. So I dropped it.
But before doing that, I tested all 3 solutions at virus, which was created by me during one interesting security offline course. And, here was another surprise – both ClamAV and Bitdefender did not discover it, only ESET would do it:

So, yep, here ESET solution was a winner.
And Then It Hit Me — ClamAV Got Better
Here’s the funny part.
While I was chasing paid solutions, I missed a major update to ClamAV.
ClamAV now supports On-Access Scanning via clamonacc
(from v0.102+). It’s not a true kernel hook, but it uses fanotify
with clamd in the background.
Here’s how I got it working:
Step-by-Step: Hybrid Real-Time Setup with ClamAV
Edit /etc/clamav/clamd.conf
by adding several lines:
# On-Access Scanning Configuration
OnAccessIncludePath /home/user/Downloads
OnAccessPrevention yes
OnAccessExcludeUname clamav
Restart Daemon:
sudo systemctl restart clamav-daemon
Increase inotify watches (optional but helps):
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Run clamonacc:
sudo clamonacc --log=/var/log/clamonacc.log
# or sudo clamonacc --log=/var/log/clamonacc.log --verbose --foreground - for debugging and verifying how all works
Test with EICAR:
cd ~/Downloads
curl -o eicar.txt https://secure.eicar.org/eicar.com.txt
cat eicar.txt
Result:
cat: eicar.txt: Operation not permitted
Pro Tip: Use Hybrid Mode
To avoid system slowdowns:
- Enable notification-only mode for e.g.
/home/user
- Enable prevention mode only for /Downloads
- Use two clamonacc processes with separate include lists. You may also create 2 systemd units for that, installation package with whole that stuff, including some cron that will read notification’s log regularly and send alarms at your alarm panel. But it is out of the scope of that article
Yes, maybe ClamAV is not a perfect solution, probably it’s signatures are worth rather then Bitfender/ESET paid solutions. But it :
- works
- nothing hangs,
- it is safe – there is no remote control or kernel modifications
What I Learned
At some point, I realized I relied too much on ChatGPT to guide this journey.
It helped — sure — but it missed recent ClamAV updates. Only by reading the actual docs, changelogs, and testing myself, I found the real solution.
This made me think…