VPS 安全 · Linux
Fail2ban 完整指南 2026:保护 VPS 免受 SSH 暴力破解攻击
目录
每台上线的 VPS 都会持续遭受 SSH 暴力破解攻击——机器人 24 小时扫描 22 端口,不断尝试用户名和密码组合。Fail2ban 是 Linux 服务器的行业标准工具,能够检测这些攻击并自动在防火墙层面封禁攻击 IP。
Fail2ban 是什么?
Fail2ban 是一个基于 Python 的开源守护程序,监控日志文件中的可疑模式(如重复的登录失败),并通过系统防火墙(iptables、nftables、ufw 或 firewalld)临时封禁违规 IP 地址。
当前稳定版本为 v1.1.x,需要 Python ≥ 3.5。内置针对 SSH、Nginx、Apache、Postfix 等数十种服务的过滤器,采用 GPLv2 许可证,完全免费。
- 100% 免费开源(GPLv2)
- 自 v0.10 起支持 IPv6
- 兼容 iptables、nftables、ufw、pf(BSD)和 firewalld
- 内置 SSH、Web 服务器、邮件服务器、FTP 等过滤器
- 轻量级——通常仅占用 10-20 MB 内存
已验证事实(GitHub fail2ban/fail2ban,2026 年 10 月)
Fail2ban v1.1.x · 需要 Python ≥ 3.5 · GPLv2 许可证 · 自 v0.10 起支持 IPv6 · 兼容 iptables / nftables / ufw
工作原理
Fail2ban 分三个阶段运作:
- 日志监控——持续读取
/var/log/auth.log、/var/log/nginx/access.log等日志文件 - 模式匹配——使用正则表达式(过滤器)检测可疑行,如"Failed password"或"Invalid user"
- 执行动作——当某 IP 在
findtime秒内超过maxretry次失败,将封禁该 IPbantime时长
# SSH 暴力破解日志示例
Oct 30 01:23:45 server sshd[1234]: Failed password for root from 45.142.212.10 port 54321 ssh2
Oct 30 01:23:47 server sshd[1234]: Failed password for root from 45.142.212.10 port 54321 ssh2
Oct 30 01:23:49 server sshd[1234]: Failed password for root from 45.142.212.10 port 54321 ssh2
# → 达到 maxretry=3,IP 被封禁
在 Ubuntu/Debian 上安装 Fail2ban
# 更新软件包列表并安装
sudo apt update
sudo apt install fail2ban -y
# 检查服务状态
sudo systemctl status fail2ban
# 设置开机自启
sudo systemctl enable fail2ban
CentOS/AlmaLinux/Rocky Linux
sudo dnf install epel-release -y
sudo dnf install fail2ban -y
sudo systemctl enable --now fail2ban
配置 jail.local
重要:不要直接修改 /etc/fail2ban/jail.conf,更新时会被覆盖。应创建 jail.local 来覆盖默认配置:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
[DEFAULT] 基本设置
[DEFAULT]
# 封禁时长——1h = 封禁 1 小时
bantime = 1h
# 检测窗口——在此时间内统计失败次数
findtime = 10m
# 封禁前允许的失败次数
maxretry = 5
# 永不封禁的 IP(务必添加您自己的 IP!)
ignoreip = 127.0.0.1/8 ::1 YOUR_HOME_IP/32
# 日志后端(auto = 自动检测最佳选项)
backend = auto
保护 SSH
在 jail.local 中添加:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 2h
findtime = 5m
修改后重新加载配置:
sudo systemctl reload fail2ban
保护 Nginx、Apache 和 WordPress
Nginx
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2
WordPress 登录保护
创建自定义过滤器文件:
sudo nano /etc/fail2ban/filter.d/wordpress.conf
[Definition]
failregex = ^<HOST>.*POST.*(wp-login\.php|xmlrpc\.php).* 200
ignoreregex =
在 jail.local 中添加:
[wordpress]
enabled = true
port = http,https
filter = wordpress
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 5m
bantime = 24h
常用命令
| 命令 | 说明 |
|---|---|
sudo fail2ban-client status | 列出所有活跃的 jail |
sudo fail2ban-client status sshd | 查看 sshd jail 状态和已封禁 IP |
sudo fail2ban-client set sshd unbanip 1.2.3.4 | 解封指定 IP |
sudo fail2ban-client set sshd banip 1.2.3.4 | 手动封禁 IP |
sudo fail2ban-client reload | 重新加载配置(无需重启) |
sudo tail -f /var/log/fail2ban.log | 实时查看日志 |
高级配置:Recidive Jail(惯犯封禁)
Recidive jail 针对多次被封禁的 IP 实施更长时间的封禁(1周或永久),阻止攻击者等待封禁解除后再次尝试。
[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
action = iptables-allports[name=recidive]
bantime = 1w
findtime = 1d
maxretry = 5
Fail2ban 与 CrowdSec 对比
| 特性 | Fail2ban | CrowdSec |
|---|---|---|
| 费用 | 免费(GPLv2) | 免费(MIT) |
| 威胁情报 | 仅本地日志 | 众包 + 共享封禁列表 |
| 配置复杂度 | 简单,快速 | 较复杂(API、bouncer) |
| 误封率 | 偶尔 | 较低(社区验证) |
| 内存占用 | 约 10-20 MB | 略多 |
| 适用场景 | 单台 VPS、简单部署 | 多服务器、企业级 |
建议:对于单台 VPS 或小型企业服务器,建议从 Fail2ban 开始——配置简单,文档丰富,是全球系统管理员熟悉的标准工具。如果您管理多台服务器并希望共享威胁情报,可以考虑 CrowdSec。
常见问题
Q:Fail2ban 支持 UFW 吗?
A:支持。在 jail.local 中设置 banaction = ufw,或使用 action = %(action_)s 自动检测防火墙后端。
Q:Fail2ban 重启后封禁列表会丢失吗?
A:新版本默认使用 SQLite 数据库持久化封禁记录(/var/lib/fail2ban/fail2ban.sqlite3),重启后封禁仍然有效。
Q:不小心封禁了自己的 IP 怎么办?
A:使用 VPS 服务商提供的紧急控制台(KVM/IPMI)登录,然后运行:sudo fail2ban-client set sshd unbanip YOUR_IP
Q:SSH 的 maxretry 应该设置为多少?
A:建议设置为 3。合法用户很少输错密码超过 3 次。务必将自己的 IP 加入白名单以防止意外封禁。