
任何具有公共 IP 的 VPS 都会全天候面临 SSH 暴力攻击。来自世界各地的机器人扫描端口 22 并每天尝试数百万个用户名/密码组合。即使使用强密码,这些尝试也会浪费 CPU 资源并用噪音充满您的 auth.log,使得很难发现真实事件。
Fail2Ban 旨在直接解决此问题。它实时监控您的日志文件并自动禁止超过您登录失败阈值的 IP。本指南指导您在 Ubuntu 22.04 上完成设置。
前置要求: 具有根或 sudo 访问权限的 Ubuntu 20.04/22.04 VPS,可通过 SSH 访问。
什么是 SSH 暴力攻击?
暴力攻击意味着尝试每个可能的用户名/密码组合:root/123456、admin/password 或来自以前数据泄露的凭据。即使您的密码是破不了的,不断的请求洪泛也会消耗服务器资源并污染您的日志。
Fail2Ban 如何工作
Fail2Ban 是用 Python 编写的入侵防御框架。它分三个阶段运作:
- 监控: 实时读取日志文件,例如
/var/log/auth.log。 - 检测: 将行与过滤器模式匹配(例如,"Failed password for root from 1.2.3.4")。
- 行动: 添加 iptables 或 nftables 规则以暂时阻止该 IP。
一旦 IP 被禁止,来自该来源的所有流量都将在防火墙处被丢弃。Fail2Ban 在配置的禁止持续时间后自动解除 IP 禁令(默认值:10 分钟)。
步骤 1 — 更新系统并安装 Fail2Ban
sudo apt update && sudo apt upgrade -y sudo apt install fail2ban -y
验证安装并确认它正在运行:
sudo systemctl status fail2ban
如果您看到 Active: active (running),Fail2Ban 已经用默认设置保护您的服务器。
启用重启时自动启动:
sudo systemctl enable fail2ban
步骤 2 — 了解配置结构
Fail2Ban 使用两个关键配置文件:
/etc/fail2ban/jail.conf— 默认包配置。永远不要直接编辑此文件;在包升级时会被覆盖。/etc/fail2ban/jail.local— 您的自定义覆盖。自己创建此文件。
最佳做法: 始终仅编辑 jail.local。保持 jail.conf 未触及,以便您的配置在包更新时得以保留。
步骤 3 — 创建并配置 jail.local
创建文件:
sudo nano /etc/fail2ban/jail.local
粘贴以下配置并根据您的需要调整值:
[DEFAULT] # Ban an IP that fails login 5 times within 10 minutes bantime = 3600 # Ban duration: 1 hour (seconds) findtime = 600 # Detection window: 10 minutes maxretry = 5 # Failures allowed before ban # IPs to never ban (your own machine) ignoreip = 127.0.0.1/8 ::1 [sshd] enabled = true port = ssh filter = sshd logpath = /var/log/auth.log maxretry = 3 # Stricter for SSH — 3 strikes and you're banned bantime = 7200 # Ban for 2 hours
⚠️ 重要: 如果您更改了 SSH 端口,请明确指定,例如 port = 2222 而不是 port = ssh。否则 Fail2Ban 不会监控您实际使用的端口。
使用 Ctrl+O 保存文件,使用 Ctrl+X 退出,然后重启 Fail2Ban:
sudo systemctl restart fail2ban
步骤 4 — 检查状态和活动监狱
查看所有 Fail2Ban 监狱的摘要:
sudo fail2ban-client status
查看 SSH 监狱的具体详情:
sudo fail2ban-client status sshd
输出显示当前被禁止的 IP 数量和曾经被禁止的总 IP 数量。
步骤 5 — 解除 IP 禁止
如果合法用户意外被禁止,立即解除禁止:
sudo fail2ban-client set sshd unbanip 1.2.3.4
用实际 IP 地址替换 1.2.3.4。
预防提示: 在 jail.local 中的 ignoreip 行添加您自己的 IP,这样您永远不会意外锁定自己。
步骤 6 — 监控日志
Fail2Ban 将每个禁止和解除禁止操作记录到:
sudo tail -f /var/log/fail2ban.log
显示正在应用的禁止的示例日志输出:
2026-05-11 14:32:01,782 fail2ban.actions [12345]: NOTICE [sshd] Ban 185.22.xxx.xxx 2026-05-11 14:32:01,783 fail2ban.actions [12345]: NOTICE [sshd] Ban 91.108.xxx.xxx
确认 Fail2Ban 正在捕获实际的暴力尝试:
sudo grep "Failed password" /var/log/auth.log | tail -20
额外功能:Recidive 监狱 — 对重复违规者的长期禁止
Recidive 监狱如果 IP 持续重复被禁止,将禁止该 IP 整整一周。将其添加到 jail.local:
[recidive] enabled = true logpath = /var/log/fail2ban.log banaction = %(banaction_allports)s bantime = 604800 # 1 week findtime = 86400 # Look back 1 day maxretry = 3 # Banned 3 times in 1 day → 1-week ban
为 Nginx、Apache 和 WordPress 添加监狱
Fail2Ban 的保护不仅限于 SSH。如果您的 VPS 运行 Nginx 或 Apache 等 web 服务器,您可以添加监狱来阻止发起 7 层攻击的 IP:针对 WordPress 登录的暴力攻击、快速 404 探测以扫描漏洞,或激进爬取浪费带宽的恶意机器人。
Nginx 监狱(HTTP 身份验证 + 恶意机器人)
为运行 Nginx 的 VPS 服务器将以下内容添加到 /etc/fail2ban/jail.local:
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 5
bantime = 3600
[nginx-botsearch]
enabled = true
filter = nginx-botsearch
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 10
findtime = 600
bantime = 7200 # Block bots scanning for vulnerable pathsApache 监狱
如果您的 VPS 使用 Apache(例如,使用 DirectAdmin),请使用 apache-* 过滤器系列:
[apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache2/error.log
maxretry = 5
bantime = 3600
[apache-badbots]
enabled = true
port = http,https
filter = apache-badbots
logpath = /var/log/apache2/access.log
maxretry = 2
bantime = 86400 # Block bad bots for 1 dayWordPress 监狱(wp-login.php / xmlrpc.php)
WordPress 是通过 wp-login.php 和 xmlrpc.php 的主要暴力攻击目标。Fail2Ban 没有内置的 WordPress 过滤器,所以在 /etc/fail2ban/filter.d/wordpress.conf 创建一个:
[Definition]
failregex = ^<HOST> .* "POST /wp-login.php
^<HOST> .* "POST /xmlrpc.php
ignoreregex =然后在 jail.local 中添加引用此过滤器的监狱(设置 logpath 匹配您域的访问日志):
[wordpress] enabled = true filter = wordpress port = http,https logpath = /var/log/nginx/access.log maxretry = 5 findtime = 300 bantime = 7200
⚠️ 注意: 如果您的网站位于 Cloudflare 或反向代理后面,日志中的 IP 将是代理的 IP,而不是真实访问者的 IP。首先配置 Nginx/Apache 记录 X-Forwarded-For,否则 Fail2Ban 将禁止 Cloudflare 的 IP 而不是攻击者的 IP。
添加任何新监狱后,始终重新加载并确认过滤器没有语法错误:
sudo fail2ban-client reload sudo fail2ban-client status
使用 fail2ban-client 检查和管理禁止
一旦您运行多个监狱,您需要 fail2ban-client 命令来获得概览并管理被禁止的 IP。以下是基础内容。
列出所有活动监狱:
sudo fail2ban-client status
查看特定监狱的详情,包括当前被禁止的 IP:
sudo fail2ban-client status wordpress
下表总结了您最常使用的管理命令:
| 命令 | 作用 |
|---|---|
fail2ban-client status |
列出所有运行的监狱 |
fail2ban-client status sshd |
显示 sshd 监狱中的被禁止 IP |
fail2ban-client set sshd unbanip IP |
解除指定 IP 的禁止 |
fail2ban-client set sshd banip IP |
立即手动禁止一个 IP |
fail2ban-client reload |
重新加载配置而不停止服务 |
要快速计算已应用的禁止总数,grep 日志文件:
sudo zgrep "Ban" /var/log/fail2ban.log* | wc -l
此命令包括压缩(.gz)的轮转日志,为您提供自启动以来已阻止的攻击数量的完整情况。
白名单 IP 和常见问题
困扰每个管理员的问题是"禁止自己"和被锁定。设置正确的白名单(ignoreip)与禁止规则一样重要。将您的家庭/办公室 IP 和任何信任的内部范围添加到 jail.local:
[DEFAULT]
# Separate each IP/range with a space — supports IPv4 and IPv6
ignoreip = 127.0.0.1/8 ::1 203.0.113.45 198.51.100.0/24编辑 ignoreip 后,始终运行 sudo systemctl restart fail2ban 使更改生效。下表列出常见问题及其修复方法:
| 症状 | 原因 / 修复 |
|---|---|
| Fail2Ban 永远不禁止任何 IP | logpath 指向错误的文件,或 SSH 使用未在监狱中声明的端口 |
| 突然无法 SSH 连接 | 您禁止了自己 — 使用您的提供商的控制台,然后解除禁止并添加 ignoreip |
| 禁止 Cloudflare IP | 日志记录代理 IP — 在 web 服务器中配置 real_ip / X-Forwarded-For |
| 较新的 Ubuntu 没有 auth.log | 某些 Ubuntu 版本使用 journald — 在监狱中设置 backend = systemd |
防止锁定提示: 如果您使用经常变化的动态家庭 IP,请设置 SSH 密钥身份验证并完全禁用密码登录。这样更安全,并消除了 SSH 暴力攻击的顾虑。
设置检查清单
- 安装 Fail2Ban 并启用自动启动。
- 创建
/etc/fail2ban/jail.local— 永远不要编辑jail.conf。 - 使用正确的端口号配置
[sshd]监狱。 - 将您自己的 IP 添加到
ignoreip以避免锁定自己。 - 使用
fail2ban-client status sshd进行验证。 - 可选地为持久攻击者启用 Recidive 监狱。
关于 Fail2Ban 的常见问题
Fail2Ban 与防火墙(UFW/iptables)有什么不同?
像 UFW 或 iptables 这样的防火墙设置静态规则来确定哪些端口是打开还是关闭的。Fail2Ban 是一个动态系统,它读取日志并指示防火墙阻止表现出攻击行为的 IP,然后在计时器过期时解除禁止。它们一起工作 — Fail2Ban 为您添加临时 iptables/nftables 规则。您不必二选一;您应该同时运行两者。
Fail2Ban 会大量使用 VPS 资源吗?
几乎不会。Fail2Ban 是一个 Python 守护进程,tail 日志文件,使用大约 20-40 MB 的 RAM,对典型 VPS 的 CPU 影响可以忽略不计。即使是 AsiaGB 500 泰铢/月的入门级 VPS 也可以舒适地运行它,不会影响您的网站或应用 — 除非您在多 GB 日志上设置非常宽的 findtime,但这很少见。
如果我更改了 SSH 端口,我仍然需要 Fail2Ban 吗?
您仍然应该这样做。更改端口会大大减少扫描端口 22 的机器人,但它不会阻止扫描所有端口或特别针对您的机器人。Fail2Ban 仍然会捕获并禁止找到您端口的 IP — 只需记住在监狱中将 port = ssh 更新为您的新端口,否则 Fail2Ban 将监控错误的端口。
被禁止的 IP 是否自动解除禁止还是我手动操作?
一旦配置的 bantime 过期,它们会自动解除禁止 — 例如,7200 秒禁止该 IP 2 小时,然后释放它。您可以使用 fail2ban-client set [jail] unbanip [IP] 提早解除禁止,设置 bantime = -1 会创建永久禁止,直到您手动删除它为止。