一、简介

1、什么是 Fail2ban

Fail2ban 是一个入侵防御软件框架,用于保护计算机服务器免受暴力攻击。它通过监控服务日志文件,检测恶意行为模式,并采取相应的防御措施(通常是更新防火墙规则来封禁攻击者的 IP 地址)。

2、主要特性

  • 日志监控: 实时监控各种服务的日志文件
  • 模式匹配: 使用正则表达式识别失败的登录尝试
  • 自动封禁: 自动封禁触发规则的 IP 地址
  • 多服务支持: 支持 SSH、Apache、Nginx、Postfix 等多种服务
  • 灵活配置: 高度可配置的规则和动作
  • 自动解封: 可设置封禁时间,到期自动解封

3、应用场景

  • SSH 暴力破解防护
  • Web 服务器攻击防护
  • 邮件服务器防护
  • FTP 服务防护
  • 防止 DDoS 攻击

4、工作原理

基本流程

日志文件 → 监控进程 → 模式匹配 → 触发条件 → 执行动作 → 更新防火墙

详细步骤

  1. 监控日志: Fail2ban 持续监控指定的日志文件
  2. 匹配规则: 使用正则表达式匹配失败登录等恶意行为
  3. 计数统计: 统计指定时间窗口内的失败次数
  4. 触发阈值: 达到设定的失败次数阈值
  5. 执行动作: 调用 action(通常是 iptables 规则)
  6. 封禁 IP: 将恶意 IP 添加到防火墙黑名单
  7. 定时解封: 封禁时间到期后自动解封

二、安装配置

1、在 Debian/Ubuntu 上安装

# 更新包列表
sudo apt update

# 安装 fail2ban
sudo apt install fail2ban

# 启动服务
sudo systemctl start fail2ban

# 设置开机自启
sudo systemctl enable fail2ban

# 检查状态
sudo systemctl status fail2ban

2、在 CentOS/RHEL 上安装

# 安装 EPEL 仓库
sudo yum install epel-release

# 安装 fail2ban
sudo yum install fail2ban fail2ban-systemd

# 启动服务
sudo systemctl start fail2ban

# 设置开机自启
sudo systemctl enable fail2ban

# 检查状态
sudo systemctl status fail2ban

3、基本配置文件结构

/etc/fail2ban/
├── fail2ban.conf          # 主配置文件(不建议直接修改)
├── fail2ban.local         # 本地主配置(覆盖 .conf)
├── jail.conf              # jail 配置文件(不建议直接修改)
├── jail.local             # 本地 jail 配置(推荐使用)
├── jail.d/                # jail 配置目录
├── filter.d/              # 过滤器配置目录
├── action.d/              # 动作配置目录
└── paths-*.conf           # 路径配置文件

4、初始配置

# 复制默认配置文件
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

# 编辑本地配置
sudo vim /etc/fail2ban/jail.local

三、核心概念

1、Filter (过滤器)

过滤器定义了如何从日志文件中识别恶意行为。

示例/etc/fail2ban/filter.d/sshd.conf

[Definition]
# 定义失败模式
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from <HOST>( via \S+)?\s*$
            ^%(__prefix_line)sFailed (?:password|publickey) for .* from <HOST>(?: port \d*)?(?: ssh\d*)?$
            ^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>\s*$

# 定义忽略模式(可选)
ignoreregex =

2、Action (动作)

动作定义了当检测到恶意行为时应该执行什么操作。

示例/etc/fail2ban/action.d/iptables-multiport.conf

[Definition]
# 封禁动作
actionban = <iptables> -I f2b-<name> 1 -s <ip> -j <blocktype>

# 解封动作
actionunban = <iptables> -D f2b-<name> -s <ip> -j <blocktype>

# 启动时动作
actionstart = <iptables> -N f2b-<name>
              <iptables> -A f2b-<name> -j <returntype>
              <iptables> -I <chain> -p <protocol> -m multiport --dports <port> -j f2b-<name>

# 停止时动作
actionstop = <iptables> -D <chain> -p <protocol> -m multiport --dports <port> -j f2b-<name>
             <iptables> -F f2b-<name>
             <iptables> -X f2b-<name>

3、Jail (监狱)

Jail 是 fail2ban 的核心配置单元,组合了 filter 和 action。

基本参数:

  • enabled: 是否启用该 jail
  • port: 保护的端口
  • filter: 使用的过滤器名称
  • logpath: 监控的日志文件路径
  • maxretry: 最大重试次数
  • findtime: 查找时间窗口(秒)
  • bantime: 封禁时间(秒)
  • action: 执行的动作

四、配置详解

1、全局配置 (jail.local)

[DEFAULT]
# 忽略的 IP 地址(白名单)
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24

# 封禁时间(秒)-1 表示永久封禁
bantime = 3600

# 查找时间窗口(秒)
findtime = 600

# 最大重试次数
maxretry = 5

# 后端(监控方式)
backend = auto

# 邮件相关配置
destemail = admin@example.com
sender = fail2ban@example.com
mta = sendmail

# 默认 action
action = %(action_)s
# action_: 仅封禁
# action_mw: 封禁并发送邮件
# action_mwl: 封禁并发送包含日志的邮件

2、SSH 保护配置

[sshd]
enabled = true
port = ssh,22
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 600
bantime = 3600

3、Apache/Nginx 保护配置

[apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache*/*error.log
maxretry = 5
bantime = 3600

[nginx-http-auth]
enabled = true
filter = nginx-http-auth
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 5
bantime = 3600

[nginx-noscript]
enabled = true
port = http,https
filter = nginx-noscript
logpath = /var/log/nginx/access.log
maxretry = 6
bantime = 3600

[nginx-badbots]
enabled = true
port = http,https
filter = nginx-badbots
logpath = /var/log/nginx/access.log
maxretry = 2
bantime = 86400

4、自定义 Filter 示例

创建文件 /etc/fail2ban/filter.d/custom-app.conf:

[Definition]
# 匹配登录失败
failregex = ^.*Login failed for user .* from <HOST>.*$
            ^.*Invalid authentication attempt from <HOST>.*$

# 忽略特定模式
ignoreregex = ^.*successful login.*$

# 日期格式
datepattern = ^%%Y-%%m-%%d %%H:%%M:%%S

5、自定义 Action 示例

创建文件 /etc/fail2ban/action.d/custom-notify.conf:

[Definition]
# 封禁时发送通知
actionban = curl -X POST https://api.example.com/alert \
            -d "ip=<ip>&action=ban&jail=<name>"

# 解封时发送通知
actionunban = curl -X POST https://api.example.com/alert \
              -d "ip=<ip>&action=unban&jail=<name>"

五、常用命令

1、服务管理

# 启动服务
sudo systemctl start fail2ban

# 停止服务
sudo systemctl stop fail2ban

# 重启服务
sudo systemctl restart fail2ban

# 重新加载配置
sudo systemctl reload fail2ban

# 查看状态
sudo systemctl status fail2ban

# 查看日志
sudo tail -f /var/log/fail2ban.log

2、fail2ban-client 命令

2.1查看状态

# 查看所有 jail 状态
sudo fail2ban-client status

# 查看特定 jail 状态
sudo fail2ban-client status sshd

# 查看被封禁的 IP
sudo fail2ban-client get sshd banip

# 查看当前被封禁的 IP 列表
sudo fail2ban-client status sshd | grep "Banned IP"

2.2手动封禁/解封

# 手动封禁 IP
sudo fail2ban-client set sshd banip 192.168.1.100

# 手动解封 IP
sudo fail2ban-client set sshd unbanip 192.168.1.100

# 解封所有 IP
sudo fail2ban-client unban --all

2.3Jail 管理

# 启动特定 jail
sudo fail2ban-client start sshd

# 停止特定 jail
sudo fail2ban-client stop sshd

# 重新加载 jail
sudo fail2ban-client reload sshd

# 查看 jail 配置
sudo fail2ban-client get sshd logpath
sudo fail2ban-client get sshd maxretry
sudo fail2ban-client get sshd bantime

2.4测试配置

# 测试配置文件语法
sudo fail2ban-client -t

# 测试正则表达式
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

# 详细测试输出
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf --print-all-matched

2.5iptables 命令(查看封禁规则)

# 查看所有 fail2ban 规则
sudo iptables -L -n

# 查看特定链
sudo iptables -L f2b-sshd -n -v

# 查看被封禁的 IP 数量
sudo iptables -L f2b-sshd -n | grep -c DROP

六、实战案例

1、加强 SSH 保护

需求: 防止 SSH 暴力破解,3 次失败尝试即封禁 1 小时

配置/etc/fail2ban/jail.local

[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 600
bantime = 3600
action = iptables[name=SSH, port=ssh, protocol=tcp]
         sendmail-whois[name=SSH, dest=admin@example.com]

2、 WordPress 登录保护

创建过滤器/etc/fail2ban/filter.d/wordpress-auth.conf

[Definition]
failregex = ^<HOST> .* "POST /wp-login.php
            ^<HOST> .* "POST /xmlrpc.php

ignoreregex =

配置 Jail/etc/fail2ban/jail.local

[wordpress-auth]
enabled = true
filter = wordpress-auth
logpath = /var/log/nginx/access.log
port = http,https
maxretry = 3
findtime = 600
bantime = 7200

3、防止端口扫描

创建过滤器/etc/fail2ban/filter.d/port-scan.conf

[Definition]
failregex = ^.*Denied .* from <HOST>.*$
ignoreregex =

配置 Jail/etc/fail2ban/jail.local

[port-scan]
enabled = true
filter = port-scan
logpath = /var/log/syslog
maxretry = 5
findtime = 300
bantime = 86400

4、配置邮件通知

全局配置/etc/fail2ban/jail.local

[DEFAULT]
# 邮件设置
destemail = admin@example.com
sender = fail2ban@example.com
sendername = Fail2Ban

# 使用带邮件的 action
action = %(action_mwl)s

配置发送邮件:

# 安装邮件工具
sudo apt install mailutils

# 测试邮件
echo "Test" | mail -s "Test Subject" admin@example.com

5、白名单配置

添加信任的 IP/etc/fail2ban/jail.local

[DEFAULT]
# 忽略特定 IP 和网段
ignoreip = 127.0.0.1/8 
           ::1 
           192.168.1.0/24 
           10.0.0.0/8

# 自己的办公室 IP
ignoreip = %(ignoreip)s 10.80.10.0/24

七、最佳实践

1、安全配置建议

1.1合理设置封禁时间

# 短期封禁(适用于一般情况)
bantime = 3600  # 1小时

# 长期封禁(适用于严重攻击)
bantime = 86400  # 24小时

# 永久封禁(谨慎使用)
bantime = -1

1.2调整重试次数

# SSH 服务(更严格)
maxretry = 3

# Web 服务(适当宽松)
maxretry = 5

1.3使用递增封禁时间

[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
action = iptables-allports[name=recidive]
bantime = 604800  # 7天
findtime = 86400  # 24小时
maxretry = 5

2、监控和维护

2.1定期检查日志

# 查看 fail2ban 日志
sudo tail -f /var/log/fail2ban.log

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

2.2监控封禁统计

# 创建监控脚本 /usr/local/bin/fail2ban-stats.sh
#!/bin/bash
echo "=== Fail2ban 统计 ==="
echo "当前活动的 Jails:"
sudo fail2ban-client status
echo ""
echo "各 Jail 详细状态:"
for jail in $(sudo fail2ban-client status | grep "Jail list" | sed -E 's/^[^:]+:[ \t]+//' | sed 's/,//g')
do
    echo "--- $jail ---"
    sudo fail2ban-client status $jail
done

2.3设置定期清理

# 添加到 crontab
# 每周日凌晨 2 点清理所有封禁
0 2 * * 0 /usr/bin/fail2ban-client unban --all

八、故障排查

1、配置测试不通过

# 检查配置语法
sudo fail2ban-client -t

# 查看详细错误
sudo fail2ban-client -vvv start

2、Filter 不工作

# 测试正则表达式
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

# 查看匹配到的内容
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf --print-all-matched

3、IP 未被封禁

# 检查 jail 是否运行
sudo fail2ban-client status sshd

# 检查日志路径是否正确
sudo fail2ban-client get sshd logpath

# 手动测试封禁
sudo fail2ban-client set sshd banip 1.2.3.4
sudo iptables -L f2b-sshd -n

4、服务启动失败

# 查看系统日志
sudo journalctl -u fail2ban -n 50

# 查看 fail2ban 日志
sudo tail -100 /var/log/fail2ban.log

# 检查权限
ls -la /var/run/fail2ban/
ls -la /var/log/fail2ban.log

九、高级配置技巧

1、配置递增封禁

# 对重复违规者加重处罚
[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
action = iptables-allports[name=recidive, protocol=all]
bantime = 1w
findtime = 1d
maxretry = 3

2、配置多个动作

[sshd]
enabled = true
filter = sshd
action = iptables[name=SSH, port=ssh, protocol=tcp]
         sendmail-whois[name=SSH, dest=admin@example.com]
         cloudflare[cfuser="user@example.com", cftoken="XXX"]

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐