clamdscan uses the daemon of the virus scanner clamav to check emails and the like for viruses. If you use Courier-mta, you are probably using mailfilter for local delivery in many cases. The easiest way to use clamav seems to be to configure it in the .mailfiter configuration file and use it from there[1], but then
lstat() failed: Permission denied. ERROR
an error like this appears, and it does not work properly. This seems to be because clamd runs with the privileges of the clamd user and therefore cannot read the mail files.
To avoid this, you can use clamscan instead of clamdscan, but performance is far too poor because it loads the virus database every time.
In the end, it took me several hours to investigate, but the most useful reference was the article titled “HOWTO_Install_Courier_with_maildrop_and_ClamAV_and_SpamA.”
According to it, first prepare /usr/bin/clamdscan.sh as follows.
#!/bin/bash
# Created by Tom Walsh, slim at ala.net
# slightly modified by Wolfgang Ziegler, nuppla at gmx.at
# RUN=clamscan
# Enable this line, if you are using the clamav-daemon.
RUN=clamdscan
#start
MSG=$(< /proc/self/fd/0) # stdin -> $MSG
SCAN=$(echo "$MSG" | $RUN - --stdout --disable-summary)
EXIT="$?"
VIRUS=$(echo "$SCAN" | awk '{print $2}')
SUBJECT=$(echo "$MSG" | reformail -x Subject:)
if [ "$EXIT" == "1" ]; then
SUBJECT="**VIRUS** [$VIRUS] $SUBJECT"
MSG=$(echo "$MSG" | reformail -i"X-Virus-Status: INFECTED")
MSG=$(echo "$MSG" | reformail -i"Subject: $(echo "$SUBJECT")")
else
MSG=$(echo "$MSG" | reformail -i"X-Virus-Status: CLEAN")
fi
echo "$MSG"
exit 0
Make this file executable.
chmod +x /usr/bin/clamscan.sh
Then add the following to .mailfilter.
MAILDIR="$HOME/Maildir"
DEFAULT="$MAILDIR"
FOLDERS="$DEFAULT/."
SPAM="${FOLDERS}junk"
CLAMDSCAN="/usr/bin/clamdcan.sh"
`${CLAMDSCAN}`
if ( /^X-Virus-Status:.*INFECTED/ )
{
log "Clamdscan: Virus found\n"
to $SPAM
}
This probably works now… Clamav will inspect even the contents of ZIP files, which is a good point.
If all you want to do is drop messages with attachments such as .exe[2], there is no need to bring clamav into the picture; something like the following will do.
# attachments are in the body, so :b flag
if ( /^Content-type: (audio|application)/:b \\
&& /name=.*\\.(bat|com|exe|hta|pif|scr|shs|vb[es]|ws[fh])/:b )
{
xfilter "${REFORMAIL} -a'$SPAMHEADER potential virus attachment'"
log "Illegal Extention\n"
to $SPAM
}
If you absolutely do not want to receive emails like this, you could exit instead of using to $SPAM, but sometimes you want to read just the body, after all. It may also be possible to use reformail to strip the attachment section, but I have been too lazy to try it.
Well, then.
[1] You could say it should be installed on the mail server itself, but this was easier at a personal level. I will also try doing it with perlmailfilter if I can find the time to set up a test server.
[2] It has been a topic of discussion for the past few days because of the Pension Service leak.
Related posts

Installing an SSL Certificate with Let’s Encrypt, Now Certbot
This article is outdated. Most Linux distributions should now support Certbot packages, so please use those.If custom configuration is needed, it will probably concern how to…

Setting Up Name-Based HTTPS Virtual Hosts (SNI) with Let’s Encrypt
Let's Encrypt is a free TLS server-certificate service provided by the US foundation Internet Security Research Group (ISRG). Its motto is free, automated, secure, transparent, open,…
Let’s Call Japan Post’s Digi-Ad API and Retrieve an “Address.” Is It Really OAuth?
Sorry for the long gap after I became unwell. In the previous article, I obtained a Japan Post Digital Address (Digi-Ad) and used it in Japan…
