Something I always wanted to have in my Zimbra installations is virus check via VirusTotal. My initial idea was to have a Zimlet that would add this feature to the WebUI, a new action for a mail attachment. This solution is good because you won’t likely hit the limits of the free version of VirusTotal, but has the downside that the final user is in charge of doing the check! So an optional feature could allow a sysadmin to force virus check for all attachments. Sadly I never had time to start developing and I’ve never been able to convince anyone of my idea, so it remained a wish.
But then I ran into amavisvt.
AmavisVT is a plugin for Amavisd which, as done for any other antivirus engine, submits attachments to VirusTotal via API.
By creating an account to VirusTotal you can obtain an API key and perform requests via GET calls. There’s a free tier usage quota which is mostly fine for a small/medium traffic mailserver, the big limit is the 4 requests/minute which can often be hit. Unfortunately paid subscription are rather expensive, they can start from around 20k$.
The installation is pretty easy. It was a little complicated in the beginning, but now it’s almost straightforward. I’m very unfamiliar with Python programs, so there could be better ways to do it. Feel free to comment or submit a mail.
First let’s get the source from GitHub. You can either download the ZIP and unpack it somewhere or directly clone the repo. I often choose the latter:
git clone https://github.com/ercpe/amavisvt.git /usr/local/src/amavisvt
cd /usr/local/src/amavisvt
Now that we have the source let’s build it. From the same path above:
apt install python3-pip
pip3 install -r requirements.txt
python3 setup.py install
This will install the AmavisVTd package in /usr/local/lib/python3.5/dist-packages/amavisvt-0.5.3-py3.5.egg/amavisvt/
. Again I don’t know if this is the best place, but works.
Let’s configure it for Zimbra usage. Create /etc/amavisvt.cfg
with the following content (of course changing YOUR_VT_API_KEY):
[DEFAULT]
api-key = YOUR_VT_API_KEY
database-path = /opt/zimbra/data/amavisvt.sqlite3
[daemon]
socket-path = /opt/zimbra/data/clamav/amavisvtd.sock
You can of course have a look at the example config file to find more options.
Now let’s make the plugin start at boot by copying the systemd unit file. Before this action edit the file and add User=zimbra
in [Service] section.
cp etc/amavis-vtd.service /etc/systemd/system
systemctl daemon-reload
systemctl enable amavis-vtd
systemctl start amavis-vtd
Last step: configure Zimbra’s Amavisd to use this additional scanner. Open /opt/zimbra/conf/amavisd.conf.in
and add the following in the @av_scanners
group:
['AmavisVTd',
\&ask_daemon, ["CONTSCAN {}\n", "/opt/zimbra/data/clamav/amavisvtd.sock"],
undef,
qr/(?:Detected as) (.*)/m,
qr/(?:Detected as) (.*)/m],
Restart Zimbra’s amavisd and you’re done, your mails will pass through VirusTotal!
You can tail messages to see if it’s working properly with journalctl -fu amavis-vtd
. You will likely see several messages like this:
Nov 03 06:25:34 mail.server.com amavisvtd[11591]: 2019-11-03 06:26:54,419 ERROR [Thread-10975] Error asking virustotal about files
Nov 03 06:25:34 mail.server.com amavisvtd[11591]: File "/usr/local/lib/python3.5/dist-packages/amavisvt-0.5.3-py3.5.egg/amavisvt/client.py", line 529, in check_vt
Nov 03 06:25:34 mail.server.com amavisvtd[11591]: raise Exception("API-Limit exceeded!")
Nov 03 06:25:34 mail.server.com amavisvtd[11591]: Exception: API-Limit exceeded!
Nov 03 06:25:34 mail.server.com amavisvt[11591]: Thread-10970 - Error asking virustotal about files
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/amavisvt-0.5.3-py3.5.egg/amavisvt/client.py", line 529, in check_vt
raise Exception("API-Limit exceeded!")
Exception: API-Limit exceeded!
which, as the message says, the API quota limit has been exceeded. You can safely ignore the message, usual ClamAV scan have been performed anyway.
I see there are some ways to mitigate quota limits, like using caches. I haven’t looked into them yet, might do in the future. If you have suggestions feel free to leave a comment.
Can work with alternative like https://github.com/maliceio/malice
Interesting project, unfortunately it looks unmantained. I found there’s Cuckoo Sandbox, I wish I had the time to investigate in it 🙂
how is the speed? or delay in mail incoming/outgoing?
I’ve modified config.py to randomly select one of a series of API keys. Next is to change it to a queue…
@property
def apikey(self):
apikeys = self.get(‘DEFAULT’, ‘api-key’).split(“,”)
r = randint(1,len(apikeys))-1
return apikeys[r]