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