📖 前言
本教程基于真实的 Claude API Service 防护案例,讲解如何使用 fail2ban 保护 Web 服务免受暴力破解攻击。
案例背景:
- 服务:claude API 服务
- 问题:IP
125.120.99.124持续尝试登录POST /web/auth/login - 目标:自动检测并阻止恶意登录尝试
- 环境:Ubuntu 24.04 + Docker + Caddy + fail2ban
🎯 什么是 fail2ban?
核心概念
fail2ban 是一个入侵防御软件框架,通过监控日志文件来检测恶意行为,并自动执行防御动作(通常是修改防火墙规则来封禁 IP)。
工作原理
┌─────────────────┐
│ 服务日志文件 │ ← 应用程序记录访问日志
└────────┬────────┘
│
↓
┌─────────────────┐
│ fail2ban │
│ ┌───────────┐ │
│ │ Filter │ │ ← 正则表达式匹配失败模式
│ └─────┬─────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ Jail │ │ ← 判断是否达到阈值
│ └─────┬─────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ Action │ │ ← 执行封禁动作
│ └───────────┘ │
└────────┬────────┘
│
↓
┌─────────────────┐
│ iptables │ ← 在防火墙层面阻止 IP
└─────────────────┘
核心组件
- Filter(过滤器):定义如何识别失败的尝试
- Jail(监狱):定义监控规则和惩罚措施
- Action(动作):定义如何惩罚(通常是 iptables 封禁)
🛠️ 实战案例:保护 Caddy Web 服务
场景描述
攻击特征:
- 攻击者 IP:
125.120.99.124 - 目标端点:
/web/auth/login - 攻击方式: 暴力破解(不断尝试登录)
- 日志表现: 大量 401/403 响应
防护需求:
- 10分钟内失败 5 次 → 封禁 1 小时
- 自动化,无需人工干预
- 保留日志用于审计
步骤 1:安装 fail2ban
# 更新系统包
sudo apt update
# 安装 fail2ban
sudo apt install -y fail2ban
# 查看版本
fail2ban-server --version
输出示例:
Fail2Ban v1.0.2
步骤 2:理解日志格式
首先,我们需要了解 Caddy 的日志格式,以便编写正确的正则表达式。
Caddy 访问日志示例:
{
"level": "info",
"ts": 1730188800.123,
"logger": "http.log.access",
"msg": "handled request",
"request": {
"remote_ip": "125.120.99.124",
"remote_port": "54321",
"client_ip": "125.120.99.124",
"proto": "HTTP/2.0",
"method": "POST",
"host": "claude-code.club",
"uri": "/web/auth/login",
"headers": {
"User-Agent": ["Python/3.11"],
"Content-Type": ["application/json"]
}
},
"status": 401,
"size": 42
}
关键信息:
remote_ip: 客户端 IP 地址uri: 请求的端点status: HTTP 状态码(401 = 未授权,403 = 禁止访问)
步骤 3:创建 Filter(过滤器)
Filter 使用正则表达式来匹配日志中的失败尝试。
文件路径:/etc/fail2ban/filter.d/caddy-auth.conf
# Fail2Ban filter for Caddy authentication failures
[Definition]
# 匹配模式 - 捕获失败的登录尝试
failregex = ^.*"remote_ip":"<HOST>".*"status":(?:401|403).*"uri":".*\/web\/auth\/login.*$
^.*<HOST>.*POST.*\/web\/auth\/login.*(?:401|403)
# 忽略模式(可选)
ignoreregex =
正则表达式详解:
^.*"remote_ip":"<HOST>".*"status":(?:401|403).*"uri":".*\/web\/auth\/login.*$
│ │ │ │ │ │ │
│ │ │ │ │ │ └─ 行结束
│ │ │ │ │ └─ 匹配 /web/auth/login 路径
│ │ │ │ └─ 匹配 401 或 403 状态码(非捕获组)
│ │ │ └─ 匹配 "status": 字段
│ │ └─ fail2ban 占位符,自动提取 IP
│ └─ 匹配任意字符
└─ 行开始
特殊标记说明:
<HOST>: fail2ban 的特殊占位符,自动捕获并提取 IP 地址(?:...): 非捕获组,只匹配不捕获\/: 转义斜杠
步骤 4:测试 Filter
在应用之前,务必测试 filter 是否能正确匹配日志。
# 测试 filter 正则表达式
sudo fail2ban-regex /var/log/caddy/claude-code.club.log \
/etc/fail2ban/filter.d/caddy-auth.conf
成功输出示例:
Running tests
=============
Use failregex filter file : caddy-auth, basedir: /etc/fail2ban
Use log file : /var/log/caddy/claude-code.club.log
Use encoding : UTF-8
Results
=======
Failregex: 37 total
|- #) [# of hits] regular expression
| 1) [37] ^.*"remote_ip":"<HOST>".*"status":(?:401|403).*"uri":".*\/web\/auth\/login.*$
Ignoreregex: 0 total
Date template hits:
|- [# of hits] date format
| [37] Day(?P<_sep>[-/])MON(?P=_sep)Year[ :]?24hour:Minute:Second(?:\.Microseconds)?(?:\s*Zone offset)?
Lines: 1250 lines, 0 ignored, 37 matched, 1213 missed
[processed in 0.12 sec]
解读结果:
Failregex: 37 total: 成功匹配了 37 条记录Lines: 1250 lines, 37 matched: 从 1250 行日志中匹配到 37 次失败
步骤 5:创建 Jail(监狱)
Jail 定义了监控规则、阈值和惩罚措施。
文件路径:/etc/fail2ban/jail.d/caddy-auth.conf
[caddy-auth]
# ========== 基本配置 ==========
# 是否启用此 jail
enabled = true
# 保护的端口(服务名或端口号)
port = http,https
# ========== 日志监控 ==========
# 使用的 filter 名称
filter = caddy-auth
# 监控的日志文件路径(支持通配符)
logpath = /var/log/caddy/*.log
# 日志文件编码
encoding = auto
# ========== 检测阈值 ==========
# 最大重试次数(超过此次数则封禁)
maxretry = 5
# 检测时间窗口(秒)- 10分钟内
findtime = 600
# 封禁时长(秒)- 1小时
bantime = 3600
# ========== 封禁动作 ==========
# 执行的动作
action = iptables-multiport[name=caddy-auth, port="http,https", protocol=tcp]
# ========== 高级配置(可选)==========
# 后端类型(auto, pyinotify, gamin, polling, systemd)
backend = auto
# 日志时区
logtimezone = UTC
参数详解:
| 参数 | 说明 | 示例值 | 推荐值 |
|---|---|---|---|
enabled | 是否启用 | true | true |
port | 保护的端口 | http,https | 根据服务 |
filter | 过滤器名称 | caddy-auth | 对应 filter 文件名 |
logpath | 日志文件路径 | /var/log/caddy/*.log | 实际路径 |
maxretry | 失败次数阈值 | 5 | 3-10 次 |
findtime | 时间窗口(秒) | 600 (10分钟) | 300-3600 秒 |
bantime | 封禁时长(秒) | 3600 (1小时) | 1800-86400 秒 |
action | 封禁动作 | iptables-multiport | 根据防火墙 |
阈值计算公式:
封禁条件:在 findtime 秒内,失败次数 >= maxretry
示例:
findtime = 600 秒(10分钟)
maxretry = 5 次
意思是:10分钟内失败 5 次或以上 → 封禁 1 小时
不同场景的推荐配置:
# 场景 1: 严格模式(生产环境)
maxretry = 3
findtime = 300 # 5分钟
bantime = 7200 # 2小时
# 场景 2: 标准模式(推荐)
maxretry = 5
findtime = 600 # 10分钟
bantime = 3600 # 1小时
# 场景 3: 宽松模式(内部网络)
maxretry = 10
findtime = 1800 # 30分钟
bantime = 1800 # 30分钟
步骤 6:理解 Action(动作)
Action 定义了如何惩罚恶意 IP。最常用的是 iptables。
内置 Action 类型:
-
iptables-multiport(推荐)
action = iptables-multiport[name=caddy-auth, port="http,https", protocol=tcp]- 同时封禁多个端口
- 效率高
-
iptables-allports
action = iptables-allports[name=caddy-auth]- 封禁所有端口
- 适用于严重攻击
-
自定义 Action(发送邮件通知)
action = iptables-multiport[name=caddy-auth, port="http,https", protocol=tcp] sendmail-whois[name=caddy-auth, dest=admin@example.com]
iptables 规则示例:
当 IP 125.120.99.124 被封禁时,fail2ban 会执行:
iptables -I INPUT -s 125.120.99.124 -p tcp -m multiport --dports http,https -j REJECT
查看实际规则:
sudo iptables -L -n -v | grep fail2ban
步骤 7:启动和测试
# 启动 fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
# 检查状态
sudo systemctl status fail2ban
# 重新加载配置
sudo fail2ban-client reload
# 验证 jail 已加载
sudo fail2ban-client status
预期输出:
Status
|- Number of jail: 2
`- Jail list: caddy-auth, sshd
查看特定 jail 状态:
sudo fail2ban-client status caddy-auth
输出示例:
Status for the jail: caddy-auth
|- Filter
| |- Currently failed: 3 ← 当前失败次数
| |- Total failed: 127 ← 总失败次数
| `- Journal matches:
`- Actions
|- Currently banned: 1 ← 当前被封禁的 IP 数量
|- Total banned: 5 ← 历史封禁总数
`- Banned IP list: 125.120.99.124 ← 被封禁的 IP 列表
步骤 8:模拟攻击测试
安全测试环境下,我们可以模拟攻击来验证配置:
# 从测试机器发起多次失败的登录尝试
for i in {1..6}; do
curl -X POST https://claude-code.club/web/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"test","password":"wrong"}' \
-w "\nStatus: %{http_code}\n"
sleep 1
done
观察 fail2ban 日志:
sudo tail -f /var/log/fail2ban.log
预期日志:
2025-10-29 08:30:15,123 fail2ban.filter [12345]: INFO [caddy-auth] Found 192.168.1.100 - 2025-10-29 08:30:15
2025-10-29 08:30:16,234 fail2ban.filter [12345]: INFO [caddy-auth] Found 192.168.1.100 - 2025-10-29 08:30:16
2025-10-29 08:30:17,345 fail2ban.filter [12345]: INFO [caddy-auth] Found 192.168.1.100 - 2025-10-29 08:30:17
2025-10-29 08:30:18,456 fail2ban.filter [12345]: INFO [caddy-auth] Found 192.168.1.100 - 2025-10-29 08:30:18
2025-10-29 08:30:19,567 fail2ban.filter [12345]: INFO [caddy-auth] Found 192.168.1.100 - 2025-10-29 08:30:19
2025-10-29 08:30:19,678 fail2ban.actions [12345]: NOTICE [caddy-auth] Ban 192.168.1.100
📊 监控和管理
实时监控命令
# 1. 查看所有 jail 的状态
sudo fail2ban-client status
# 2. 查看特定 jail 的详细信息
sudo fail2ban-client status caddy-auth
# 3. 实时查看 fail2ban 日志
sudo tail -f /var/log/fail2ban.log
# 4. 实时监控被封禁的 IP(每 5 秒刷新)
watch -n 5 'sudo fail2ban-client status caddy-auth'
# 5. 查看 iptables 规则
sudo iptables -L INPUT -n -v | grep -A 5 "fail2ban"
# 6. 查看应用日志中的失败尝试
sudo tail -f /var/log/caddy/claude-code.club.log | grep -E "(401|403)"
手动管理 IP
# 手动封禁 IP
sudo fail2ban-client set caddy-auth banip 1.2.3.4
# 手动解封 IP
sudo fail2ban-client set caddy-auth unbanip 1.2.3.4
# 解封所有 IP
sudo fail2ban-client unban --all
# 检查 IP 是否被封禁
sudo iptables -L -n | grep "1.2.3.4"
日志分析
统计被攻击最多的端点:
sudo grep "401\|403" /var/log/caddy/*.log | \
grep -oP '"uri":".*?"' | \
sort | uniq -c | sort -rn | head -10
统计攻击来源 IP Top 10:
sudo grep "401\|403" /var/log/caddy/*.log | \
grep -oP '"remote_ip":".*?"' | \
cut -d'"' -f4 | \
sort | uniq -c | sort -rn | head -10
输出示例:
127 125.120.99.124
45 1.2.3.4
23 5.6.7.8
12 9.10.11.12
查看特定 IP 的所有活动:
sudo grep "125.120.99.124" /var/log/caddy/*.log | tail -20
生成统计报告
# 创建统计脚本
cat > ~/fail2ban-stats.sh << 'EOF'
#!/bin/bash
echo "========== Fail2ban 统计报告 =========="
echo "生成时间: $(date)"
echo ""
echo "=== 所有 Jail 状态 ==="
sudo fail2ban-client status
echo ""
echo "=== Caddy Auth Jail 详细信息 ==="
sudo fail2ban-client status caddy-auth
echo ""
echo "=== 最近 10 次封禁事件 ==="
sudo grep "Ban " /var/log/fail2ban.log | tail -10
echo ""
echo "=== 当前 iptables 封禁规则 ==="
sudo iptables -L INPUT -n | grep -A 1 "fail2ban"
echo ""
echo "=== 攻击来源 IP Top 5 ==="
sudo grep "401\|403" /var/log/caddy/*.log 2>/dev/null | \
grep -oP '"remote_ip":".*?"' | \
cut -d'"' -f4 | \
sort | uniq -c | sort -rn | head -5
EOF
chmod +x ~/fail2ban-stats.sh
运行报告:
~/fail2ban-stats.sh
🔧 高级配置
1. 白名单配置
某些 IP 永远不应该被封禁(如办公室 IP、监控服务器)。
编辑全局配置:
sudo nano /etc/fail2ban/jail.local
添加白名单:
[DEFAULT]
# 忽略的 IP 地址(支持 CIDR)
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24 你的办公室IP
# 或在特定 jail 中配置
[caddy-auth]
ignoreip = 10.0.0.100 10.0.0.101
2. 动态阈值(根据时间调整)
工作时间严格,夜间宽松:
# /etc/fail2ban/jail.d/caddy-auth-day.conf
[caddy-auth-day]
enabled = true
filter = caddy-auth
logpath = /var/log/caddy/*.log
maxretry = 3
findtime = 300
bantime = 7200
# 使用 cron 在白天启用此配置
3. 递增封禁时间
首次封禁 1 小时,第二次 2 小时,第三次 24 小时:
编辑 action:
[caddy-auth]
action = iptables-multiport[name=caddy-auth, port="http,https", protocol=tcp]
bantime.increment = true
bantime.multipliers = 1 2 4 8 16 32 64
bantime.maxtime = 86400 # 最长 24 小时
4. 邮件通知
安装邮件工具:
sudo apt install -y mailutils
配置通知:
[caddy-auth]
action = iptables-multiport[name=caddy-auth, port="http,https", protocol=tcp]
sendmail-whois[name=caddy-auth, dest=admin@example.com, sender=fail2ban@example.com]
# 或使用 sendmail-buffered(减少邮件数量)
action = iptables-multiport[name=caddy-auth, port="http,https", protocol=tcp]
sendmail-buffered[name=caddy-auth, dest=admin@example.com]
5. 地理位置封禁
结合 GeoIP 数据库封禁特定国家:
# 安装 GeoIP
sudo apt install -y geoip-database geoip-bin
# 创建 filter
sudo tee /etc/fail2ban/filter.d/caddy-geo.conf > /dev/null << 'EOF'
[Definition]
failregex = ^.*"remote_ip":"<HOST>".*$
ignoreregex =
EOF
# 创建 action(示例:阻止中国以外的访问)
sudo tee /etc/fail2ban/action.d/iptables-geoip.conf > /dev/null << 'EOF'
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = iptables -I INPUT -s <ip> -m geoip ! --src-cc CN -j DROP
actionunban = iptables -D INPUT -s <ip> -m geoip ! --src-cc CN -j DROP
EOF
6. 整合 Telegram 通知
创建 Telegram 通知 action:
sudo tee /etc/fail2ban/action.d/telegram.conf > /dev/null << 'EOF'
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = curl -s -X POST "https://api.telegram.org/bot<your_bot_token>/sendMessage" \
-d "chat_id=<your_chat_id>" \
-d "text=🚨 Fail2ban Alert: IP <ip> has been banned in jail <name>"
actionunban = curl -s -X POST "https://api.telegram.org/bot<your_bot_token>/sendMessage" \
-d "chat_id=<your_chat_id>" \
-d "text=✅ Fail2ban: IP <ip> has been unbanned from jail <name>"
EOF
在 jail 中使用:
[caddy-auth]
action = iptables-multiport[name=caddy-auth, port="http,https", protocol=tcp]
telegram[name=caddy-auth]
🐛 故障排查
问题 1:fail2ban 启动失败
症状:
sudo systemctl status fail2ban
● fail2ban.service - Fail2Ban Service
Active: failed (Result: exit-code)
排查步骤:
-
检查配置语法:
sudo fail2ban-client -t -
查看详细错误:
sudo journalctl -u fail2ban -n 50 --no-pager -
常见错误及解决:
错误:
jail 'xxx' skipped, because no actions# 检查 action 配置 grep -A 5 "^\[caddy-auth\]" /etc/fail2ban/jail.d/caddy-auth.conf # 添加缺失的 action action = iptables-multiport[name=caddy-auth, port="http,https", protocol=tcp]错误:
Unable to find a corresponding IP address for xxx# 检查 DNS 解析 nslookup xxx # 使用 IP 地址代替域名
问题 2:Jail 不工作(没有封禁)
排查步骤:
-
测试 filter 正则表达式:
sudo fail2ban-regex /var/log/caddy/claude-code.club.log \ /etc/fail2ban/filter.d/caddy-auth.conf -v如果匹配数为 0,说明正则表达式有问题。
-
检查日志文件权限:
ls -la /var/log/caddy/ # fail2ban 需要读取权限 sudo chmod 644 /var/log/caddy/*.log -
检查日志文件是否在更新:
sudo tail -f /var/log/caddy/claude-code.club.log # 发起测试请求看是否有新日志 -
启用 debug 模式:
# 临时启用 debug sudo fail2ban-client set loglevel DEBUG # 查看详细日志 sudo tail -f /var/log/fail2ban.log
问题 3:误封正常用户
解决方案:
-
立即解封:
sudo fail2ban-client set caddy-auth unbanip <IP> -
添加到白名单:
sudo nano /etc/fail2ban/jail.d/caddy-auth.conf # 添加 ignoreip = 127.0.0.1/8 ::1 误封的IP -
调整阈值(更宽松):
maxretry = 10 # 增加失败次数 findtime = 1800 # 延长时间窗口
问题 4:性能问题
症状:fail2ban 占用大量 CPU/内存
优化方案:
-
使用 systemd backend(推荐):
[caddy-auth] backend = systemd -
限制日志扫描范围:
# 只扫描最近 1 天的日志 maxlines = 10000 # 或使用 logrotate -
优化正则表达式:
# 避免过于复杂的正则 # 使用更精确的匹配,减少回溯
问题 5:iptables 规则冲突
症状:封禁后 IP 仍能访问
排查:
-
检查 iptables 规则顺序:
sudo iptables -L INPUT -n -v --line-numbersfail2ban 规则应该在 ACCEPT 规则之前。
-
检查 Docker 网络:
# Docker 可能会绕过 INPUT 链 sudo iptables -L DOCKER-USER -n -v -
在 DOCKER-USER 链中添加规则:
# 编辑 fail2ban action sudo nano /etc/fail2ban/action.d/iptables-multiport.conf # 修改 chain 为 DOCKER-USER chain = DOCKER-USER
📈 性能优化
1. 选择合适的 Backend
fail2ban 支持多种后端来监控日志文件:
| Backend | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
| auto | 自动选择最优 | - | 一般场景 |
| systemd | 高效,实时 | 仅支持 systemd 日志 | 现代 Linux |
| pyinotify | 实时监控 | 需要额外依赖 | 大量日志 |
| polling | 兼容性好 | 占用资源多 | 兼容性优先 |
配置示例:
[caddy-auth]
backend = systemd # 推荐
2. 日志轮转
防止日志文件过大影响性能:
sudo tee /etc/logrotate.d/caddy > /dev/null << 'EOF'
/var/log/caddy/*.log {
daily # 每天轮转
rotate 14 # 保留 14 天
compress # 压缩旧日志
delaycompress # 延迟压缩(保留最新的未压缩)
notifempty # 空文件不轮转
missingok # 文件缺失不报错
sharedscripts # 多个文件共享脚本
postrotate
# 通知 Caddy 重新打开日志文件
docker compose -f /home/ubuntu/cc-club/compose.yml exec caddy caddy reload 2>/dev/null || true
endscript
}
EOF
3. 限制日志扫描行数
[caddy-auth]
# 只扫描最后 10000 行
maxlines = 10000
🛡️ 最佳实践总结
1. 配置策略
✅ 推荐做法:
- 根据实际攻击模式调整阈值
- 设置合理的白名单
- 启用日志轮转
- 定期审查封禁列表
- 保持 fail2ban 更新
❌ 避免:
- 阈值设置过低(易误封)
- 阈值设置过高(防护效果差)
- 忘记监控 fail2ban 日志
- 无限期封禁(可以设置 maxtime)
2. 监控建议
# 每天检查一次统计
0 9 * * * ~/fail2ban-stats.sh | mail -s "Fail2ban Daily Report" admin@example.com
# 监控 fail2ban 服务状态
*/5 * * * * systemctl is-active --quiet fail2ban || systemctl restart fail2ban
3. 安全加固
多层防护:
Layer 1: fail2ban (动态防护)
↓
Layer 2: Caddy IP 黑名单 (静态防护)
↓
Layer 3: 应用层速率限制
↓
Layer 4: 网络层 DDoS 防护(CloudFlare/AWS Shield)
📚 实用脚本集合
1. 快速查看脚本
#!/bin/bash
# ~/fail2ban-quick-view.sh
echo "=== 当前被封禁的 IP ==="
sudo fail2ban-client status caddy-auth | grep "Banned IP"
echo ""
echo "=== 最近 5 次封禁 ==="
sudo grep "Ban " /var/log/fail2ban.log | tail -5
echo ""
echo "=== 攻击来源统计 ==="
sudo grep "401\|403" /var/log/caddy/*.log 2>/dev/null | \
grep -oP '"remote_ip":".*?"' | \
cut -d'"' -f4 | \
sort | uniq -c | sort -rn | head -5
2. 自动解封脚本
#!/bin/bash
# ~/fail2ban-auto-unban.sh
# 每天自动解封超过 24 小时的 IP
JAIL="caddy-auth"
MAX_AGE=86400 # 24 小时
# 获取被封禁的 IP 列表
BANNED_IPS=$(sudo fail2ban-client status $JAIL | grep "Banned IP" | cut -d: -f2)
for IP in $BANNED_IPS; do
# 检查封禁时间
BAN_TIME=$(sudo grep "Ban $IP" /var/log/fail2ban.log | tail -1 | cut -d' ' -f1-2)
BAN_TIMESTAMP=$(date -d "$BAN_TIME" +%s)
CURRENT_TIMESTAMP=$(date +%s)
AGE=$((CURRENT_TIMESTAMP - BAN_TIMESTAMP))
if [ $AGE -gt $MAX_AGE ]; then
echo "解封 $IP (封禁时长: $((AGE / 3600)) 小时)"
sudo fail2ban-client set $JAIL unbanip $IP
fi
done
3. 封禁统计脚本
#!/bin/bash
# ~/fail2ban-ban-stats.sh
echo "=== Fail2ban 封禁统计 ==="
echo ""
echo "今天封禁次数:"
sudo grep "$(date +%Y-%m-%d)" /var/log/fail2ban.log | grep -c "Ban "
echo ""
echo "本周封禁次数:"
sudo grep "$(date -d '7 days ago' +%Y-%m-%d)" /var/log/fail2ban.log | grep -c "Ban "
echo ""
echo "最常被封禁的 IP Top 10:"
sudo grep "Ban " /var/log/fail2ban.log | \
grep -oP 'Ban \K[0-9.]+' | \
sort | uniq -c | sort -rn | head -10
🎓 学习资源
官方文档
正则表达式工具
安全资源
✅ 检查清单
部署 fail2ban 后的验证清单:
- fail2ban 服务正常运行
- 所有 jail 已启用并正常工作
- filter 正则表达式能正确匹配日志
- 白名单 IP 配置正确
- 阈值设置合理(不会误封)
- iptables 规则正常添加
- 日志轮转配置生效
- 监控脚本已部署
- 测试封禁和解封功能
- 文档已更新
📝 总结
本教程通过实际案例演示了 fail2ban 的完整配置流程:
- ✅ 理解 fail2ban 的工作原理
- ✅ 分析应用日志格式
- ✅ 编写 filter 正则表达式
- ✅ 配置 jail 规则和阈值
- ✅ 测试和验证配置
- ✅ 监控和管理封禁
- ✅ 高级配置和优化
关键要点:
- fail2ban 是动态防护,配合静态黑名单效果更好
- 正则表达式是核心,务必充分测试
- 阈值设置需要平衡安全性和可用性
- 持续监控和调整配置