网络安全:Fail2ban 实战,从暴力破解防护到自动化安全

208 阅读6分钟

📖 前言

本教程基于真实的 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
└─────────────────┘

核心组件

  1. Filter(过滤器):定义如何识别失败的尝试
  2. Jail(监狱):定义监控规则和惩罚措施
  3. 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是否启用truetrue
port保护的端口http,https根据服务
filter过滤器名称caddy-auth对应 filter 文件名
logpath日志文件路径/var/log/caddy/*.log实际路径
maxretry失败次数阈值53-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 类型

  1. iptables-multiport(推荐)

    action = iptables-multiport[name=caddy-auth, port="http,https", protocol=tcp]
    
    • 同时封禁多个端口
    • 效率高
  2. iptables-allports

    action = iptables-allports[name=caddy-auth]
    
    • 封禁所有端口
    • 适用于严重攻击
  3. 自定义 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)

排查步骤

  1. 检查配置语法

    sudo fail2ban-client -t
    
  2. 查看详细错误

    sudo journalctl -u fail2ban -n 50 --no-pager
    
  3. 常见错误及解决

    错误: 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 不工作(没有封禁)

排查步骤

  1. 测试 filter 正则表达式

    sudo fail2ban-regex /var/log/caddy/claude-code.club.log \
      /etc/fail2ban/filter.d/caddy-auth.conf -v
    

    如果匹配数为 0,说明正则表达式有问题。

  2. 检查日志文件权限

    ls -la /var/log/caddy/
    
    # fail2ban 需要读取权限
    sudo chmod 644 /var/log/caddy/*.log
    
  3. 检查日志文件是否在更新

    sudo tail -f /var/log/caddy/claude-code.club.log
    
    # 发起测试请求看是否有新日志
    
  4. 启用 debug 模式

    # 临时启用 debug
    sudo fail2ban-client set loglevel DEBUG
    
    # 查看详细日志
    sudo tail -f /var/log/fail2ban.log
    

问题 3:误封正常用户

解决方案

  1. 立即解封

    sudo fail2ban-client set caddy-auth unbanip <IP>
    
  2. 添加到白名单

    sudo nano /etc/fail2ban/jail.d/caddy-auth.conf
    
    # 添加
    ignoreip = 127.0.0.1/8 ::1 误封的IP
    
  3. 调整阈值(更宽松):

    maxretry = 10   # 增加失败次数
    findtime = 1800 # 延长时间窗口
    

问题 4:性能问题

症状:fail2ban 占用大量 CPU/内存

优化方案

  1. 使用 systemd backend(推荐):

    [caddy-auth]
    backend = systemd
    
  2. 限制日志扫描范围

    # 只扫描最近 1 天的日志
    maxlines = 10000
    
    # 或使用 logrotate
    
  3. 优化正则表达式

    # 避免过于复杂的正则
    # 使用更精确的匹配,减少回溯
    

问题 5:iptables 规则冲突

症状:封禁后 IP 仍能访问

排查

  1. 检查 iptables 规则顺序

    sudo iptables -L INPUT -n -v --line-numbers
    

    fail2ban 规则应该在 ACCEPT 规则之前。

  2. 检查 Docker 网络

    # Docker 可能会绕过 INPUT 链
    sudo iptables -L DOCKER-USER -n -v
    
  3. 在 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

🎓 学习资源

官方文档

正则表达式工具

  • Regex101 - 在线测试正则表达式
  • RegExr - 可视化正则表达式

安全资源


✅ 检查清单

部署 fail2ban 后的验证清单:

  • fail2ban 服务正常运行
  • 所有 jail 已启用并正常工作
  • filter 正则表达式能正确匹配日志
  • 白名单 IP 配置正确
  • 阈值设置合理(不会误封)
  • iptables 规则正常添加
  • 日志轮转配置生效
  • 监控脚本已部署
  • 测试封禁和解封功能
  • 文档已更新

📝 总结

本教程通过实际案例演示了 fail2ban 的完整配置流程:

  1. ✅ 理解 fail2ban 的工作原理
  2. ✅ 分析应用日志格式
  3. ✅ 编写 filter 正则表达式
  4. ✅ 配置 jail 规则和阈值
  5. ✅ 测试和验证配置
  6. ✅ 监控和管理封禁
  7. ✅ 高级配置和优化

关键要点

  • fail2ban 是动态防护,配合静态黑名单效果更好
  • 正则表达式是核心,务必充分测试
  • 阈值设置需要平衡安全性和可用性
  • 持续监控和调整配置