inotify-tools实时监控网站文件被修改情况

有时我们发现自己的网站被入侵,被黑客留下一些黑链或者其他后门,排除起来非常头疼。那么有没有办法对网站的所有文件进行监控,监控一些重要文件被人修改了就会有记录呢?

使用Linux服务器,我们可以使用 inotify-tools 工具对网站文件进行实时监控。以下是整个实施步骤:

1、安装 inotify-tools 组件

首先需要明白 inotify-tools 是一个监控的组件,它是利用了 Linux 的inotify的功能开发的比较好用的监控组件。

[root@localhost ~]# wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
[root@localhost ~]# tar xzf inotify-tools-3.14.tar.gz
[root@localhost ~]# cd inotify-tools-3.14
[root@localhost ~]# ./configure --prefix=/usr && make && su -c 'make install'

安装过程中可能会出现一些小问题:

如果出现这个错误“/usr/local/bin/inotifywait: error while loading shared libraries: libinotifytools.so.0”可以采用以下办法解决:

[root@localhost ~]# ln -sv /usr/local/lib/libinotify* /usr/lib/
[root@localhost ~]# ln -s /usr/local/lib/libinotifytools.so.0 /usr/lib64/libinotifytools.so.0
[root@localhost ~]# cp /usr/lib/libinotifytools.so.0 /usr/local/lib/

2.inotifywait 和 inotifywatch 使用方法

inotifywait 可以实时监控某个目录下的所有文件的事件

语法:inotifywait [-hcmrq] [-e ] [-t ] [–format ] [–timefmt ] [ … ]

inotifywatch 统计监控事件

语法:inotifywatch [-hvzrqf] [-e ] [-t ] [-a ] [-d ] [ … ]

3.项目实例

最近做了一个小的监控项目:对服务器上所有网站的php文件、js文件以及网站首页index.html进行实时监控。

3.1 制作监控脚本

#!/bin/bash
echo 8192000 > /proc/sys/fs/inotify/max_user_watches
inotifywait -mrq --excludei '.*cache.*|.*data.*|^.*\.(gz|zip|xml|htm|txt|png|jpg|gif|css|mp4|swp|swx|log)$' --timefmt '%Y-%m-%d %H:%M:%S' --format  '%T %w%f %e' --event create,modify  /www/web | while read date time file event
  do
        case $event in
                CREATE | MODIFY)
                A=".php"
                B=".js"
                C="public_html/index.html"
                if [[ $file == *$A ]] || [[ $file == *$B ]] || [[ $file == *$C ]]
                then
                file1=${file:9}
                file2=${file1%%/*}
                datetime=$date' '$time
                uid1=${event}${file}${datetime}
                uid=`echo -n $uid1|md5sum`
                sql="insert ignore into log(uid,type,file,time,site) values('${uid}','${event}','${file}','${datetime}','${file2}')"
                mysql -hlocalhost -P3306 -ujiankong -pjiankong jiankong -e"${sql}"
                fi

                ;;
        esac
  done

说明:

(1)echo 8192000 > /proc/sys/fs/inotify/max_user_watches 这个是增加inotify的监控数量,默认只有8192个,如果文件数量超过这个就需要增加这句。

(2)–excludei ‘.*cache.*|.*data.*|^.*\.(gz|zip|xml|htm|txt|png|jpg|gif|css|mp4|swp|swx|log)$’ 这里是排除监控目录/www/web里面包含cache和data目录,以及gz|zip|xml|htm|txt|png|jpg|gif|css|mp4|swp|swx|log后缀的文件。

(3)由于监控规则只提供了排除哪些内容,所以排除规则不彻底。于是,在下面再做一次判断 A=”.php” B=”.js” C=”public_html/index.html” if [[ $file == *$A ]] || [[ $file == *$B ]] || [[ $file == *$C ]] 这里就是必须是.php 或 .js 或public_html/index.html结尾的文件。

(4)为了记录监控的事件,我这里将监控记录写入到数据库中,当然你必须要创建一个数据库。

(5)为了避免插入的监控数据重复,我在数据表中加入了唯一字符uid

3.2 后台运行脚本

做好的脚本,我们将它运行起来,并且使用Linux后台运行。这样我们关闭SSH终端,监控命令依旧在运行。(不过服务器重启会关闭)

[root@localhost ~]# nohup /etc/init.d/jiankong.sh

3.3 将脚本加入开机自启动

把上面的监控脚本放入到 /etc/init.d/ 目录,然后加入自启动

[root@localhost ~]# ln -s /etc/init.d/jiankong.ssh /etc/rc.d/rc3.d/S79jiankong

附录:inotifywait 和 inotifywatch 详细参数

inotifywait 可以实时监控某个目录下的所有文件的事件

语法:inotifywait [-hcmrq] [-e ] [-t ] [–format ] [–timefmt ] [ … ]

参数:
-h,–help
输出帮助信息
@
排除不需要监视的文件,可以是相对路径,也可以是绝对路径。
–fromfile
从文件读取需要监视的文件或排除的文件,一个文件一行,排除的文件以@开头。
-m, –monitor
接收到一个事情而不退出,无限期地执行。默认的行为是接收到一个事情后立即退出。
-d, –daemon
跟–monitor一样,除了是在后台运行,需要指定–outfile把事情输出到一个文件。也意味着使用了–syslog。
-o, –outfile
输出事情到一个文件而不是标准输出。
-s, –syslog
输出错误信息到系统日志
-r, –recursive
监视一个目录下的所有子目录。
-q, –quiet
指定一次,不会输出详细信息,指定二次,除了致命错误,不会输出任何信息。
–exclude
正则匹配需要排除的文件,大小写敏感。
–excludei
正则匹配需要排除的文件,忽略大小写。
-t , –timeout
设置超时时间,如果为0,则无限期地执行下去。
-e , –event
指定监视的事件。
-c, –csv
输出csv格式。
–timefmt
指定时间格式,用于–format选项中的%T格式。
–format
指定输出格式。
%w 表示发生事件的目录
%f 表示发生事件的文件
%e 表示发生的事件
%Xe 事件以“X”分隔
%T 使用由–timefmt定义的时间格式

inotifywatch 统计监控事件

语法:inotifywatch [-hvzrqf] [-e ] [-t ] [-a ] [-d ] [ … ]

参数:
-h, –help
输出帮助信息
-v, –verbose
输出详细信息
@
排除不需要监视的文件,可以是相对路径,也可以是绝对路径。
–fromfile
从文件读取需要监视的文件或排除的文件,一个文件一行,排除的文件以@开头。
-z, –zero
输出表格的行和列,即使元素为空
–exclude
正则匹配需要排除的文件,大小写敏感。
–excludei
正则匹配需要排除的文件,忽略大小写。
-r, –recursive
监视一个目录下的所有子目录。
-t , –timeout
设置超时时间
-e , –event
只监听指定的事件。
-a , –ascending
以指定事件升序排列。
-d , –descending
以指定事件降序排列。

可监听事件

access 文件读取
modify 文件更改。
attrib 文件属性更改,如权限,时间戳等。
close_write 以可写模式打开的文件被关闭,不代表此文件一定已经写入数据。
close_nowrite 以只读模式打开的文件被关闭。
close 文件被关闭,不管它是如何打开的。
open 文件打开。
moved_to 一个文件或目录移动到监听的目录,即使是在同一目录内移动,此事件也触发。
moved_from 一个文件或目录移出监听的目录,即使是在同一目录内移动,此事件也触发。
move 包括moved_to和 moved_from
move_self 文件或目录被移除,之后不再监听此文件或目录。
create 文件或目录创建
delete 文件或目录删除
delete_self 文件或目录移除,之后不再监听此文件或目录
unmount 文件系统取消挂载,之后不再监听此文件系统。

PS:由于我对 shell 语法不是非常熟悉,特别是正则规则。所以写出的勉强可以用,并不是最优的代码。需要不断完善。↖(^ω^)↗

本文内容参考了以下文章:

http://www.cnblogs.com/luoine/articles/4332314.html

http://www.cnblogs.com/luoine/articles/4332380.html

http://anxue071.blog.51cto.com/2750845/884946

https://www.cnblogs.com/nerxious/archive/2013/01/18/2866548.html

http://blog.csdn.net/hudashi/article/details/6877351

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注