我创建了一个 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/clamav
cron 脚本将使用文件列表:
# /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=$?
# ...