如何使用 clamav 仅扫描过去 24 小时的文件

如何使用 clamav 仅扫描过去 24 小时的文件

我创建了一个 bash 脚本,通过 clamav 扫描整个服务器中的病毒。该脚本每晚都会通过 cron 运行。因此,我只想扫描过去 24 小时内添加的文件。目前,我在脚本中使用以下命令:

find /home -type f -mmin -1440  -print0 | xargs -0 -r clamscan --infected

但是它太慢了,find 命令是导致它慢的原因吗?如果是这样,那么使用 clamscan 扫描过去 24 小时的文件的更好方法是什么?clamav 有没有什么选项可以做到这一点?

任何帮助将非常感激。

答案1

我在寻找 clamscan 脚本时偶然发现了这个页面。我按照上述建议操作,并让它运行起来:

#!/usr/bin/bash
# Create Hourly Cron Job With Clamscan

# Directories to scan
scan_dir="/home"

# Temporary file
list_file=$(mktemp -t clamscan.XXXXXX) || exit 1

# Location of log file
log_file="/var/log/clamav/hourly_clamscan.log"

# Make list of new files
if [ -f  "$log_file" ]
then
        # use newer files then logfile
        find "$scan_dir" -type f -cnewer "$log_file" -fprint "$list_file"
else
        # scan last 60 minutes
        find "$scan_dir" -type f -cmin -60 -fprint "$list_file"
fi

if [ -s "$list_file" ]
then
        # Scan files and remove (--remove) infected
        clamscan -i -f "$list_file" --remove=yes > "$log_file"

        # If there were infected files detected, send email alert
        if [ `cat $log_file | grep Infected | grep -v 0 | wc -l` != 0 ]
        then
                HOSTNAME=`hostname`
                echo "$(egrep "FOUND" $log_file)" | mail -s "VIRUS PROBLEM on $HOSTNAME" -r     [email protected] [email protected]
        fi
else
        # remove the empty file, contains no info
        rm -f "$list_file"
fi
exit

对我来说这是一个按小时运行的脚本,但应该可以每天运行(修改第二个发现)。

答案2

根据实际受影响的文件数量,我认为 2 小时对于病毒扫描来说不算太长。无论如何,您可以尝试通过以下方式提高速度:

find结果输出到文件中,而不是通过管道传输xargs,然后clamscan--file-list=FILE选项一起使用。这可能会缩短运行时间,因为clamav只需要启动和初始化一次,而不是多次。请发表评论并告诉我这能加快多少速度。

另一个选项(或附加选项)是将扫描限制到某些易受攻击的文件类型,但就我个人而言,我不喜欢这种方法。

答案3

我还没有测试过,但我计划将 clamscan 运行与备份运行集成。我的备份工具会生成修改的文件列表以执行增量备份,那么为什么要重新计算两次相同的文件列表呢?

我使用 dirvish 创建备份,它使用底层的 rsync。最后,我收到一份log.bz2所有已备份文件的报告,其中包括已备份文件的列表。

该脚本将从最新备份genclamfilelist.sh中提取文件列表并打印出来:log.bz2

#!/bin/sh

AWK=/usr/bin/awk
BUNZIP2=/bin/bunzip2
HEAD=/usr/bin/head
HOSTNAME=/bin/hostname
LS=/bin/ls
SED=/bin/sed

SNAPSHOT_HOME=/path/to/dirvish/snapshots

   for vaultHome in ${SNAPSHOT_HOME}/*; do

      # vault naming convention: <hostname>-<sharename>
      vaultName="`echo ${vaultHome} | ${SED} -e 's/^.*\/\([^\/]\+\)$/\1/'`"
      vaultHost="`echo ${vaultName} | ${SED} -e 's/\([^\-]\+\)\-.*$/\1/'`"

      # only proceed if vault being considered is for the same host
      if [ "${vaultHost}" = "`${HOSTNAME}`" ]; then
         logfile="`${LS} -1t ${vaultHome}/20??????-???? \
                      | ${HEAD} -1 \
                      | ${SED} -e 's/^\(.*\)\:$/\1/'`/log.bz2"

         if [ -f ${logfile} ]; then
            ${BUNZIP2} -c ${logfile} | ${AWK} '
               /^$/ {
                  if (start) {
                     start=0
                  }
               }

               {
                  if (start) {
                     print $0
                  }
               }

               /^receiving\ file\ list\ \.\.\.\ done$/ {
                  start=1
               }' | ${SED} -e "s/^\(.*\)$/\/\1/"
         fi
         # else skip - no log file found, probably backup didn't run or failed
      fi
      # else skip - another vault
   done

exit 0

/etc/cron.d/clamavcron 脚本将使用文件列表:

# /etc/cron.d/clamav: crontab fragment for clamav
CLAMAV_FILELIST=/tmp/clamav_filelist_`/bin/hostname`.txt

# run every night
0 19 * * *     root      /usr/bin/test -f ${CLAMAV_FILELIST} && /usr/bin/clamscan --any-desired-options --file-list=${CLAMAV_FILELIST} && /bin/rm ${CLAMAV_FILELIST}

由于我使用了 dirvish,因此我修改了它/etc/dirvish/dirvish-cronjob以调用第一个脚本来生成供最后一个脚本使用的文件列表:

# ...
/usr/sbin/dirvish-expire --quiet && /usr/sbin/dirvish-runall --quiet rc=$?

# v--- BEGIN ADDING NEW LINES
touch /tmp/clamav_filelist_`hostname`.txt
chmod 400 /tmp/clamav_filelist_`hostname`.txt
/usr/local/bin/genclamfilelist.sh >> /tmp/clamav_filelist_`hostname`.txt
# ^--- END ADDING NEW LINES

umount /mnt/backup0 || rc=$?
# ...

相关内容