Install Fail2Ban to Block SSH Brute Force Attacks on Ubuntu VPS

任何具有公共 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 编写的入侵防御框架。它分三个阶段运作:

  1. 监控: 实时读取日志文件,例如 /var/log/auth.log。
  2. 检测: 将行与过滤器模式匹配(例如,"Failed password for root from 1.2.3.4")。
  3. 行动: 添加 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 使用两个关键配置文件:

最佳做法: 始终仅编辑 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 paths

Apache 监狱

如果您的 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 day

WordPress 监狱(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 暴力攻击的顾虑。

设置检查清单

  1. 安装 Fail2Ban 并启用自动启动。
  2. 创建 /etc/fail2ban/jail.local — 永远不要编辑 jail.conf。
  3. 使用正确的端口号配置 [sshd] 监狱。
  4. 将您自己的 IP 添加到 ignoreip 以避免锁定自己。
  5. 使用 fail2ban-client status sshd 进行验证。
  6. 可选地为持久攻击者启用 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 会创建永久禁止,直到您手动删除它为止。

具有完全根访问权的 VPS 以获得最大安全控制

自己配置每个安全设置。Linux VPS 起价 500 泰铢/月 — 泰国或新加坡。

查看 VPS 计划

查看泰国VPS主机全部套餐 →