I have the following problem: how to scan incoming ftp files without using proftpd mod_clamav in Debian Lenny. Why? The reason is simple. I use Debian for my servers due it's stability and compiling my self proftpd to support mod_clamav leads to problems I could not manage in time, like recompiling every time there are a security bug, etc. A script running, let's say every minute, from a cron-job, should be fine. So I have a solution, but I don't know how to implement, because I don't know bash. If there is anybody who know bash and he/she's willing to help me, this is what should be implement it: ProFTPD write the transfer log in /var/log/proftpd/xferlog. Here is an example: Sat Feb 5 19:14:12 2011 0 vip-srv1.grupnet.ro 68 /home/vhost/template/template.tld/public_html/eicar.com.txt a _ i r [email protected] ftp 0 * c a_i means ascii incoming; /home/vhost/template/template.tld/public_html/eicar.com.txt is the full path to uploaded file The bash script (scan_incomming_ftp.sh) should check if in the last xx seconds from current time there was the following records in xferlog: a _ i or b _ i, that's meaning upload. If that is true then should extract from the log the names of the uploaded files and create a string with all matches (let's say the string is incoming_files). At the end the script should call clamdscan with incoming_files as parameter + --remove. A more elaborated version could mail the administrator to let him know the user who done bad things. Thank You very much in advance.
I give a partial answer my self Here is a partial answer; the script is written in php PHP: #!/usr/bin/php <?php /** * Scan Incoming ProFTPd files * @copyright Marius Ionel <[email protected]> */ // We need to initialize variables $CheckInterval = 60; // check interval in seconds; 1 minute should be enough $PathToLog = '/var/log/proftpd/xferlog'; // path to log file, including file $FilesToScan = ''; // Files need to be checked by antivirus // Let's rock'n'roll // get current time $EndCheckTime = time(); // compute the interval to check $StartCheckTime = $EndCheckTime - $CheckInterval; // get the log file as array in reversed order $ArrayLog = array_reverse(file($PathToLog)); // parse the array log to find a mathc in date and file operation $ParseLog=TRUE; $LogCounter=0; while ($ParseLog==TRUE){ // get the current line of the log $CurrentLogLine = explode(' ', $ArrayLog[$LogCounter]); // get date from the current log line $LogLineDate= strtotime($CurrentLogLine[0] . ' ' . $CurrentLogLine[1] . ' ' . $CurrentLogLine[2] . ' ' . $CurrentLogLine[3] . ' ' . $CurrentLogLine[4] . ' ' . $CurrentLogLine[5]); // Check the date from the current log line if($LogLineDate >=$StartCheckTime) { // curent line is in interval, but it is a realy upload? $CurrentLogOperation=$CurrentLogLine[10] . $CurrentLogLine[11] . $CurrentLogLine[12]; if($CurrentLogOperation=='a_i' || $CurrentLogOperation=='b_i'){ // upload $FilesToScan=$FilesToScan . $CurrentLogLine[9] . ' '; } // increment the counter to check another line $LogCounter++; } else { // nothing to check in the current interval $ParseLog=FALSE; break; } } // Let's check if we have files to scan if($FilesToScan<>'') { // call the antivirus with $FilesToScan as parameter. // Obviosly we delete the virused files! // clamdscan ... } // get the current time again $ExecutionTime = time(); // We should run as a daemon, so sleep until we should run again time_sleep_until($ExecutionTime - $CheckInterval); // we should call it's self ?>