Fail2ban 是什么?为什么你需要它
服务器暴露在公网上,每天都会遭受大量自动化脚本的扫描和暴力破解尝试。据统计,一台未加防护的 SSH 服务器每小时可能收到数千次登录尝试。仅靠强密码已经不够——攻击者的工具可以在几分钟内尝试数百万种组合。
Fail2ban 是一个基于日志的 IP 自动屏蔽工具。它通过实时监控系统日志,识别异常登录行为(如连续密码错误),然后自动调用防火墙规则临时封禁攻击者的 IP 地址。
Fail2ban 的核心价值:
- 自动化防护:无需人工干预,24 小时持续监控
- 轻量高效:占用极少系统资源,适合所有服务器
- 灵活可配:支持 SSH、Nginx、WordPress 等多种服务
- 自动解封:封禁期满后自动解除,避免永久封锁
Fail2ban 工作原理
Fail2ban 的工作流程可以简化为四个步骤:
- 日志监控:持续读取指定的日志文件(如
/var/log/auth.log) - 模式匹配:使用正则表达式(Filter)识别攻击特征
- 触发封禁:当失败次数超过阈值时,调用防火墙规则封锁 IP
- 自动解封:封禁时间到期后,自动移除封锁规则
核心概念:
- Jail(监狱):一个完整的防护单元,包含 Filter + Action + 日志路径 + 阈值
- Filter(过滤器):定义如何从日志中识别攻击行为
- Action(动作):定义触发封禁后执行的操作
安装 Fail2ban
Ubuntu/Debian 系统
# 更新软件包列表
sudo apt update
# 安装 Fail2ban
sudo apt install fail2ban -y
# 启动并设置开机自启
sudo systemctl enable --now fail2ban
CentOS/RHEL 系统
# 安装 EPEL 仓库
sudo yum install epel-release -y
# 安装 Fail2ban
sudo yum install fail2ban -y
# 启动服务
sudo systemctl enable --now fail2ban
验证安装
# 检查服务状态
sudo systemctl status fail2ban
# 查看版本号
fail2ban-client version
配置 SSH 防护(核心配置)
Fail2ban 有两个关键配置文件:
jail.conf:默认配置,不要直接修改jail.local:用户自定义配置,优先级更高
所有自定义配置都应该写在 jail.local 中,这样升级 Fail2ban 后不会覆盖你的配置。
创建 jail.local
# 复制默认配置为本地配置
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# 编辑配置文件
sudo nano /etc/fail2ban/jail.local
完整的 SSH 防护配置
在 jail.local 中添加以下内容:
[DEFAULT]
# ── 全局基础设置 ──────────────────────────────
# 白名单:这些 IP 永远不会被封禁
# 强烈建议把你的固定办公 IP 加进来,防止误封自己
ignoreip = 127.0.0.1/8 ::1
# 封禁时长(秒):-1 表示永久封禁,推荐生产环境用 86400(1天)
bantime = 86400
# 检测时间窗口(秒):在此时间内达到 maxretry 次则封禁
findtime = 600
# 最大失败次数:600 秒内失败 5 次即封禁
maxretry = 5
# 封禁动作:推荐使用 nftables-multiport(2026年主流)
banaction = nftables-multiport
# 日志读取后端:systemd 适用于现代 Linux 发行版
backend = systemd
[sshd]
# ── SSH 防护配置 ──────────────────────────────
enabled = true
port = ssh
# 如果你修改了 SSH 端口,将 ssh 改为实际端口号
# port = 2222
# SSH 使用更严格的策略
maxretry = 3 # SSH 只允许失败 3 次
bantime = 86400 # 封禁 24 小时
findtime = 300 # 5 分钟内统计
关键参数说明:
| 参数 | 说明 | 推荐值 |
|---|---|---|
| ignoreip | 白名单 IP,不会被封禁 | 127.0.0.1/8 ::1 + 你的 IP |
| bantime | 封禁时长(秒) | 86400(1天) |
| findtime | 统计时间窗口(秒) | 600(10分钟) |
| maxretry | 最大失败次数 | 3-5 |
| banaction | 防火墙动作 | nftables-multiport |
| backend | 日志读取方式 | systemd |
应用配置
# 重启 Fail2Ban 使配置生效
sudo systemctl restart fail2ban
# 查看 SSH jail 状态
sudo fail2ban-client status sshd
验证 Fail2ban 是否正常工作
查看封禁状态
# 查看所有已启用的 jail 列表
sudo fail2ban-client status
# 查看 SSH jail 详细状态(含已封禁 IP 列表)
sudo fail2ban-client status sshd
实时监控日志
# 实时查看 Fail2Ban 日志
sudo tail -f /var/log/fail2ban.log
手动测试封禁
# 手动封禁一个 IP(测试用)
sudo fail2ban-client set sshd banip 1.2.3.4
# 手动解封一个 IP
sudo fail2ban-client set sshd unbanip 1.2.3.4
操作前务必确认:在配置 ignoreip 时,将你当前使用的 IP 加入白名单。如果不确定自己的 IP,执行 curl ifconfig.me 查看。否则一旦测试封禁,你可能把自己锁在外面。
防护 Nginx 和 WordPress 登录
Fail2ban 不只能防护 SSH,还能防护 Nginx 暴力请求和 WordPress 登录爆破。在 jail.local 末尾追加以下配置:
[nginx-http-auth]
# ── Nginx 基础认证暴力破解防护 ─────────────────
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 5
bantime = 3600
[nginx-botsearch]
# ── 防护恶意扫描器(扫描 wp-admin、phpMyAdmin 等)──
enabled = true
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 2
bantime = 86400
filter = nginx-botsearch
[wordpress-auth]
# ── WordPress 登录暴力破解防护 ──────────────────
enabled = true
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 5
bantime = 86400
findtime = 300
创建自定义过滤器
为 WordPress 创建登录过滤规则文件:
sudo nano /etc/fail2ban/filter.d/wordpress-auth.conf
添加以下内容:
[Definition]
failregex = ^<HOST>.* "POST /wp-login\.php HTTP/.*" (200|401|403)
ignoreregex =
测试过滤规则
# 测试过滤规则是否正确匹配日志
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/wordpress-auth.conf
防火墙集成方案
2026 年,推荐使用 nftables 作为防火墙后端,性能更高、规则更清晰。
nftables 配置(推荐)
[DEFAULT]
banaction = nftables-multiport
banaction_allports = nftables[type=allports]
iptables 配置(传统方案)
[DEFAULT]
banaction = iptables-multiport
banaction_allports = iptables-allports
UFW 配置(Ubuntu 简单方案)
[DEFAULT]
banaction = ufw
firewalld 配置(RHEL/CentOS)
[DEFAULT]
banaction = firewallcmd-rich-rules
检查防火墙规则是否生效:
# nftables
sudo nft list ruleset | grep -A 15 f2b
# iptables
sudo iptables -L f2b-sshd -n --line-numbers
Fail2ban 常用命令速查
服务管理
# 启动服务
sudo systemctl start fail2ban
# 停止服务
sudo systemctl stop fail2ban
# 重启服务
sudo systemctl restart fail2ban
# 查看状态
sudo systemctl status fail2ban
状态查看
# 查看所有 jail 状态
sudo fail2ban-client status
# 查看指定 jail 状态
sudo fail2ban-client status sshd
# 查看被封禁的 IP
sudo fail2ban-client banned
IP 管理
# 手动封禁 IP
sudo fail2ban-client set sshd banip 1.2.3.4
# 手动解封 IP
sudo fail2ban-client set sshd unbanip 1.2.3.4
# 查看指定 jail 的封禁 IP
sudo fail2ban-client get sshd banip
配置管理
# 验证配置语法
sudo fail2ban-client -t
# 重新加载配置
sudo fail2ban-client reload
常见问题与解决方案
问题 1:Fail2ban 启动失败
原因:配置文件语法错误或防火墙后端不匹配。
解决方法:
# 检查配置语法
sudo fail2ban-client -t
# 查看错误日志
sudo journalctl -u fail2ban -n 50
问题 2:IP 封禁不生效
原因:banaction 与系统防火墙不匹配。
解决方法:
# 检查当前使用的防火墙
sudo iptables -L -n | head -20
# 或
sudo nft list ruleset | head -20
# 确保 jail.local 中的 banaction 匹配
问题 3:误封自己 IP
解决方法:
# 立即解封
sudo fail2ban-client set sshd unbanip 你的IP
# 将 IP 加入白名单
# 编辑 /etc/fail2ban/jail.local,在 ignoreip 中添加你的 IP
sudo systemctl restart fail2ban
SSH 安全加固进阶
Fail2ban 是事后封禁,配合以下措施可以从根源上减少攻击面:
修改 SSH 默认端口
sudo nano /etc/ssh/sshd_config
# 将 Port 22 改为高位随机端口
Port 22345
# 重启 SSH(确保新端口连接成功后再关闭旧连接)
sudo systemctl restart sshd
注意:记得同步更新 Fail2ban 中的 SSH 端口配置!
禁用密码登录,改用密钥
sudo nano /etc/ssh/sshd_config
# 修改以下配置
PermitRootLogin prohibit-password # root 只能用密钥登录
PasswordAuthentication no # 完全禁用密码认证
PubkeyAuthentication yes # 启用密钥认证
操作顺序:必须先把你的公钥添加到 ~/.ssh/authorized_keys,验证密钥登录成功后,再禁用密码认证。否则会把自己锁在外面。
安全加固 Checklist
| 优先级 | 安全措施 | 难度 | 效果 |
|---|---|---|---|
| 🔴 必做 | 安装并启用 Fail2ban | 低 | 自动封禁暴力破解 IP |
| 🔴 必做 | 使用强密码(16位以上+特殊字符) | 低 | 防止简单密码被破解 |
| 🔴 必做 | 云平台安全组限制 SSH 来源 IP | 低 | 从网络层封堵攻击 |
| 🟡 推荐 | 修改 SSH 默认端口(22 → 高位端口) | 低 | 减少 90% 自动化扫描 |
| 🟡 推荐 | 禁用密码登录,改用 SSH 密钥 | 中 | 彻底杜绝密码暴破 |
| 🟡 推荐 | 禁用 root 直接登录 | 低 | 减少高权限账号暴露 |
| 🟢 进阶 | 配置 Fail2ban 邮件告警 | 中 | 实时掌握攻击动态 |
| 🟢 进阶 | 配置 Nginx/WordPress 登录防护 | 中 | 防护 Web 应用暴力破解 |
总结
Fail2ban 是 Linux 服务器安全防护的第一道防线,通过 30 分钟的配置,你可以将暴力破解风险降低 90% 以上。推荐的安全防护组合:
- 云平台安全组:限制只有指定来源 IP 能访问 SSH
- Fail2ban:自动封禁暴力破解的恶意 IP
- SSH 密钥登录:彻底禁用密码认证
- 修改默认端口:减少自动化扫描攻击
这套分层防御体系可以有效保护你的服务器安全,让攻击者在第一层就被拦截。记住,安全不是一次性工作,而是持续的过程——定期检查 Fail2ban 日志,及时更新白名单,保持系统和软件的更新。