Nginx服务器遭持续攻击致控制台日志泛滥,求助解决方法
Nginx服务器遭持续攻击致控制台日志泛滥,求助解决方法
我来帮你分析问题并给出针对性的解决方案,首先你遇到的核心问题有两个:
- 宿主机的ufw/iptables规则没生效——因为你的Nginx是容器化部署的,宿主机的INPUT链规则无法直接拦截进入容器的流量;
- Nginx的错误日志持续刷控制台——可以通过Nginx配置直接关闭特定路径/IP的错误日志,或者在容器网络层面彻底拦截恶意IP。
方案一:修复宿主机防火墙规则,拦截容器入站流量
你之前用iptables -A INPUT -s 94.130.56.244 -j DROP没效果,是因为容器的入站流量走的是DOCKER-USER链(属于FORWARD链的子链),而非INPUT链。正确的命令应该是:
# 拦截特定IP的所有容器入站流量 iptables -A DOCKER-USER -s 94.130.56.244 -j DROP # 保存规则(Ubuntu下需先安装iptables-persistent) iptables-save > /etc/iptables/rules.v4
这个规则会作用于所有Docker容器的入站请求,从根源上阻断该IP的访问,自然就不会产生Nginx错误日志了。
方案二:修改Nginx配置,禁止特定路径/IP的错误日志
如果不想从网络层面拦截,只想让控制台不再刷日志,可以通过Nginx配置精准关闭特定请求的错误日志,有两种方式:
方式1:针对/.well-known/acme-challenge/路径关闭错误日志
在你的Nginx server块中添加以下配置:
location ^~ /.well-known/acme-challenge/ { # 保留你原有的IP拦截规则 deny 94.130.56.244; # 将该路径的错误日志重定向到/dev/null(即不记录) error_log /dev/null; # 可选:若需保留严重错误,可指定日志级别为crit # error_log /dev/null crit; }
修改后重启Nginx容器:
docker restart nginx_1
之后该路径的错误日志就不会输出到控制台了。
方式2:针对特定IP全局关闭错误日志
如果要彻底屏蔽该IP的所有错误日志,可以在Nginx的http块中使用map模块定义变量,动态控制日志输出:
http { # 定义变量:匹配指定IP时不记录错误日志 map $remote_addr $log_errors { 94.130.56.244 0; default 1; } # 其他全局配置... server { # 你的server配置... # 只有当$log_errors为1时才记录错误日志 error_log /var/log/nginx/error.log if=$log_errors; } }
这种方式更灵活,不会影响其他IP的错误日志记录。
方案三:进入容器网络命名空间添加拦截规则
如果上述宿主机规则仍不生效(比如Docker网络模式不是默认的bridge),可以直接进入Nginx容器的网络命名空间添加iptables规则:
- 先获取Nginx容器的PID:
docker inspect -f '{{.State.Pid}}' nginx_1
- 进入容器的网络命名空间并添加拦截规则:
nsenter -t <容器PID> -n iptables -A INPUT -s 94.130.56.244 -j DROP
这个规则直接作用于容器的网络栈,会立刻阻断该IP的访问。
方案四:用Fail2Ban自动拦截批量恶意IP
如果后续还有其他IP发起类似攻击,可以用Fail2Ban自动识别并拦截:
- 安装Fail2Ban:
sudo apt update && sudo apt install fail2ban -y
- 创建自定义过滤规则文件
/etc/fail2ban/filter.d/nginx-acme.conf:
[Definition] # 匹配Nginx错误日志中包含acme-challenge和IP的行 failregex = ^.*access forbidden by rule, client: <HOST>.*GET /.well-known/acme-challenge/.*$ ignoreregex =
- 创建 jail 配置文件
/etc/fail2ban/jail.d/nginx-acme.conf:
[nginx-acme] enabled = true filter = nginx-acme # 指向你的Nginx错误日志路径(容器日志路径为/var/lib/docker/containers/<容器ID>/<容器ID>-json.log) logpath = /var/log/nginx/error.log # 5分钟内触发3次拦截就封禁IP maxretry = 3 findtime = 300 # 封禁24小时 bantime = 86400 # 针对Docker容器的流量,用DOCKER-USER链封禁 banaction = iptables-docker
- 重启Fail2Ban服务:
sudo systemctl restart fail2ban
这样Fail2Ban会自动监控日志,批量拦截类似的恶意请求。
备注:内容来源于stack exchange,提问作者Gianmarco Santi




