Nginx 恶意 IP 屏蔽脚本:禁止每小时访问超过1000次的IP地址访问

太多机器人了,将服务器压的破烂不堪,写了一个脚本,解决这个问题:

  1. 每小时检测所有IP访问次数,超过 1000 次就添加到 ban.list 中,返回 403
  2. 检测成功后发送邮件通知
  3. 这个 nginx 在 Docker 中
#!/bin/bash

# 配置路径及变量
LOG_FILE="/var/logs/nginx/wwwaccess.log"
BAN_FILE="/etc/nginx/conf/ban.www.appinn.list"
NGINX_CONTAINER="nginx-1"
SMTP_SERVER="邮件服务器"
SMTP_PORT="2525"
FROM_EMAIL="发信邮箱"
TO_EMAIL="收信邮箱"
SUBJECT="新添加 ban.list.conf 地址"
MAIL_BODY="/tmp/nginx_ban_mail.txt"

# 查找访问超过1000次的IP(排除403)
BAD_IPS=$(awk '$9 != 403 {print $1}' "$LOG_FILE" | sort | uniq -c | sort -nr | awk '$1 > 1000 {print $2}')

if [ -z "$BAD_IPS" ]; then
    echo "没有超限IP"
    exit 0
fi

# 标记添加信息
ADD_STR=""
for ip in $BAD_IPS; do
    # 确保这个IP还没被ban
    if ! grep -q "deny $ip;" "$BAN_FILE"; then
        echo "deny $ip;" >> "$BAN_FILE"
        ADD_STR="$ADD_STR$ip"$'\n'
    fi
done

if [ -z "$ADD_STR" ]; then
    echo "无新IP需要ban"
    exit 0
fi

# 测试nginx配置
docker exec $NGINX_CONTAINER nginx -t
if [ $? -ne 0 ]; then
    echo "nginx 配置测试失败"
    exit 1
fi

# 重载nginx配置
docker exec $NGINX_CONTAINER nginx -s reload
if [ $? -eq 0 ]; then
    RESTART_INFO="nginx重启成功"
else
    RESTART_INFO="nginx重载失败"
fi

# 组织邮件内容
echo -e "新ban IP列表:\n$ADD_STR\n$RESTART_INFO" > "$MAIL_BODY"

# 发送邮件(使用swaks简易SMTP命令行工具)
swaks --server "$SMTP_SERVER" --port "$SMTP_PORT" --tls-optional \
      --from "$FROM_EMAIL" --to "$TO_EMAIL" \
      --header "Subject: $SUBJECT" --body "$MAIL_BODY"

# 清理临时文件
rm -f "$MAIL_BODY"

我的 SMTP 服务器是用了 smtp to telegram,实际上并没有发信,而是一个 tg 通知。

另外,1000次可能也比较高了,一个正常人类,一个小时能有500次都很不错了。

如果今后服务器还是被压迫的不行,就继续调低这个数值。

1 个赞

Screen-20250831142824@2x.png

这东西有点立竿见影了。

不过我要考虑另外一件事情:IP太多,可能 nginx 扛不住,还是要上 iptables 么?

我用WAF

image.png

这种有开源可以免费用的么

大概是这种东西?

具体看许可证吧,你说的这个确实可以商用,
UUWAF的社区版本也可以商用。
雷池社区版不能商用。

太烦了,我就5M带宽,4.999 全是机器人

1 个赞

kong gateway 搭配流量控制插件

具体?

感觉套一个CF会好点。其他的性能成本感觉会比较高的。

国内服务器

开源的话可以看看(不过我没用过)GitHub - crowdsecurity/crowdsec: CrowdSec - the open-source and participative security solution offering crowdsourced protection against malicious IPs and access to the most advanced real-world CTI.

反爬虫会比较艰难,原站的CDN没相关的功能么?反正成本最后成本要么落到服务器上,要么落到云服务商那。

kong也可以试试,但印象里配置要求比较高。

fail2ban可以专门干这个事情,包括发送邮件

1 个赞

不反,我只挡住太多的流量即可。现在是每天服务器被ddos了差不多

你的需求看上去套上腾讯的免费CDN也很合适

我没搞定实名验证…

不得不说,在3天以后,现在恶意IP的数量,从最开始的20条,减少到好几个小时一条。