星期五, 六月 08, 2007

A small hack for logcheck-1.2.45

对于 log filter,logcheck 是比较好的选择,但是从 1.1.1 到 1.2.45,还是有比较大的变化,例如 logtail 由 C 程序改成了 perl 脚本。但最主要的一点是 logcheck-1.2.45 的设计上正交性更好,而且提供了针对各种服务和应用的更多模式,因而可以给管理员更多的自由选择。因此可以省去很多使用 1.1.1 的情况下必须自己编写模式的麻烦,而且 1.2.45 的模式匹配也更为精确。

问题主要在于 logcheck-1.2.45 的安装比较麻烦,而且由于使用的是 shell 脚本,所以平台相关性比较严重一点,而且对于依赖性的检查不好。logcheck-1.2.45 依赖于 lockfile-progs,但除非你安装了 logcheck 并运行,你不会知道这一点,而 lockfile-progs 在安装时也会出现编译错误,因为缺少 lockfile.h 这个头文件,但它并不会告诉你这是因为还需要安装 liblockfile-1.06.2 这个包。

安装了所有这些之后,将 /var/log 拷贝成 /tmp/log,然后:
sh# chown logcheck.logcheck /tmp/log -R
sh# vi /etc/logcheck/logfiles
/tmp/log/messages
/tmp/log/maillog
/tmp/log/secure
sh# su - logcheck
sh$ /usr/sbin/logcheck

不会有输出,从接收到的邮件中分析,发现没有做任何过滤,但是 /etc/logcheck/ignore.d.server/* 中却确实有相应的模式!

因此我分析了一下 /usr/sbin/logcheck 这个 shell 程序,找到寻找模式文件的那部分
......
cleanrules "$RULEDIR/cracking.d" $TMPDIR/cracking
cleanrules "$RULEDIR/violations.d" $TMPDIR/violations
cleanrules "$RULEDIR/violations.ignore.d" $TMPDIR/violations-ignore

# Now clean the ignore rulefiles for the report levels
for level in $REPORTLEVELS; do
cleanrules "$RULEDIR/ignore.d.$level" $TMPDIR/ignore
done

# The following cracking.ignore directory will only be used if
# $SUPPORT_CRACKING_IGNORE is set to 1 in the configuration file.
# This is *only* for local admin use.
if [ $SUPPORT_CRACKING_IGNORE -eq 1 ]; then
cleanrules "$RULEDIR/cracking.ignore.d" $TMPDIR/cracking-ignore
fi
......
cleanrules() {
dir=$1
cleaned=$2

if [ -d $dir ]; then
if [ ! -d $cleaned ]; then
mkdir $cleaned \
|| error "Could not make dir $cleaned for cleaned rulefiles."
fi
for rulefile in $(run-parts --list $dir); do
rulefile=$(basename $rulefile)
if [ -f ${dir}/${rulefile} ]; then
debug "cleanrules: ${dir}/${rulefile}"
if [ -r ${dir}/${rulefile} ]; then
# pipe to cat on greps to get usable exit status
egrep --text -v '^[[:space:]]*$|^#' $dir/$rulefile | cat \
>> $cleaned/$rulefile \
|| error "Couldn't append to $cleaned/$rulefile. Disk Full?"
else
error "Couldn't read $dir/$rulefile"
fi
fi
done
elif [ -f $dir ]; then
error "cleanrules: '$dir' is a file, not a directory"
elif [ -z $dir ]; then
error "cleanrules: called without argument"
fi
}
可以看到,寻找模式文件的操作由 cleanrules() 函数来完成,而实际上有哪些文件需要应用是由 run-parts --list $dir 这个命令来查找的。增加一个 DEBUG 输出来查看有那些 rulefiles 被应用了,结果发现出错信息。

单独运行:
sh# run-parts --list /etc/logcheck/ignore.d.server/
Not a directory: --list
sh# run-parts /etc/logcheck/ignore.d.server/ --list
# EMPTY!
所以这样实际上没有找到任何文件。

从 google search 的情况来看,run-parts 的平台相关性比较大,这个命令是用来寻找一个目录下那些有执行权限的文件的,如果不使用 --list,就会执行这些文件。当然前提是这个 run-parts 有这个参数,而 RHEL4 上面的这个 run-parts 就没有这个参数(实际上只有一个 PATH 参数),而 logcheck 的开发者似乎对 debian 比较熟悉,所以这里不能直接使用。

可以做一个修改,将 run-parts 命令改为:
find $dir -type f -perm +0100
即可。对于使用 ulfs 安装,相应的 profile 为:
sh# cat /usr/src/logcheck/.config
pkgname = "logcheck";
version = "1.2.45";
user = "logcheck";
groups = "";
group = "logcheck";
archive = "logcheck_1.2.45.tar.gz";
command = "tar xfz logcheck_1.2.45.tar.gz";
command = "cd logcheck-1.2.45";
command = "sed -i 's/install -d/mkdir -p/g' Makefile";
command = "sed -i 's/run-parts --list $dir/find $dir -type f -perm +0100/g' src/logcheck";
command = "make";
command = "cd ..";
command = "rm -rf logcheck-1.2.45";
time = "20070608 10:49:35 Fri"
然后,在 /etc/logcheck/ignore.d.server 下,对那些需要用到的模式文件,使用 chmod u+x 增加可执行权限,这样这些文件就会在过滤的时候被用到!因此可以看到这种方法提供了更高的正交性和灵活性。

没有评论: