Guide based on this blog post by Daniel Aleksandersen and the ArchLinux Wiki. None of these worked perfectly on their own and some modifications were made to accommodate for that. The setup that this configuration belongs to is:
- Laptop (This guide is not meant for servers, additional configuration is most likely required)
- Fedora 41
Fedora has some extra configuration that needs to happen before setting up ClamAV to work properly. The components are:
clamdfreshclam
Install the packages:
1sudo dnf install clamav freshclam clamd
Start by enabling the antivirus scanning option of SELinux:
1sudo setsebool -P antivirus_can_scan_system 1
freshclam
Start by generating initial configuration for freshclam. Freshclam is ran under the user clamupdate.
1clamconf -g freshclam.conf > freshclam.conf
2sudo mkdir /etc/freshclam.conf
3sudo chown root:root /etc/freshclam.conf
4sudo chmod u=rw,go=r /etc/freshclam.conf
Apply the following diff:
15,7d4
2< # Comment out or remove the line below.
3< Example
4<
514c11
6< #LogFileMaxSize 5M
7---
8> LogFileMaxSize 100M
918c15
10< #LogTime yes
11---
12> LogTime yes
1345c42
14< #DatabaseDirectory /var/lib/clamav
15---
16> DatabaseDirectory /var/lib/clamav
1762c59
18< #DatabaseOwner clamupdate
19---
20> DatabaseOwner clamupdate
2180c77
22< #DatabaseMirror database.clamav.net
23---
24> DatabaseMirror database.clamav.net
25186c183
26< #Bytecode yes
27---
28> Bytecode yes
Run a virus definition update and additionally enable the freshclam service:
Enabling the service will perform periodic updating. This is in contrast to the blog post that used cron for this functionality.
clamd
Start by generating initial configuration for the daemon. The scanning service will be ran under the user clamscan.
1clamconf -g clamd.d/scan.conf > scan.conf
2sudo mkdir /etc/clamd.d/
3sudo chown root:root /etc/clamd.d/scan.conf
4sudo chmod u=rw,go=r /etc/clamd.d/scan.conf
The following options were changed in my file, which are based of the ArchLinux guide’s recommended settings, however, not exact:
15,7d4
2< # Comment out or remove the line below.
3< Example
4<
535c32
6< #LogFileMaxSize 5M
7---
8> LogFileMaxSize 50M
939c36
10< #LogTime yes
11---
12> LogTime yes
1348c45
14< #LogSyslog yes
15---
16> LogSyslog yes
1766c63
18< #ExtendedDetectionInfo yes
19---
20> ExtendedDetectionInfo yes
2188c85
22< #LocalSocket /tmp/clamd.socket
23---
24> LocalSocket /var/run/clamd.scan/clamd.socket
2592c89
26< #LocalSocketGroup virusgroup
27---
28> LocalSocketGroup virusgroup
2996c93
30< #LocalSocketMode 660
31---
32> LocalSocketMode 660
33100c97
34< #FixStaleSocket yes
35---
36> FixStaleSocket yes
37135c132
38< #MaxThreads 20
39---
40> MaxThreads 8
41176c173
42< #MaxDirectoryRecursion 15
43---
44> MaxDirectoryRecursion 20
45219c216
46< #VirusEvent /opt/send_virus_alert_sms.sh
47---
48> VirusEvent /opt/clamav/virus-event.sh
49250c247
50< #User clamav
51---
52> User clamscan
53254c251
54< #Bytecode yes
55---
56> Bytecode yes
57284c281
58< #DetectPUA yes
59---
60> DetectPUA yes
61307c304
62< #ScanPE yes
63---
64> ScanPE yes
65314c311
66< #ScanELF yes
67---
68> ScanELF yes
69320c317
70< #ScanMail yes
71---
72> ScanMail yes
73386c383
74< #ScanHTML yes
75---
76> ScanHTML yes
77393c390
78< #ScanOLE2 yes
79---
80> ScanOLE2 yes
81398c395
82< #AlertBrokenExecutables yes
83---
84> AlertBrokenExecutables no
85403c400
86< #AlertBrokenMedia yes
87---
88> AlertBrokenMedia no
89425c422
90< #AlertOLE2Macros no
91---
92> AlertOLE2Macros yes
93439c436
94< #AlertPartitionIntersection yes
95---
96> AlertPartitionIntersection yes
97445c442
98< #ScanPDF yes
99---
100> ScanPDF yes
101451c448
102< #ScanSWF yes
103---
104> ScanSWF yes
105457c454
106< #ScanXMLDOCS yes
107---
108> ScanXMLDOCS yes
109463c460
110< #ScanHWP3 yes
111---
112> ScanHWP3 yes
113469c466
114< #ScanArchive yes
115---
116> ScanArchive yes
117634c631,637
118< #OnAccessIncludePath /home
119---
120> OnAccessIncludePath /home
121> OnAccessIncludePath /mnt
122> OnAccessIncludePath /media
123> OnAccessIncludePath /etc
124> OnAccessIncludePath /usr
125> OnAccessIncludePath /opt
126> OnAccessIncludePath /dev
127656c659,660
128< #OnAccessExcludeUname clamuser
129---
130> OnAccessExcludeUname clamupdate
131> OnAccessExcludeUname clamscan
132663c667
133< #OnAccessMaxFileSize 5M
134---
135> OnAccessMaxFileSize 5M
136671c675,676
137< #OnAccessPrevention yes
138---
139> # Warning: Setting to yes can increase package install times by 1000x
140> OnAccessPrevention no
141675c680
142< #OnAccessExtraScanning yes
143---
144> OnAccessExtraScanning yes
VirusEvent
You might have noticed the VirusEvent option that triggers when a virus is found is set to execute /opt/clamav/virus-event.sh. Set it up by running the following commands:
Save the following file contents:
Set permissions:
1sudo chmod u=rwx,go= /opt/clamav/virus-event.sh
2sudo chown clamscan:clamscan /opt/clamav/virus-event.sh
Starting the Daemon
Controlled through SystemD unit files. The daemon has the possibility to freeze your system (a lot of times), so the blog post recommends to set system resource limits by overriding the systemd files.
1sudo systemctl edit clamd@
Add the following overrides:
[Service]
Nice=18
IOSchedulingClass=idle
CPUSchedulingPolicy=idle
Activate the daemon:
Enabling OnAccessScan
OnAccessScan allows ClamAV to scan files on demand as the users access them. This is useful to have as it provides constant security at the cost of speed. To enable the service that runs the OnAccessScan, edit the service to add passing file-descriptors instead of paths:
1sudo systemctl edit clamav-clamonacc.service
Add the following overrides (the reason is explained in the ArchLinux guide):
[Service]
ExecStart=
ExecStart=/usr/sbin/clamonacc -F --fdpass --config-file=/etc/clamd.d/scan.conf
Reload and enable:
Testing
This will test if a fake virus is detected. The file in the URL is harmless (it’s a txt file).
Manual
1curl https://secure.eicar.org/eicar.com.txt | clamscan -
Realtime Protection
cd ~/Downloads
wget https://secure.eicar.org/eicar.com.txt
cat eicar.com.txt
Check the logs:
1journalctl -eu clamav-clamonacc.service
If a notification did not appear, then please look at the workaround for VirusEvent below, as you may have encountered a ClamAV bug.
Using clamdscan
With clamd running in the background, we can use clamdscan. It’s like clamscan but uses the config from /etc/clamd.d/scan.conf as it uses the clamd@scan daemon we enabled previously:
1clamdscan --multiscan --infected --log clamav.log $HOME
File Permission Issues
You might notice that trying to use clamdscan, gives you a variety of errors:
--------------------------------------
/home/yiannis: File path check failure: Permission denied. ERROR
----------- SCAN SUMMARY -----------
Infected files: 0
Total errors: 1
Time: 0.002 sec (0 m 0 s)
Start Date: 2025:02:17 23:45:20
End Date: 2025:02:17 23:45:20
In order to fix this issue, the parameter --fdpass needs to be included; clamdscan -mil clamav.log --fdpass $HOME. This will make clamscan (ran under the $USER) pass the file descriptor to clamd (ran under clamscan), allowing the clamscan user to bypass the file permissions of the home folder.
LocalSocket Issues
At this point, another error with local socket permissions should appear:
ERROR: Could not connect to clamd on LocalSocket /var/run/clamd.scan/clamd.socket
This is caused because the clamdscan process (ran under $USER) does not have permissions to access the socket; owned by clamscan and part of the virusgroup group. The solution to this:
1sudo usermod -aG virusgroup $USER
Log out and log back in. Now clamdscan should work (don’t forget to pass --fdpass.
VirusEvent Workaround
There’s an issue that ClamAV is facing where VirusEvent is not working. A user suggested a workaround where we deploy an extra script to read the logs and trigger the virus event manually. Keep this while the issue is open. After the issue is resolved, you can delete all the work done in this section.
Notifier Script
Start by creating a script the notifier script:
1sudo nvim /opt/clamav/clamonacc-log-notifier.sh
This script is responsible for scanning the log file and creating the virus events.
Monitor Script
Create the monitor script that will feed the log file to the notifier script.
1sudo nvim /opt/clamav/clamonacc-log-monitor.sh
This script pipes the output of the journal which contains the logs from the OnAccessScan service to the notifier script.
Set appropriate permissions for both scripts:
1sudo chmod --reference=/opt/clamav/virus-event.sh /opt/clamav/clamonacc-log-notifier.sh /opt/clamav/clamonacc-log-monitor.sh
2sudo chown --reference=/opt/clamav/virus-event.sh /opt/clamav/clamonacc-log-notifier.sh /opt/clamav/clamonacc-log-monitor.sh
Service File
Now create a service file to run these two scripts:
1sudo nvim /etc/systemd/system/clamav-clamonacc-notifier.service
This simply waits for all other services to start, then run the script as root:
[Unit]
Description=ClamAV On-Access Notifier (Workaround for VirusEvent being broken in ClamAV)
Requires=clamav-clamonacc.service
After=clamav-clamonacc.service syslog.target network.target
[Service]
Type=simple
User=root
ExecStart=/opt/clamav/clamonacc-log-monitor.sh
Restart=always
[Install]
WantedBy=multi-user.target
Enable the service:
Reversing the Workaround
Effort was put to make the VirusEvent workaround changes as minimal as possible. When the issue is fixed, reverse the changes by running the following commands:
1sudo systemctl stop clamav-clamonacc-notifier
2sudo systemctl disable clamav-clamonacc-notifier
3sudo systemctl daemon-reload
4sudo rm /etc/systemd/system/clamav-clamonacc-notifier.service /opt/clamav/clamonacc-log-monitor.sh /opt/clamav/clamonacc-log-notifier.sh
These commands stop and delete the service from the system and delete the remaining scripts that were created.
Install GUI - ClamTK
ClamTK is a GUI front-end for ClamAV. Its main limitation is that it doesn’t allow you to configure ClamAV in any meaningful way. It contains some basic utilities such as scanning files and directories. To install it run the following command:
1sudo dnf install clamtk
I personally don’t find it that useful.
Existing Issues
While my research into this program has resolved most of the issues, I have still am facing the following problems. If you know how to resolve them, please get in touch.
Duplicate Reports in clamav-clamonacc
- It can be observed that when running:
journalctl --follow -eu clamav-clamonacc, and an infected file is accessed, multiple entries are created. I don’t think this is intended behaviour.
Running clamdscan
The following problems are produced when running the command:
1clamdscan --quiet -mil clamav.log --fdpass -i $HOME
STDOUT
- The output of the command is a lot of these lines:
LibClamAV Warning: cli_realpath: Invalid arguments.
LOG FILE
- When running clamdscan, I get a
WARNING: [FILE]: Not supported file typeon some entries. I thought that the--infectedin conjunction with--quietoption would work. This is not the case! - When running clamdscan, I get a
[FILE]: Failed to open fileon some entries. I thought that the--infectedin conjunction with--quietoption would work. This is not the case!