In the last few months, I upgraded my personal server from CentOS 7 to Red Hat Enterprise Linux 8 (with a free developper account). I have many services running on it, and one of them is my email server composed of 4 pieces of software: Dovecot, Exim, SpamAssassin and Clamav (clamd).
I have had a hard time making all this work together, especially the virus scanning part. Especially, having Exim to scan emails through the local clamd socket made me totally upset. It seems that in the latest RHEL / clamd updates, something has been broken. Either I could not get Clamd to start, or if it could start, Exim got a “permission denied” trying to access the clamd socket. Here are the messages I encountered:
When I could start clamd with default settings, Exim gave me the following error:
1nj2d9-000Rui-F7 malware acl condition: clamd /run/clamd.scan/clamd.sock : unable to connect to UNIX socket (/run/clamd.scan/clamd.sock): Permission denied
This is because Exim did not have write access to the local socket file. Even though I put the Exim user in the clamscan group, for some obscure reasons, Exim was still unable to send the scanning requests to clamd.
When Clamd was configure to change the ownership to the virusgroup group, clamd would refuse to start:
systemd: Starting clamd scanner (scan) daemon…
clamd: WARNING: Ignoring deprecated option AllowSupplementaryGroups at /etc/clamd.d/scan.conf:99
clamd: ERROR: Failed to change socket ownership to group virusgroup
systemd: email@example.com: Control process exited, code=exited status=1
systemd: firstname.lastname@example.org: Failed with result 'exit-code'.
systemd: Failed to start clamd scanner (scan) daemon.
This all seems to have been documented in some places, but most bugs encoutered are rather old and were corrected using a deprecated setting in the /etc/clamd.d/scan.conf:
Since the setting is deprecated, and I could not get the local socket to work correctly with Exim, I thought “What if I used it through TCP, just like spamassassin”. After a big 5 minutes of searching in the config files, I came up with a pretty secure solution: using the localhost IP address (127.0.0.1) and a custom TCP port, 3310, that was already suggested in the scan.conf file.
Here is the part that made it work in /etc/clamd.d/scan.conf:
Then, in /etc/exim/exim.conf, you have to change the av_scanner line:
av_scanner = clamd:127.0.0.1 3310
With these lines in, I issued:
# systemctl restart clamd@scan
# systemctl restart exim
Tadam! Now Exim can scan incoming and outgoing messages through a local TCP socket, which is inaccessible from other servers/clients, which means it’s secure enough.
Make sure clamd is not listening on anything else (public or private IP, other than 127.0.0.1), cause it has no authentication or access control, and could be disabled by any attacker who can telnet to it, causing a denial of service.