简介

上次分享了基于Nginx配置文件封禁异常访问的IP的脚本,今天分享基于iptables+Nginx封禁异常访问的IP的脚本。
在运营网站或服务器时,保护系统安全和防范恶意攻击是非常重要的任务之一。
本文将介绍一个自动监控Nginx日志并封禁恶意IP的实用脚本,帮助您及时应对恶意攻击,提高系统的安全性。


脚本介绍

在本文中,我们将分享一个基于Bash脚本的自动封禁恶意IP的解决方案。
该脚本可以在Nginx服务器上运行,实时监控访问日志,并根据预设条件自动封禁恶意IP。这将大大减轻管理员的工作负担,提高服务器的安全性。


实现原理

脚本的实现原理

  1. 定义起始时间和结束时间,用于过滤出最近5分钟内的日志。
  2. 根据起始时间和结束时间,从Nginx日志中提取符合条件的日志并保存到临时文件中。
  3. 从临时文件中提取出所有的IP地址,并保存到另一个临时文件中。
  4. 处理IP地址,只保留前三位,进行排序和去重,并统计每个IP段的请求次数。
  5. 根据设定的阈值(默认为1500次),筛选出请求次数超过阈值的IP段,将其封禁。
  6. 将封禁的IP记录到日志文件中。

脚本详解

脚本

#!/bin/bash
# 定义5分钟以前的时间,用于过滤5分钟以前的日志
start_time=$(LC_TIME=en_US.UTF-8 date -d "-5 minutes" "+%d/%b/%Y:%H:%M")
# 定义为当前时间
end_time=$(LC_TIME=en_US.UTF-8 date "+%d/%b/%Y:%H:%M")
# 需要过滤的nginx日志
log="/data/nginx/log/user_access.log"
#排除列表,如有多个可以这样写 '116\\.179\\.37|116\\.177\\.37'
exclude_nets='116\\.179\\.37'

block_ip() {
    # 截取5分钟以前至当前的日志
    awk -v start="$start_time" -v end="$end_time" -F '[][]' '$2 >= start && $2 <= end' "$log" >/data/nginx/log/tmp_last_minute.log

    # 将所有ip都过滤出来,存到临时文件
    awk '{print $1}' /data/nginx/log/tmp_last_minute.log >/data/nginx/log/tmp_last_minute_ip.log

    # 处理IP,只留前面三位,排除、排序、去重,获取多于1500次请求的ip段,这个数字可以根据实际情况来调整
    awk -F '.' '{print $1"."$2"."$3"."}' /data/nginx/log/tmp_last_minute_ip.log | awk -v nets="$exclude_nets" '!($0 ~ nets)' | sort | uniq -c | sort -n | awk '$1 > 1500 {print $2}' >/data/nginx/log/bad_ip_minute.list

    # 当ip数大于0时,才会将它写入到封禁IP文件中
    ip_n=$(wc -l /data/nginx/log/bad_ip_minute.list | awk '{print $1}')
    if [ ${ip_n} -ne 0 ]; then
        for ip in $(cat /data/nginx/log/bad_ip_minute.list); do
            # 封ip,不能直接封ip段
            for ip2 in $(grep "^$ip" /data/nginx/log/tmp_last_minute_ip.log | sort -n | uniq); do
                /usr/sbin/iptables -I INPUT -s $ip2 -j REJECT
            done
        done
        # 将这些被封的IP记录到日志里
        echo "" >>/data/nginx/log/block_ip2.log
        echo "$(date) 封掉的IP段有:" >>/data/nginx/log/block_ip2.log
        cat /data/nginx/log/bad_ip_minute.list >>/data/nginx/log/block_ip2.log
    fi
    # 这句根据需要配置,我这里是因为5分钟的访问量也太多了,导致日志文件体积太大,所以清空一下
    cat /dev/null >$log
}

unblock_ip() {
    # 先清空计数
    /usr/sbin/iptables -Z
    # 等待2分钟
    sleep 120
    # 检查包个数小于5的ip段并记录到一个临时文件里,把它们标记为白名单IP
    /usr/sbin/iptables -nvL INPUT | grep REJECT | awk '$1<5 {print $8}' >/data/nginx/log/good_ip2.list
    n=$(wc -l /data/nginx/log/good_ip2.list | awk '{print $1}')
    if [ $n -ne 0 ]; then
        for ip in $(cat /data/nginx/log/good_ip2.list); do
            /usr/sbin/iptables -D INPUT -s $ip -j REJECT
        done
        echo "" >>/data/nginx/log/unblock_ip2.log
        echo "$(date) 解封的IP有:" >>/data/nginx/log/unblock_ip2.log
        cat /data/nginx/log/good_ip2.list >>/data/nginx/log/unblock_ip2.log
    fi
    # 当解封完白名单IP后,将计数器清零,进入下一个计数周期
    /usr/sbin/iptables -Z
}

# 检查命令行参数
if [[ $# -ne 1 ]]; then
    echo "请输入参数,block 或者 unblock。"
    exit 1
fi

# 根据命令行参数调用相应的函数
if [[ $1 == "block" ]]; then
    block_ip
elif [[ $1 == "unblock" ]]; then
    unblock_ip
else
    echo "参数输入错误。"
    exit 1
fi

如何使用

# 做成定时任务
# 每5分钟执行一次block操作,每2小时执行一次unblock操作
*/5 * * * * root /data/nginx/log/Block_IP_WAF.sh block
0 */2 * * * root /data/nginx/log/Block_IP_WAF.sh unblock

脚本中各部分的详细解释

  1. 设置起始时间和结束时间: 脚本通过使用date命令设置了起始时间和结束时间,起始时间为5分钟前,结束时间为当前时间。
  2. 截取日志: 使用awk命令根据起始时间和结束时间从Nginx日志中截取出最近5分钟内的日志,并保存到临时文件tmp_last_minute.log中。
  3. 提取IP地址: 使用awk命令从临时文件中提取出所有的IP地址,并保存到另一个临时文件tmp_last_minute_ip.log中。
  4. 处理IP地址: 使用awk命令对IP地址进行处理,只保留前三位,并进行排序、去重和计数。然后根据设定的阈值(1500次),筛选出请求次数超过阈值的IP段,并将其保存到bad_ip_minute.list文件中。
  5. 封禁IP地址: 当存在需要封禁的IP段时,使用iptables命令逐个封禁IP地址。首先,使用grep命令根据IP段提取出具体的IP地址,然后使用iptables命令将这些IP地址添加到封禁列表中。
  6. 记录封禁的IP地址: 将被封禁的IP段记录到日志文件block_ip2.log中,包含封禁时间和被封禁的IP段。
  7. 解封IP地址: 使用iptables命令清空计数器,等待2分钟。然后,检查请求次数小于5次的IP段,并将其记录到good_ip2.list文件中,标记为白名单IP。最后,使用iptables命令逐个解封白名单IP
  8. 记录解封的IP地址: 将被解封的IP地址记录到日志文件unblock_ip2.log中,包含解封时间和被解封的IP地址。

使用方法

脚本接受一个参数,即blockunblock,用于执行相应的功能。
通过运行脚本并传入合适的参数,可以实现IP封禁和解封的操作。


结语

本文介绍了一个自动封禁恶意IPNginx日志监控脚本。
通过定时运行该脚本,您可以及时发现并封禁恶意IP,提高服务器的安全性。
希望本文能够帮助您改善服务器安全,并为您的技术工作提供一些灵感。
如有疑问或建议,请随时留言。


文章作者: Runfa Li
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Linux 小白鼠
网络 Shell Linux Linux 网络 iptables 防火墙 Centos7 shell Centos7 nginx 动态封禁ip 封禁ip 防爬虫
觉得文章不错,打赏一点吧,1分也是爱~
打赏
微信 微信
支付宝 支付宝