工具盒子 Logo
🏘首页
📦归档
🏷标签
🧰关于
登录 →
工具盒子 Logo
🏘首页 📦归档 🏷标签 🧰关于
登录
  1. 首页
  2. 运维工具
  3. Fail2Ban与IPSet集成配置指南

Fail2Ban与IPSet集成配置指南

  • 运维工具
  • 发布于 2026-05-27
  • 2 次阅读
Administrator
Administrator
目录
当前文章没有目录

以下是为您整理的专门针对 RedHat 系发行版(CentOS、RHEL、Rocky Linux、AlmaLinux 等)的 Markdown 格式配置文档。


Fail2ban + Caddy 404 封禁 + Firewalld (nftables) 持久化配置指南 (RedHat 系)

本文档详细介绍如何在 RedHat 系 Linux 发行版上,通过 Fail2ban 分析 Caddy 的 JSON 访问日志,自动提取 404 错误请求的客户端 IP,并利用 Firewalld(底层 nftables)进行永久封禁,同时确保服务器重启后封禁规则不丢失。


一、 整体架构与依赖说明

客户端请求 → Caddy (JSON 访问日志) → Fail2ban (正则匹配 404) → firewall-cmd (firewalld) → nftables 内核规则

所需软件包:

软件 作用
caddy Web 服务器,输出 JSON 格式访问日志
fail2ban 日志分析引擎,触发自动封禁
fail2ban-firewalld Fail2ban 的 firewalld 动作支持插件
firewalld 防火墙管理守护进程(底层自动调用 nftables)
logrotate 日志轮转工具,防止日志文件无限增长

二、 安装所需软件

在 RedHat 系系统中,使用 dnf 包管理器进行安装。

# 1. 安装 EPEL 源(提供 fail2ban 等额外软件包)
sudo dnf install epel-release -y

# 2. 添加 Caddy 官方 COPR 仓库(如果系统尚未安装 Caddy)
sudo dnf install 'dnf-command(copr)' -y
sudo dnf copr enable @caddy/caddy -y

# 3. 安装所有必需软件
sudo dnf install caddy fail2ban fail2ban-firewalld firewalld logrotate -y

# 4. 设置 firewalld 和 fail2ban 开机自启并立即启动
sudo systemctl enable --now firewalld
sudo systemctl enable --now fail2ban

三、 配置 Caddy 输出 JSON 访问日志

Caddy v2 默认使用 JSON 格式记录日志,但需要显式配置将其输出到指定文件。

编辑您的 Caddyfile(通常位于 /etc/caddy/Caddyfile),在站点块中添加 log 指令:

example.com {
    # ... 您的其他站点配置 ...
    reverse_proxy localhost:8080

    # 开启 JSON 格式访问日志并输出到文件
    log {
        output file /var/log/caddy/access.log {
            roll_size 100mb
            roll_keep 5
            roll_keep_for 720h
        }
        format json
        sampling {
            interval 1
        }
    }
}

确保日志目录权限正确:

sudo mkdir -p /var/log/caddy
sudo chown caddy:caddy /var/log/caddy
sudo touch /var/log/caddy/access.log
sudo chown caddy:caddy /var/log/caddy/access.log

重载 Caddy 使配置生效:

sudo systemctl reload caddy

四、 配置 Fail2ban 过滤器 (Filter)

创建一个专门用于匹配 Caddy JSON 日志中 404 状态的过滤器。

sudo nano /etc/fail2ban/filter.d/caddy-404.conf

写入以下内容:

# /etc/fail2ban/filter.d/caddy-404.conf
# 匹配 Caddy JSON 访问日志中 status 为 404 的请求

[INCLUDES]
before = common.conf

[Definition]
# 优化后的正则:使用非贪婪匹配,并兼容行尾可能存在的 \r 换行符
failregex = ^.*"remote_ip":"<HOST>".*?"status":\s*404.*\}?\s*$

ignoreregex = 

测试过滤器匹配效果:

# 使用 fail2ban-regex 工具测试真实日志
sudo fail2ban-regex /var/log/caddy/access.log /etc/fail2ban/filter.d/caddy-404.conf

如果输出中包含 Lines: X matched,则说明正则表达式工作正常。


五、 配置 Fail2ban 封禁动作 (Action)

创建一个自定义 Action,确保封禁操作同时写入 Firewalld 的运行时和持久化配置中。

sudo nano /etc/fail2ban/action.d/firewalld-permanent.conf

写入以下内容:

# /etc/fail2ban/action.d/firewalld-permanent.conf
# 通过 firewalld rich rules 永久封禁 IP(兼容 nftables 后端)

[Definition]

# 启动时不需要额外操作
actionstart = 

# 停止时不清除规则(因为是永久封禁,交由 firewalld 自身管理)
actionstop = 

# 封禁 IP:同时写入 runtime(立即生效)和 permanent(持久化)
actionban = firewall-cmd --add-rich-rule='rule family="ipv4" source address="<ip>" drop'
            firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="<ip>" drop'
            firewall-cmd --add-rich-rule='rule family="ipv6" source address="<ip>" drop'
            firewall-cmd --permanent --add-rich-rule='rule family="ipv6" source address="<ip>" drop'

# 解封 IP:同时从 runtime 和 permanent 中移除
actionunban = firewall-cmd --remove-rich-rule='rule family="ipv4" source address="<ip>" drop'
              firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="<ip>" drop'
              firewall-cmd --remove-rich-rule='rule family="ipv6" source address="<ip>" drop'
              firewall-cmd --permanent --remove-rich-rule='rule family="ipv6" source address="<ip>" drop'

[Init]
name = default

六、 配置 Fail2ban 规则 (Jail)

创建本地 Jail 配置文件(请勿直接修改默认的 jail.conf)。

sudo nano /etc/fail2ban/jail.local

写入以下内容:

# /etc/fail2ban/jail.local

[DEFAULT]
# ===== 全局默认设置 =====

# 使用自定义的 firewalld 持久化动作
banaction = firewalld-permanent
banaction_allports = firewalld-permanent

# 永久封禁(-1 表示永不自动解封)
bantime  = -1

# 检测时间窗口(秒)
findtime = 600

# 触发封禁的失败次数阈值
maxretry = 5

# 忽略的 IP(白名单:本地回环、内网网段、您的管理 IP)
ignoreip = 127.0.0.1/8 ::1 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16

# 使用 SQLite 数据库持久化封禁记录(Fail2ban 重启不丢失)
dbfile   = /var/lib/fail2ban/fail2ban.sqlite3

# 日志后端
backend  = auto


# ===== Caddy 404 封禁规则 =====
[caddy-404]
enabled  = true
port     = http,https
filter   = caddy-404
logpath  = /var/log/caddy/access.log
maxretry = 10
findtime = 600
bantime  = -1
action   = firewalld-permanent[name=caddy-404]

七、 配置 Logrotate 日志轮转

防止 Caddy 日志文件占用过多磁盘空间,并确保轮转后 Fail2ban 能继续正常读取。

sudo nano /etc/logrotate.d/caddy

写入以下内容:

/var/log/caddy/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 caddy caddy
    sharedscripts
    postrotate
        # 通知 fail2ban 重新打开日志文件
        /usr/bin/fail2ban-client flushlogs 2>/dev/null || true
        # 通知 caddy 重新打开日志
        /usr/bin/systemctl reload caddy 2>/dev/null || true
    endscript
}

八、 确认 Firewalld 使用 nftables 后端

检查 Firewalld 的底层后端配置:

grep FirewallBackend /etc/firewalld/firewalld.conf

确保输出为 FirewallBackend=nftables。如果不是,请修改并重启服务:

sudo sed -i 's/FirewallBackend=.*/FirewallBackend=nftables/' /etc/firewalld/firewalld.conf
sudo systemctl restart firewalld

验证 nftables 规则集是否正常加载:

sudo nft list ruleset | head -10

九、 启动服务与验证测试

9.1 重载并检查状态

# 重载 fail2ban 配置
sudo fail2ban-client reload

# 查看 caddy-404 jail 状态
sudo fail2ban-client status caddy-404

9.2 手动测试封禁与持久化

# 1. 手动封禁一个测试 IP (例如 203.0.113.50)
sudo fail2ban-client set caddy-404 banip 203.0.113.50

# 2. 验证 firewalld 规则(应包含该 IP 的 rich rule)
sudo firewall-cmd --list-rich-rules

# 3. 验证底层 nftables 规则
sudo nft list ruleset | grep 203.0.113.50

# 4. 模拟重启 firewalld 验证持久化
sudo systemctl restart firewalld
sudo firewall-cmd --list-rich-rules  # 规则应依然存在

# 5. 测试完成后解封
sudo fail2ban-client set caddy-404 unbanip 203.0.113.50

十、 日常管理命令速查

操作目的 命令
查看 Jail 运行状态 sudo fail2ban-client status caddy-404
手动封禁指定 IP sudo fail2ban-client set caddy-404 banip <IP地址>
手动解封指定 IP sudo fail2ban-client set caddy-404 unbanip <IP地址>
解封所有 IP sudo fail2ban-client unban --all
查看 Fail2ban 运行日志 sudo tail -f /var/log/fail2ban.log
重新加载 Fail2ban 配置 sudo fail2ban-client reload
查看 Firewalld 富规则 sudo firewall-cmd --list-rich-rules
测试 Filter 正则匹配 sudo fail2ban-regex /var/log/caddy/access.log /etc/fail2ban/filter.d/caddy-404.conf

十一、 持久化原理与注意事项

持久化三重保障机制

  1. Fail2ban SQLite 数据库 (dbfile):Fail2ban 重启时,会自动从 /var/lib/fail2ban/fail2ban.sqlite3 读取封禁列表并重新执行封禁动作。
  2. Firewalld Permanent 配置:自定义 Action 在封禁时同时执行 --permanent 参数,将规则写入 Firewalld 的 XML 配置文件中,确保 Firewalld 重启或系统重启后规则不丢失。
  3. Systemd 开机自启:firewalld 和 fail2ban 均已设置为 enable,确保系统启动时自动加载防火墙规则并启动日志监控。

⚠️ 重要注意事项

  • 阈值设置:maxretry 不建议设置过低(推荐 5~20 之间),以免误封正常用户(例如浏览器自动请求不存在的 favicon.ico 或 robots.txt)。
  • CDN 代理问题:如果 Caddy 部署在 Cloudflare 等 CDN 之后,日志中的 remote_ip 可能是 CDN 节点的 IP。您需要在 Caddy 中配置 trusted_proxies 以获取真实的客户端 IP,否则会导致 CDN 节点被封禁。
  • 白名单配置:务必在 jail.local 的 ignoreip 中添加您自己的固定管理 IP 和常用的 CDN 回源 IP 段。
标签: #Linux 4
相关文章

主机hosts配置工具

下载地址: SwitchHosts 5.0:https://github.com/oldj/SwitchHosts/releases Hostly:https://github.com/zengyufei/Hostly/releases

lsof替代工具

一个 Go 编写的 CLI 工具,让你一眼看清 localhost 上所有在监听的服务——进程名、Docker 容器名、Compose 项目、资源占用、可点击 URL,全部一目了然。 安装 # macOS / Linux(推荐) brew install raskrebs/sonar/sonar

Fail2Ban与IPSet集成配置指南

以下是为您整理的专门针对 RedHat 系发行版(CentOS、RHEL、Rocky Linux、AlmaLinux 等)的 Markdown 格式配置文档。 Fail2ban + Caddy 404 封禁 + Firewalld (nftables) 持久化配置指南 (RedHat 系) 本文档详

目录
当前文章没有目录
  • 工具盒子公众号
Copyright © 2025 toolhz.cn All Rights Reserved
粤ICP备2025427282号
gongan beian 粤公网安备44030002008642号