Rough notes on how to setup clamav-milter with Sendmail for malware scanning with Clam AntiVirus (clamav). Malware is a general term encompassing viruses, trojan horses, worms: software that may damage or render insecure computers and networks.
These notes reference clamav 0.65 (with references to configuration filename changes introduced in 0.80) and Sendmail 8.12.10 compiled from source. Only general setup notes are provided, as I currently run clamav from MIMEDefang.
The following image shows an overview of the three daemons involved (sendmail, clamav-milter, and clamd), the connecting socket files /var/run/clamav-milter.sock and /var/run/clamav.sock between the daemons, along the configuration files for the daemons and log paths to syslogd. The clamd daemon should be started before clamav-milter, and finally sendmail, as clamd and clamav-milter create the socket files used for communication.
Setup
- Sendmail requires MILTER support.
- libmilter* library must be installed.
- clamav must be configured with --enable-milter.
- Configure clamd.conf.
- Launch clamd.
- Launch clamav-milter with appropriate command line arguments.
- Configure Sendmail to use the clamav-milter socket.
To see whether sendmail supports MILTER, run the following command. If MILTER is listed in the output, skip to the next step. Sendmail 8.13 enables MILTER by default. Some vendors provide ports or packages of Sendmail: consult these before compiling from scratch. On RedHat linux, install the sendmail and sendmail-devel packages.
$ sendmail -d0 < /dev/null | grep MILTER
Compiled with: DNSMAP LOG MAP_REGEX MATCHGECOS MILTER MIME7TO8 MIME8TO7
Adding MILTER support to Sendmail 8.12 usually involves adding the following entries to a site.config.m4 used to build Sendmail from source then rebuilding Sendmail. The second entry is disabled with dnl for debugging, though can be enabled if clamav-milter is not running as the root user.
APPENDDEF(`confENVDEF', `-DMILTER')
dnl APPENDDEF(`conf_libmilter_ENVDEF', `-D_FFR_MILTER_ROOT_UNSAFE')
To rebuild sendmail from a site.config.m4, use the Build script with the -f option.
$ sh Build -c -f /etc/mail/site.config.m4
In addition to sendmail, the libmilter* library must be installed. The install location of the library and supporting header files will vary by system.
$ locate libmilter | grep /usr/local
/usr/local/include/sendmail/libmilter
/usr/local/include/sendmail/libmilter/mfapi.h
/usr/local/include/sendmail/libmilter/mfdef.h
/usr/local/include/sendmail/libmilter/milter.h
/usr/local/lib/libmilter.a
If the library is not installed, go to the Sendmail source directory, change into the libmilter subdirectory and run the install script.
$ cd libmilter
$ sh Build install
Some operating systems provide MILTER support via a port or package. Check with your vendor before compiling from scratch.
$ ./configure --enable-milter …
This must be done on a system where the libmilter library and header files have also been installed to a location that clamav can find.
Important configuration options for clamd are as follows. Also be sure to set the LocalSocket option to be a secure file location only readable by the clamav user.
LocalSocket /var/run/clamav.sock
LogSyslog
FixStaleSocket
StreamSaveToDisk
# set this below confMAX_MESSAGE_SIZE for Sendmail
StreamMaxLength 10M
User clamav
ScanMail
ScanArchive
ArchiveMaxFileSize 10M
Verbose logging or debugging mode may be required when first learning how to run clamav.
The clamd daemon will need to be listening to the file given by the LocalSocket option before clamav-milter is started.
$ sudo /usr/local/sbin/clamd
Review the --help options to clamav-milter for the various options supported, and experiment with test messages once sendmail is configured and running before putting clamav-milter onto a production system.
$ sudo /usr/local/sbin/clamav-milter --max-children=2 -olb \
local:/var/run/clamav-milter.sock
The --max-children=2 limit is only for testing, and will need to be increased on a production mail server.
Set the following in the proper *.mc configuration file for sendmail, and rebuild sendmail.cf from that. Consult my Sendmail Configurations for more information about sendmail.mc and configuring Sendmail.
INPUT_MAIL_FILTER(`clamav', `S=local:/var/run/clamav-milter.sock, F=T, T=S:4m;R:4m')
The F=T causes messages to be bounced with a Simple Mail Transport Protocol (SMTP) temporary failure if clamd-milter has problems running properly. You may want to remove this statement if you prefer e-mail getting through over being tempfailed. Consult the “X — Mail Filter (Milter) Definitions” section of doc/op/op.ps under the Sendmail source for more information on mail filters, notably the flags (F) and timeout (T) options. Note that different vendors will hide the socket file in different locations; solving this problem is a simple matter of ensuring any parent directory files of the socket exist and have the correct permission, and that the Sendmail and clamav-milter processes use the same location.
Once sendmail.cf is rebuilt, restart Sendmail.
Debugging
- clamav Logging
- Permissions
- Sendmail Logging
- Socket path problems
- Timeout vs. External errors
Set LogVerbose and either configure clamd.conf to log to a local system file or to syslog. Be sure to restart clamd and clamav-milter after changing the configuration file.
Ensure all the daemons have permission to talk to the required socket files. This will require determining what user each daemon is running as, and whether that user can access the appropriate socket. Tools such as lsof and ktrace(1) or strace(1) will help.
Try increasing the Sendmail LogLevel setting, while submitting messages with known malware to Sendmail. Restart sendmail after increasing the LogLevel.
$ grep LogLevel /etc/mail/sendmail.cf
O LogLevel=15
Sendmail logs via the syslog(3) protocol, so the configuration of the syslogd(8) daemon will need to be consulted to see where the mail logs are being sent to. Usually, /etc/syslog.conf will list the log file locations.
$ grep mail /etc/syslog.conf
*.err;kern.debug;auth.notice;mail.crit /dev/console
*.info;kern.debug;mail.none /var/log/messages
mail.info /var/log/maillog
The socket path to the clamav-milter process must be the same in both the Sendmail configuration file (sendmail.cf, configured via sendmail.mc) and how clamav-milter is setup.
socket-addr (local:/var/run/clamav/clamav-milter) doesn't agree with sendmail.cf
Determine what path sendmail.cf sets to the clamav-milter socket file, and either change sendmail.mc to agree with what clamav-milter wants, or change how clamav-milter is run to use the path set in sendmail.cf.
$ grep clamav /etc/mail/sendmail.cf
O InputMailFilters=clamav
Xclamav, S=local:/var/run/clamav-milter.sock, F=T, T=S:4m;R:4m
If clamav-milter reports --timeout must not be given if --external is not given errors, launch the milter using clamav-milter --timeout=0.