侧边栏壁纸
博主头像
Disue

Carpe diem

  • 累计撰写 7 篇文章
  • 累计创建 8 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

极致性能与安全:Docker Nginx + Fail2Ban 防 CC/扫描配置指南

Disue
2025-11-28 / 0 评论 / 0 点赞 / 18 阅读 / 0 字

本教程专为使用 --network host 模式运行 Nginx 容器的场景设计。在此模式下,Fail2Ban 的配置比 Bridge 模式更简单、更高效,因为我们直接在宿主机上处理日志和封禁,无需干预 Docker 的 NAT 转发链。

📌 环境与前提

配置项

详细信息

备注

网络模式

Docker (Host Network)

宿主机直接监听 80/443 端口

Nginx日志

/root/nginx/log/access.log

请确保您的映射路径与此一致

日志格式

默认匹配 Nginx 标准日志格式

如果您使用了自定义格式,请相应调整 failregex

💡 Host 模式的限制提示

在 Host 模式下,Nginx 容器将直接使用宿主机的网络堆栈。这意味着容器使用的端口(如 80/443)会占用宿主机的端口,不能再被宿主机上的其他服务使用。

第一步:确认容器以 Host 模式运行

请确保您已使用 Host Network 模式启动容器,并正确挂载了日志卷,以便 Fail2Ban 能够读取宿主机上的日志文件。

Bash

# 停止并删除旧容器
docker rm -f nginx01

# 启动新容器( Host 模式)
docker run -d \
  --name nginx01 \
  --restart always \
  --network host \
  -v "/root/nginx/conf/nginx.conf:/etc/nginx/nginx.conf" \
  -v "/root/nginx/html:/usr/share/nginx/html" \
  -v "/root/nginx/cert:/etc/nginx/cert" \
  -v "/root/nginx/log:/var/log/nginx" \
  --add-host=host.docker.internal:host-gateway \
  nginx

第二步:配置 Fail2Ban 过滤器 (filter.d)

我们需要创建规则来定义何种行为属于恶意攻击。

1. 防恶意扫描( Bad Request )

拦截扫描敏感文件(如 .env, wp-login.php)的攻击者,通常伴随 400/404 等错误响应码。

Bash

sudo nano /etc/fail2ban/filter.d/nginx-bad-request.conf

Ini, TOML

[Definition]
# 优化后的 failregex 匹配标准 Nginx 日志格式
failregex = ^<HOST> - \S+ \[.*\] "(GET|POST|HEAD) .*\.(php|asp|aspx|jsp|cgi|env|git|yml|sql|bak|tar|gz|zip|rar|sh) HTTP.*" (400|401|403|404) .*$
            ^<HOST> - \S+ \[.*\] "(GET|POST|HEAD) .*/(phpmyadmin|admin|setup|manager|dashboard|wp-login|xmlrpc).* HTTP.*" (400|401|403|404) .*$
ignoregex = 

2. 防高频 CC 攻击( Anti-Flood )

拦截请求频率过高的 IP。我们使用 ignoregex 来排除静态资源(图片、CSS 等),以避免误封。

Bash

sudo nano /etc/fail2ban/filter.d/nginx-cc.conf

Ini, TOML

[Definition]
# 优化后的 failregex 匹配任何非忽略的请求
failregex = ^<HOST> - \S+ \[.*\] "(GET|POST|HEAD).*HTTP.*" .*$

# 忽略图片、CSS、JS 等静态资源,防止正常用户的请求被计入
ignoregex = \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg|mp4|webm|webp) HTTP

第三步:配置监狱文件(jail.local

这是 Host 模式配置的重点。由于流量直接经过宿主机网络,我们不需要指定 chain = DOCKER-USER。Fail2Ban 将直接作用于宿主机的标准 INPUT 链。

Bash

sudo nano /etc/fail2ban/jail.local

Ini, TOML

[DEFAULT]
# 白名单 IP:即使这些 IP 触发规则也不会被封
# 建议加上 localhost、内网 IP 段、以及您常用设备的 IP
ignoreip = 127.0.0.1/8 192.168.0.0/16 10.0.0.0/8

# 默认封禁时间:1 小时
bantime  = 1h

# 查找时间窗口:10 分钟内
findtime = 10m

# 最大尝试次数:5 次
maxretry = 5

# Host 模式动作配置:直接使用标准的 iptables-multiport 即可
banaction = iptables-multiport

# ==========================================
# 规则 1:防止恶意扫描 (nginx-bad-request)
# ==========================================
[nginx-bad-request]
enabled  = true
logpath  = /root/nginx/log/access.log
filter   = nginx-bad-request
port     = 80,443
maxretry = 3  # 3 次扫描即封禁
bantime  = 24h # 封禁时间较长
action   = %(banaction)s[name=NGINX-BAD-REQUEST]

# ==========================================
# 规则 2:防止 CC 攻击 (nginx-cc)
# ==========================================
[nginx-cc]
enabled  = true
logpath  = /root/nginx/log/access.log
filter   = nginx-cc
port     = 80,443
findtime = 60 # 查找时间窗口:60 秒 (1 分钟)
# 允许每分钟 120 次非静态资源请求,超过即视为 CC 攻击
maxretry = 120
bantime  = 2h # 封禁 2 小时
action   = %(banaction)s[name=NGINX-CC]

第四步:重启与验证

1. 重启 Fail2Ban

应用新的配置。

Bash

sudo systemctl restart fail2ban

2. 验证状态

确认您的两个监狱(Jail)已正确加载并处于活动状态。

Bash

sudo fail2ban-client status

您应该看到:

  • nginx-bad-request

  • nginx-cc

3. 验证防火墙规则

检查宿主机的 INPUT 链,确认 Fail2Ban 已创建用于封禁的 Jump Target。

Bash

sudo iptables -L INPUT -n

如果您的系统内网卡(如 docker0br-xxx)出现在 INPUT 链之前,则封禁生效。当有 IP 被封禁时,再次查看 iptables -L 应该会在 Fail2Ban 相关的 Target 下看到针对目标 IP 的 DROPREJECT 记录。


您的 Nginx 容器已在 Host 模式下成功集成 Fail2Ban,具备抵御恶意扫描与 CC 攻击的能力!

0

评论区