ClamAV with Rspamd and ISPConfig on Ubuntu
Howto setup ClamAV as antivirus mailfilter for Rspamd and Monit monitoring.
Versions used for this tutorial: Ubuntu 20.04, ISPConfig 3.2.7p1, Rspamd 3.1, Dovecot 3.2.7.2, ClamAV 0.103.2, Monit 5.26.0.
Rspamd
Set permissions
The permission of the _rspamd user is required for the clamav group, otherwise Rspamd can’t connect to ClamAV over Unix socket
usermod -a -G clamav _rspamd
chown -R clamav:clamav /var/run/clamav
If the permissions are not set the following error occurs:
CLAM_VIRUS_FAIL (0) [failed to scan and retransmits exceed]
ClamAV
vi /etc/clamav/clamd.conf
PidFile /var/run/clamav/clamd.pid
LocalSocket /var/run/clamav/clamd.ctl
TCPSocket 3310
TCPAddr localhost
# https://betatim.github.io/posts/clamav-memory-usage/
ConcurrentDatabaseReload no
Check configfile
egrep -v '(^.*#|^$)' /etc/clamav/clamd.conf
PidFile /var/run/clamav/clamd.pid
LocalSocket /var/run/clamav/clamd.ctl
TCPSocket 3310
TCPAddr localhost
ConcurrentDatabaseReload no
Debug false
FixStaleSocket true
LocalSocketGroup clamav
LocalSocketMode 666
User clamav
ScanMail true
ScanArchive true
DatabaseDirectory /var/lib/clamav
LogFile /var/log/clamav/clamav.log
.
.
.
Restart ClamAV
Can take about 20 seconds to restart until all signatures are loaded.
service clamav-daemon restart
ClamAV logfile
tail -f /var/log/clamav/clamav.log
Wed Dec 8 14:58:29 2021 -> --- Stopped at Wed Dec 8 14:58:29 2021
Wed Dec 8 14:58:29 2021 -> +++ Started at Wed Dec 8 14:58:29 2021
Wed Dec 8 14:58:29 2021 -> Received 0 file descriptor(s) from systemd.
Wed Dec 8 14:58:29 2021 -> clamd daemon 0.103.2 (OS: linux-gnu, ARCH: x86_64, CPU: x86_64)
Wed Dec 8 14:58:29 2021 -> Log file size limited to 4294967295 bytes.
Wed Dec 8 14:58:29 2021 -> Reading databases from /var/lib/clamav
Wed Dec 8 14:58:29 2021 -> Not loading PUA signatures.
Wed Dec 8 14:58:29 2021 -> Bytecode: Security mode set to "TrustSigned".
Wed Dec 8 14:58:48 2021 -> Loaded 8581819 signatures.
Wed Dec 8 14:58:53 2021 -> TCP: Bound to [127.0.0.1]:3310
Wed Dec 8 14:58:53 2021 -> TCP: Setting connection queue length to 15
Wed Dec 8 14:58:53 2021 -> LOCAL: Unix socket file /var/run/clamav/clamd.ctl
Wed Dec 8 14:58:53 2021 -> LOCAL: Setting connection queue length to 15
Wed Dec 8 14:58:53 2021 -> Limits: Global time limit set to 120000 milliseconds.
Wed Dec 8 14:58:53 2021 -> Limits: Global size limit set to 104857600 bytes.
Wed Dec 8 14:58:53 2021 -> Limits: File size limit set to 26214400 bytes.
Wed Dec 8 14:58:53 2021 -> Limits: Recursion level limit set to 16.
Wed Dec 8 14:58:53 2021 -> Limits: Files limit set to 10000.
Wed Dec 8 14:58:53 2021 -> Limits: MaxEmbeddedPE limit set to 10485760 bytes.
Wed Dec 8 14:58:53 2021 -> Limits: MaxHTMLNormalize limit set to 10485760 bytes.
Wed Dec 8 14:58:53 2021 -> Limits: MaxHTMLNoTags limit set to 2097152 bytes.
Wed Dec 8 14:58:53 2021 -> Limits: MaxScriptNormalize limit set to 5242880 bytes.
Wed Dec 8 14:58:53 2021 -> Limits: MaxZipTypeRcg limit set to 1048576 bytes.
Wed Dec 8 14:58:53 2021 -> Limits: MaxPartitions limit set to 50.
Wed Dec 8 14:58:53 2021 -> Limits: MaxIconsPE limit set to 100.
Wed Dec 8 14:58:53 2021 -> Limits: MaxRecHWP3 limit set to 16.
Wed Dec 8 14:58:53 2021 -> Limits: PCREMatchLimit limit set to 10000.
Wed Dec 8 14:58:53 2021 -> Limits: PCRERecMatchLimit limit set to 5000.
Wed Dec 8 14:58:53 2021 -> Limits: PCREMaxFileSize limit set to 26214400.
Wed Dec 8 14:58:53 2021 -> Archive support enabled.
Wed Dec 8 14:58:53 2021 -> AlertExceedsMax heuristic detection disabled.
Wed Dec 8 14:58:53 2021 -> Heuristic alerts enabled.
Wed Dec 8 14:58:53 2021 -> Portable Executable support enabled.
Wed Dec 8 14:58:53 2021 -> ELF support enabled.
Wed Dec 8 14:58:53 2021 -> Mail files support enabled.
Wed Dec 8 14:58:53 2021 -> OLE2 support enabled.
Wed Dec 8 14:58:53 2021 -> PDF support enabled.
Wed Dec 8 14:58:53 2021 -> SWF support enabled.
Wed Dec 8 14:58:53 2021 -> HTML support enabled.
Wed Dec 8 14:58:53 2021 -> XMLDOCS support enabled.
Wed Dec 8 14:58:53 2021 -> HWP3 support enabled.
Wed Dec 8 14:58:53 2021 -> Self checking every 3600 seconds.
Ports needed for ClamAV and Rspamd
egrep "3310/tcp|1133./tcp" /etc/services
clamd 3310/tcp
rspamd-proxy 11332/tcp
rspamd-worker 11333/tcp
rspamd-controller 11334/tcp
rspamd-fuzzy 11335/tcp
Ports listening
netstat -unplet|egrep "rspamd|clamd"
tcp 0 0 127.0.0.1:3310 0.0.0.0:* LISTEN 116 25296614 3832209/clamd
tcp 0 0 127.0.0.1:11332 0.0.0.0:* LISTEN 121 24594822 3792817/rspamd: mai
tcp 0 0 127.0.0.1:11333 0.0.0.0:* LISTEN 121 24594832 3792817/rspamd: mai
tcp 0 0 127.0.0.1:11334 0.0.0.0:* LISTEN 121 24594827 3792817/rspamd: mai
Monit
ClamAV should be monitored by Monit and restarted if it crashes just because there is not enough memory available for ClamAV. If this is the case, an oom-kill („Out of memory“) is logged in the syslog file.
grep clamav /var/log/syslog | grep kernel | grep oom-kill
Dec 02 19:41:27 ispconfig-server kernel: [1067957.981524] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/system.slice/clamav-daemon.service,task=clamd,pid=1598671,uid=116
Create configfile
vi /etc/monit/conf-available/clamd
check process clamd with pidfile /var/run/clamav/clamd.pid
group virus
start program = "/etc/init.d/clamav-daemon start"
stop program = "/etc/init.d/clamav-daemon stop"
if failed unixsocket /var/run/clamav/clamd.ctl then restart
if 5 restarts within 5 cycles then timeout
Enable monitoring for ClamAV daemon
ln -s /etc/monit/conf-available/clamd /etc/monit/conf-enabled/
Check control file syntax
monit -t
Control file syntax OK
Restart Monit
service monit restart
Monit logfile
tail -f /var/log/monit.log
[CET Dec 12 21:46:34] info : Monit daemon with pid [1598641] stopped
[CET Dec 12 21:46:34] info : 'ispconfig.server.xx' Monit 5.26.0 stopped
[CET Dec 12 21:46:34] info : Starting Monit 5.26.0 daemon with http interface at [localhost]:2812
[CET Dec 12 21:46:34] info : 'ispconfig.server.xx' Monit 5.26.0 started
Monit ist now configured for ClamAV and will restart the daemon automatically if it is not running anymore.
Monit summary
monit summary
Monit 5.26.0 uptime: 4m
┌─────────────────────────────────┬────────────────────────────┬───────────────┐
│ Service Name │ Status │ Type │
├─────────────────────────────────┼────────────────────────────┼───────────────┤
│ clamd │ OK │ Process │
├─────────────────────────────────┼────────────────────────────┼───────────────┤
Monit status
monit status
Process 'clamd'
status OK
monitoring status Monitored
monitoring mode active
on reboot start
pid 1610658
parent pid 1
uid 116
effective uid 116
gid 124
uptime 3h 12m
threads 2
children 0
cpu 0.0%
cpu total 0.0%
memory 30.8% [1.2 GB]
memory total 30.8% [1.2 GB]
security attribute unconfined
disk read 0 B/s [619.0 MB total]
disk write 0 B/s [584 kB total]
unix socket response time 0.102 ms to /var/run/clamav/clamd.ctl type TCP protocol DEFAULT
data collected Sun, 05 Dec 2021 22:56:21
Rspamd antivirus configuration for ClamAV
vi /etc/rspamd/local.d/antivirus.conf
servers = "127.0.0.1:3310";
#servers = "/var/run/clamav/clamd.ctl";
Restart Rspamd
service rspamd restart
Rspamd Logfile
tail -f /var/log/rspamd/rspamd.log | grep clamav
2021-12-08 15:21:58 #3838455(main) <whndhf>; lua; antivirus.lua:185: added antivirus engine clamav -> CLAM_VIRUS
ISPConfig
vi /usr/local/ispconfig/server/conf-custom/install/rspamd_antivirus.conf.master
#######################################################################################
# ISPConfig:
# vi /usr/local/ispconfig/server/conf-custom/install/rspamd_antivirus.conf.master
# ispconfig_update.sh --force
#######################################################################################
clamav {
# If set force this action if any virus is found (default unset: no action is forced)
action = "reject";
# Scan mime_parts separately - otherwise the complete mail will be transferred to AV Scanner
scan_mime_parts = true;
# Scanning Text is suitable for some av scanner databases (e.g. Sanesecurity)
scan_text_mime = true;
scan_image_mime = true;
# If `max_size` is set, messages > n bytes in size are not scanned
#max_size = 20000000;
# symbol to add (add it to metric if you want non-zero weight)
symbol = "CLAM_VIRUS";
# type of scanner: "clamav", "fprot", "sophos" or "savapi"
type = "clamav";
# For "savapi" you must also specify the following variable
#product_id = 12345;
# You can enable logging for clean messages
log_clean = true;
# servers to query (if port is unspecified, scanner-specific default is used)
# can be specified multiple times to pool servers
# can be set to a path to a unix socket
# Enable this in local.d/antivirus.conf
servers = "127.0.0.1:3310";
#servers = "/var/run/clamav/clamd.ctl";
# if `patterns` is specified virus name will be matched against provided regexes and the related
# symbol will be yielded if a match is found. If no match is found, default symbol is yielded.
patterns {
# symbol_name = "pattern";
JUST_EICAR = "^Eicar-Test-Signature$";
}
patterns_fail {
# symbol_name = "pattern";
CLAM_PROTOCOL_ERROR = '^unhandled response';
}
# `whitelist` points to a map of IP addresses. Mail from these addresses is not scanned.
whitelist = "/etc/rspamd/antivirus.wl";
}
Reconfigure Rspamd and restart services
ispconfig_update.sh --force
.
.
.
Reconfigure Services? (yes,no,selected) [yes]: yes
The following custom templates were found:
/usr/local/ispconfig/server/conf-custom/install/rspamd_antivirus.conf.master
Do you want to rename these conf-custom templates now so the default templates are used? (yes,no) [no]: no
.
.
.
Restarting services ...
Update finished.
Check Rspamd antivirus config file
egrep -v '(^.*#|^$)' /etc/rspamd/local.d/antivirus.conf
clamav {
action = "reject";
scan_mime_parts = true;
scan_text_mime = true;
scan_image_mime = true;
symbol = "CLAM_VIRUS";
type = "clamav";
log_clean = true;
servers = "127.0.0.1:3310";
patterns {
JUST_EICAR = "^Eicar-Test-Signature$";
}
patterns_fail {
CLAM_PROTOCOL_ERROR = '^unhandled response';
}
whitelist = "/etc/rspamd/antivirus.wl";
}
Finished!
Send yourself the EICAR test virus and watch the logfiles
Download EICAR test virus
wget https://secure.eicar.org/eicar.com --no-check-certificate && gzip eicar.com
Send test virus
swaks --to [email protected] --from [email protected] --attach - --server localhost < eicar.com.gz
If swaks (Swiss Army Knife for SMTP) is not installed, make up for it
apt -y install swaks
rspamd.log
tail -f /var/log/rspamd/rspamd.log | grep clamav
2021-12-11 19:04:10 #1117948(normal) <beac17>; task; rspamd_task_write_log: id: ... ... forced: reject "clamav: virus found: "Win.Test.EICAR_HDB-1""; score=nan (set by clamav), settings_id: ispc_spamfilter_user_6
clamav.log
tail -f /var/log/clamav/clamav.log | grep FOUND
Sat Dec 11 19:04:10 2021 -> instream(127.0.0.1@60986): Win.Test.EICAR_HDB-1(d3c03a1d552e6b7eed704e6e24d7b9d7:98) FOUND
syslog
tail -f /var/log/syslog | grep clamav
Dec 11 19:04:10 ispconfig-server postfix/cleanup[1119725]: 5B52180772: to=<[email protected]>, relay=none, delay=0.22, delays=0.22/0/0/0, dsn=5.7.1, status=bounced (clamav: virus found: "Win.Test.EICAR_HDB-1")
Rspamd GUI
swapfile
4 GB RAM seems to be not enough for ClamAV, so let’s create a swapfile
dd if=/dev/zero of=/swapfile bs=1M count=4096
chmod 0600 /swapfile
mkswap /swapfile
swapon /swapfile
swapfile is now active
swapon --show
NAME TYPE SIZE USED PRIO
/swapfile file 4G 310.7M -2
free -h
total used free shared buff/cache available
Mem: 3.7Gi 2.2Gi 451Mi 485Mi 1.1Gi 823Mi
Swap: 4.0Gi 353Mi 3.7Gi
Make swapfile permanent after reboot
vi /etc/fstab
/swapfile none swap sw 0 0