V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NGINX
NGINX Trac
3rd Party Modules
Security Advisories
CHANGES
OpenResty
ngx_lua
Tengine
在线学习资源
NGINX 开发从入门到精通
NGINX Modules
ngx_echo
cowiejulewbfwo
V2EX  ›  NGINX

fail2ban 保护 nginx 方案

  •  1
     
  •   cowiejulewbfwo · 13 小时 46 分钟前 · 557 次点击

    Docker Nginx (Host Mode) + Fail2Ban 完整指南

    本教程适用于使用 --network host 模式运行 Nginx 容器的场景。在此模式下,Fail2Ban 配置比 Bridge 模式更简单,因为不需要处理 Docker 的 NAT 转发链。


    📌 环境信息

    • 运行模式:Docker (Host Network)
    • 日志路径/root/nginx/log/access.log
    • 监听端口:宿主机直接监听 80/443

    第一步:确认容器运行状态

    请确保您已使用 Host 模式启动容器:

    # 停止并删除旧容器
    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 过滤器

    我们需要创建规则来告诉 Fail2Ban 什么是恶意行为。

    1. 防恶意扫描( Bad Request )

    拦截扫描敏感文件(如 .env, wp-login.php)的攻击者。

    sudo nano /etc/fail2ban/filter.d/nginx-bad-request.conf
    
    [Definition]
    failregex = ^<HOST> - - .* "(GET|POST|HEAD) .*\.(php|asp|aspx|jsp|cgi|env|git|yml|sql|bak|tar|gz|zip|rar|sh) HTTP.*" (400|401|403|404) .*$
                ^<HOST> - - .* "(GET|POST|HEAD) .*/(phpmyadmin|admin|setup|manager|dashboard|wp-login|xmlrpc).* HTTP.*" (400|401|403|404) .*$
    ignoregex =
    

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

    拦截请求频率过高的 IP ,但排除静态资源(图片、CSS 等)以免误封。

    sudo nano /etc/fail2ban/filter.d/nginx-cc.conf
    
    [Definition]
    failregex = ^<HOST> - - .* "(GET|POST|HEAD).*HTTP.*" .*$
    # 忽略图片、CSS 、JS 等静态资源
    ignoregex = \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg|mp4|webm) HTTP
    

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

    这是 Host 模式与 Bridge 模式最大的区别点。**Host 模式下,我们不需要指定 chain = DOCKER-USER**。

    sudo nano /etc/fail2ban/jail.local
    
    [DEFAULT]
    # 白名单 IP:即使这些 IP 触发规则也不会被封
    # 建议加上 localhost
    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 即可,无需指定 chain
    banaction = iptables-multiport
    
    # ==========================================
    # 规则 1:防止恶意扫描
    # ==========================================
    [nginx-bad-request]
    enabled  = true
    logpath  = /root/nginx/log/access.log
    filter   = nginx-bad-request
    port     = 80,443
    maxretry = 3
    bantime  = 24h
    
    # ==========================================
    # 规则 2:防止 CC 攻击
    # ==========================================
    [nginx-cc]
    enabled  = true
    logpath  = /root/nginx/log/access.log
    filter   = nginx-cc
    port     = 80,443
    findtime = 60
    # 允许每分钟 120 次非静态资源请求
    maxretry = 120
    bantime  = 2h
    

    第四步:重启与验证

    1. 重启 Fail2Ban

    sudo systemctl restart fail2ban
    

    2. 验证状态

    sudo fail2ban-client status
    

    应看到以下两个监狱处于活动状态:

    • nginx-bad-request
    • nginx-cc

    3. 验证防火墙规则

    检查 INPUT 链( Host 模式走这里):

    sudo iptables -L INPUT -n
    

    确认规则中出现针对目标 IP 的 DROPREJECT 记录,表示封禁生效。


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

    2 条回复    2025-11-28 17:11:12 +08:00
    ethusdt
        1
    ethusdt  
       13 小时 1 分钟前
    虽然像 AI 写的,不过还算完整,刚好今天我也发了相关的帖子。

    另外还要在 nginx 上配置下 `set_real_ip_from` 哦,否则恶意流量添加 X-Forwarded-For: 8.8.8.8 这种 header ,你的 nginx 日志会记录成 8.8.8.8 而忽略了源请求地址。
    cowiejulewbfwo
        2
    cowiejulewbfwo  
    OP
       12 小时 21 分钟前
    @ethusdt 感谢补充。
    现在其实都是 ai 写的,只要内容详实没问题就好。就怕用 ai 制造垃圾信息这就很恶心了。
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   812 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 18ms · UTC 21:32 · PVG 05:32 · LAX 13:32 · JFK 16:32
    ♥ Do have faith in what you're doing.