fail2ban 安装与使用教程(CentOS 9/10 + Apache)

2026-06-25 12:51 技术文章 6 阅读 分享


一、fail2ban 是什么

fail2ban 是一个开源的入侵防护工具,通过实时监控日志文件,根据预定义的规则自动识别恶意行为,并调用防火墙(firewalld / iptables)封禁来源 IP。

核心能力:

  • 实时监控日志,无需定时任务
  • 支持正则匹配,灵活定义"恶意行为"
  • 自动调用系统防火墙封禁 / 解封
  • 支持设置封禁时长,到期自动解封
  • 支持递增封禁(repeat offenders)
  • 支持邮件通知(可选)

二、安装

dnf install -y epel-release
dnf install -y fail2ban

验证安装:

fail2ban-client --version

三、目录结构

/etc/fail2ban/
├── fail2ban.conf        # 主配置(一般不改)
├── jail.conf            # 默认规则(不要直接改,升级会覆盖)
├── jail.local           # 自定义规则(写在这里)
├── jail.d/              # 额外 jail 配置目录
├── filter.d/            # 过滤器目录(定义匹配规则)
│   ├── apache-scan.conf # 你自己写的
│   └── apache-error.conf
├── action.d/            # 动作目录(定义封禁方式)
│   └── firewallcmd-rich-rules.conf  # 调用 firewalld
└── action.d/
核心原则: 不要改 jail.conf 和 filter.d/ 下的默认文件,自定义内容写到 jail.local 和新建的 filter 文件中,升级不会被覆盖。

四、核心概念

4.1 Jail(监狱)

一条防护规则,定义了监控哪个日志、用什么过滤器、匹配多少次后封禁、封禁多久。

4.2 Filter(过滤器)

定义正则表达式,从日志中提取恶意行为的特征行。

4.3 Action(动作)

定义封禁方式,比如调用 firewalld、iptables、发送邮件等。

4.4 工作流程

日志文件 → Filter(正则匹配)→ 达到阈值 → Action(封禁IP)
                                                                             → 到期自动解封

4.5 关键参数

参数 含义 示例
enabled 是否启用 true / false
port 监控的端口 http,https
filter 使用的过滤器名称 apache-scan
logpath 监控的日志文件路径 /Data/.../access.log
maxretry 触发封禁的匹配次数 30
findtime 统计次数的时间窗口(秒) 60
bantime 封禁持续时间(秒),-1 为永久 86400(24小时)
banaction 封禁使用的动作 firewallcmd-rich-rules

五、实战配置

5.1 创建过滤器一:扫描行为检测(access.log)

cat > /etc/fail2ban/filter.d/apache-scan.conf << 'EOF'
[Definition]

failregex = ^<HOST> -.*"(GET|POST|HEAD).*/(wp-admin|wp-login|xmlrpc\.php|wp-json).*".*$
            ^<HOST> -.*"(GET|POST|HEAD).*/\.?env.*".*$
            ^<HOST> -.*"(GET|POST|HEAD).*/\.git(/|config).*".*$
            ^<HOST> -.*"(GET|POST|HEAD).*/\.gitlab-ci\.yml.*".*$
            ^<HOST> -.*"(GET|POST|HEAD).*/\.github/.*".*$
            ^<HOST> -.*"(GET|POST|HEAD).*/\.idea/.*".*$
            ^<HOST> -.*"(GET|POST|HEAD).*/\.vscode/.*".*$
            ^<HOST> -.*"(GET|POST|HEAD).*/(amplify\.yml|firebase\.json|vite\.config|nuxt\.config|next\.config)\.?.*".*$
            ^<HOST> -.*"(GET|POST|HEAD).*/(Jenkinsfile|panel|\.pypirc|composer\.json).*".*$
            ^<HOST> -.*"(GET|POST|HEAD).*/(db|database)\.sql.*".*$
            ^<HOST> -.*"(GET|POST|HEAD).*/(storage/logs|var/log|config)\b.*".*$
            ^<HOST> -.*"(GET|POST|HEAD).*/goform/.*".*$

ignoreregex =
EOF

涵盖的扫描类别:

类别 匹配的路径特征
WordPress 扫描 wp-admin、wp-login、xmlrpc.php、wp-json
环境文件泄露 .env、env.js、environment.ts 等
Git 仓库暴露 .git/、.git/config
CI/CD 配置 .gitlab-ci.yml、.github/workflows/
IDE 配置泄露 .idea/、.vscode/
框架配置文件 vite.config、nuxt.config、next.config、firebase.json
开发工具文件 Jenkinsfile、.pypirc、composer.json
数据库文件 db.sql、database.sql
日志泄露 storage/logs、var/log
设备探测 goform/

5.2 创建过滤器二:错误日志检测(error.log)

cat > /etc/fail2ban/filter.d/apache-error.conf << 'EOF'
[Definition]

failregex = ^.*$$client <HOST>$$ .* (AH01630|AH01797|AH00128):.*
            ^.*$$client <HOST>$$ (File does not exist|script not found|denied by server configuration).*$
            ^.*$$client <HOST>$$ .* (SQL injection|XSS|eval\(|base64_decode).*$
            ^.*$$client <HOST>$$ .* PHP (Fatal|Parse) error.*$

ignoreregex =
EOF

5.3 验证过滤器能否匹配日志

fail2ban-regex /Data/Public_Root/iewb.net/logs/access.log /etc/fail2ban/filter.d/apache-scan.conf

输出中 Failregex: 152 hits 表示匹配成功,过滤器可正常使用。

fail2ban-regex /Data/Public_Root/iewb.net/logs/error.log /etc/fail2ban/filter.d/apache-error.conf

5.4 创建 jail.local 配置

cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
# 封禁动作:使用 firewalld rich rules
banaction = firewallcmd-rich-rules
# 封禁时间:24小时(秒),-1 为永久
bantime = 86400
# 统计时间窗口:60秒内
findtime = 60
# 忽略本机和指定IP(多个用空格分隔)
ignoreip = 127.0.0.1/8

# ============ 扫描行为防护 ============
[apache-scan]
enabled  = true
port     = http,https
filter   = apache-scan
logpath  = /Data/Public_Root/iewb.net/logs/access.log
maxretry = 30
findtime = 60
bantime  = 86400

# ============ 错误日志防护 ============
[apache-error]
enabled  = true
port     = http,https
filter   = apache-error
logpath  = /Data/Public_Root/iewb.net/logs/error.log
maxretry = 10
findtime = 60
bantime  = 86400
EOF
多网站场景:每个网站单独加一个 jail 块,指定不同的 logpath 即可。

5.5 启动与开机自启

systemctl enable --now fail2ban

六、常用管理命令

6.1 查看状态

# 查看所有 jail 列表
fail2ban-client status

# 查看某个 jail 详情(含封禁 IP 数量和列表)
fail2ban-client status apache-scan
fail2ban-client status apache-error

# 只看被封禁的 IP
fail2ban-client status apache-scan | grep "Banned IP"

6.2 手动封禁 / 解封

# 手动封禁
fail2ban-client set apache-scan banip 1.2.3.4

# 手动解封
fail2ban-client set apache-scan unbanip 1.2.3.4

6.3 查看日志

# 实时跟踪
tail -f /var/log/fail2ban.log

# 查看今天的封禁记录
grep "Ban" /var/log/fail2ban.log | grep "$(date +%Y-%m-%d)"

6.4 重载配置

# 修改 jail.local 或过滤器后重载
fail2ban-client reload

# 或重启
systemctl restart fail2ban

6.5 暂停与恢复

# 暂停(不封新 IP,已封的保留)
fail2ban-client stop apache-scan

# 恢复
fail2ban-client start apache-scan

七、进阶用法

7.1 修改封禁时间

# 查看当前封禁时间
fail2ban-client get apache-scan bantime

# 临时修改为永久封禁
fail2ban-client set apache-scan bantime -1

# 临时修改为 1 小时
fail2ban-client set apache-scan bantime 3600

7.2 忽略特定 IP

jail.local[DEFAULT] 中:

# 多个 IP 用空格分隔,支持 CIDR
ignoreip = 127.0.0.1/8 1.2.3.4 10.0.0.0/8

7.3 查看 firewalld 中 fail2ban 添加的规则

firewall-cmd --list-rich-rules | grep fail2ban

7.4 递增封禁时间(repeat offenders)

jail.local 中对应 jail 下添加:

[apache-scan]
bantime          = 3600
bantime.increment = true
bantime.factor    = 24
bantime.maxtime   = 604800

效果:第 1 次封 1 小时 → 第 2 次封 24 小时 → 第 3 次封 7 天

7.5 SSH 暴力破解防护

jail.local 中添加:

[sshd]
enabled  = true
port     = ssh
filter   = sshd
logpath  = /var/log/secure
maxretry = 5
findtime = 600
bantime  = 3600

八、故障排查

# 测试过滤器是否能匹配日志
fail2ban-regex /Data/Public_Root/iewb.net/logs/access.log /etc/fail2ban/filter.d/apache-scan.conf

# 检查配置语法
fail2ban-client --test

# 查看详细运行日志
journalctl -u fail2ban -f

# 确认 firewalld 正常运行
systemctl status firewalld

# 查看 fail2ban 运行状态
systemctl status fail2ban

九、速查表

项目 说明
配置文件 /etc/fail2ban/jail.local
过滤器目录 /etc/fail2ban/filter.d/*.conf
日志文件 /var/log/fail2ban.log
启动服务 systemctl enable --now fail2ban
查看状态 fail2ban-client status apache-scan
查看封禁 IP fail2ban-client status apache-scan | grep "Banned IP"
解封 IP fail2ban-client set apache-scan unbanip x.x.x.x
重载配置 fail2ban-client reload
测试过滤器 fail2ban-regex 日志路径 过滤器路径
查看日志 tail -f /var/log/fail2ban.log

 


发表评论
回复 取消回复
验证码
更多文章 下一页