Date: 2005-02-24T10:11:04 Editor: VincenzoGianferrari Wiki: Apache James Wiki Page: ClamAVScan URL: http://wiki.apache.org/james/ClamAVScan
no comment New Page: = ClamAVScan - antivirus scan mailet using ClamAV's CLAMD daemon = '''''ClamAVScan''''' does an antivirus scan check using the '''ClamAV''' daemon '''CLAMD''' (see http://www.clamav.net/). It interacts directly with the daemon using the "stream" method, which should have the lowest possible overhead. I've done tests getting less than 2.5 seconds of CPU per megabyte scanned on a 1.5 GHz CPU. The CLAMD daemon will typically reside on ''localhost'', but could reside on a different host. It may also consist on a set of multiple daemons, each residing on a different server and on different IP number. In such case a DNS host name with multiple IP adresses (round-robin load sharing) is supported by the mailet (but on the same port number). ClamAV runs on Linux, but there are ports to other OS too. I have ClamAVScan working on Windows XP and 2k using ''ClamAV For Windows'' (see http://www.sosdg.org/clamav-win32) = Initialization parameters = The init parameters are as follows: * '''<debug>'''. * '''<host>''': the host name of the server where CLAMD runs. It can either be a machine name, such as "java.sun.com", or a textual representation of its IP address. If a literal IP address is supplied, only the validity of the address format is checked. If the machine name resolves to multiple IP addresses, ''round-robin load sharing'' will be used. The default is ''localhost''. * '''<port>''': the port on which CLAMD listens. The default is ''3310''. * '''<maxPings>''': the maximum number of connection retries during startup. If the value is ''0'' no startup test will be done. The default is ''6''. * '''<pingIntervalMilli>''': the interval between each connection retry during startup. The default is ''30000'' (30 seconds). * '''<streamBufferSize>''': the BufferedOutputStream buffer size to use when writing to the ''stream connection''. The default is ''8192''. = Behaviour = The actions performed are as follows: * During initialization: 1. Gets all config.xml parameters, handling the defaults; 1. resolves the <host> parameter, creating the round-robin IP list; 1. connects to CLAMD at the first IP in the round-robin list, on the specified <port>; 1. if unsuccessful, retries every <pingIntervalMilli> milliseconds up to maxPings> times; 1. sends a "PING" request; 1. waits for a "PONG" answer; 1. repeats steps 3-6 for every other IP resolved. * For every mail 1. connects to CLAMD at the "next" IP in the round-robin list, on the specified <port>, and increments the "next" index; if the connection request is not accepted, tries with the next one in the list unless all of them have failed; 1. sends a "STREAM" request; 1. parses the "PORT ''streamPort''" answer obtaining the port number; 1. makes a second connection (the ''stream connection'') to CLAMD at the same host (or IP) on the ''streamPort'' just obtained; 1. sends the MimeMessage to CLAMD (using MimeMessage#writeTo(OutputStream)) through the ''stream connection''; 1. closes the ''stream connection''; 1. gets the "OK" or "... FOUND" answer from the main connection; 1. closes the main connection; 1. sets the "org.apache.james.infected" ''mail attribute'' to either "true" or "false"; 1. adds the "X-MessageIsInfected" ''header'' to either "true" or "false", depending on the results of the scan. = ClamAV configuration notes = The following parameters are required in '''clamav.conf''': * '''LocalSocket''' must be commented out * '''TCPSocket''' must be set to a port# (typically 3310) * '''StreamMaxLength''' must be >= the James config.xml parameter <maxmessagesize> in SMTP <handler> * '''MaxThreads''' should? be >= the James config.xml parameter <threads> in <spoolmanager> * '''ScanMail''' must be uncommented = A James config.xml example = Here follows an example of '''config.xml''' definitions deploying CLAMD on localhost, and handling the infected messages: {{{ ... <mailet match="All" class="ClamAVScan" onMailetException="ignore"/> <!-- If infected go to virus processor --> <mailet match="HasMailAttributeWithValue=org.apache.james.infected, true" class="ToProcessor"> <processor> virus </processor> </mailet> ... <!-- Messages containing viruses --> <processor name="virus"> <!-- To avoid a loop while bouncing --> <mailet match="All" class="SetMailAttribute"> <org.apache.james.infected>true, bouncing</org.apache.james.infected> </mailet> <mailet match="SMTPAuthSuccessful" class="Bounce"> <sender>[EMAIL PROTECTED]</sender> <inline>heads</inline> <attachment>none</attachment> <notice>Warning: We were unable to deliver the message below because it was found infected by virus(es).</notice> </mailet> <!-- <mailet match="All" class="ToRepository"> <repositoryPath>file://var/mail/infected/</repositoryPath> </mailet> --> <mailet match="All" class="Null"/> </processor> ... }}}