inotify-tools 是一个用C语言库,一个为Linux提供简单inotify接口的命令行程序。这些程序可以用于监视文件系统事件并执行相应操作。这些程序是用C语言来写的,除了需要Linux内核的inotify支持外,没有其他的依赖。inotify-tools 3.14是目前最新版本,其于2010年3月7日发布。
那么什么inotify又是什么?
inotify,它是Linux在内核 2.6.13 (June 18, 2005)版本中引入的一个新功能,它为用户态监视文件系统的变化提供了强大的支持,允许监控程序打开一个独立文件描述符,并针对事件集监控一个或者多个文件,例如打开、关闭、移动/重命名、删除、创建或者改变属性。
下面脚本目的是: 实时检测nginx访问日志, 提取remote_addr, 并对比iptables配置文件, 如果没有的话就自动更新iptables
安装inotify:
yum install inotify-tools
# 2019-08-17更新:
坑点1: 可以自动修复iptables报错, 方法是查出报错行, 然后递归删除, 之所以要递归删除, 是因为journalctl报错只能看到执行到哪一行报的, 不能显示全部报错行, 只能是依次reload iptables才能找到所有报错行.
坑点2: 之前用journalctl -n 50 -u iptables 去查找最后50行日志, 导致iptables被误删了好多规则, 观察报错, 一般是最后8行是最近一次reload的日志, 所以改成了journalctl -n 7 -u iptables.
monitor.sh:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
#!/bin/bash iptables="/etc/sysconfig/iptables" port="12345" fix_error() { error_lines="$(journalctl -n 7 -u iptables| grep "`date +%H:%M:%S`" | grep 'Error occurred at line' | \ awk '{print $NF}' | awk '!a[$0]++')" # 替换一个或多个空格, 或者换行符, 或者结尾符为 ';d' sed_del=$(echo $error_lines | sed 's/[ ][ ]*\|\n\|$/d;/g') sed -i "${sed_del}" $iptables systemctl reload iptables if [[ $? -ne 0 ]]; then fix_error fi } add_ip_to_iptables(){ new_ip=$1 if ! iptables -nvL | grep ${port} | awk '{print $8}' | grep "$new_ip" > /dev/null 2>&1; then new_ip_1=$(echo $new_ip | sed 's#/#\\/#') if ! grep -E -q "${new_ip_1}.*.${port}" $iptables; then sed -i "/#vpn/a -A INPUT -s $new_ip -m state --state NEW -m tcp -p tcp --dport ${port} -j ACCEPT" $iptables fi systemctl reload iptables if [[ $? -ne 0 ]]; then fix_error else echo "$update_time: Added $new_ip into iptables" fi fi } del_ip_from_iptables(){ new_ip=$1 if iptables -nvL | grep ${port} | awk '{print $8}' | grep "$new_ip" > /dev/null 2>&1; then new_ip_1=$(echo $new_ip | sed 's#/#\\/#') if grep -E -q "${new_ip_1}.*.${port}" $iptables; then sed -i "/${new_ip_1}.*.${port}/d" $iptables fi systemctl reload iptables if [[ $? -ne 0 ]]; then fix_error else echo "$update_time: Deleted $new_ip from iptables" fi fi } inotifywait -mqr -e modify --timefmt '%Y-%m-%d %H:%M:%S' --format '%w %f %e %T' /data/logs/nginx/ip_access.log | \ while read file; do #echo $file file_name=$(echo $file | cut -d" " -f1) #EVENT=$(echo $file | awk '{print $2}') update_time=$(echo $file | cut -d" " -f3,4) # real ip remote_addr=$(tail -n1 $file_name|cut -d'|' -f1) # request request=$(tail -n1 $file_name | awk -F'|' '{print $4}'| cut -d" " -f2) request_ip=$(echo $request | awk -F'/' '$2~/add/{print $NF}' | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}") add_ip_to_iptables ${remote_addr} if [[ "$request" == "/open" ]]; then add_ip_to_iptables '0.0.0.0/0' elif [[ "$request" == "/close" ]]; then del_ip_from_iptables '0.0.0.0/0' elif [[ ! -z $request_ip ]]; then add_ip_to_iptables $request_ip fi done |
启动:
1 |
nohup /opt/scripts/monitor_remoteip_change.sh > /data/logs/iptables_changes.log 2>&1 & |
加入开机启动:
1 |
echo 'nohup /opt/scripts/monitor_remoteip_change.sh > /data/logs/iptables_changes.log 2>&1 &' >> /etc/rc.local |
0 Comments