Fail2Ban 本来是用来防暴力破解的,但配置不小心,它也会把你自己挡在 VPS 外面。
最典型的场景是:你连续输错几次 SSH 密码,或者换了新网络出口,突然发现:
ssh: connect to host x.x.x.x port 22: Connection refused
Connection timed out
Permission denied
如果服务器没宕机,SSH 服务也没坏,那很可能是 Fail2Ban 把你的 IP 加进了 sshd jail 的封禁列表。
这篇讲的不是“怎么安装 Fail2Ban”,而是已经把自己封了以后怎么救回来,以及怎么防止下次再发生。
如果你还有一个没断开的 SSH 会话,或者能从另一个 IP 登录,先看:
sudo fail2ban-client status
再看 SSH jail:
sudo fail2ban-client status sshd
重点看:
Currently banned:当前封禁数量;Banned IP list:封禁 IP 列表;- 里面是否有你当前公网 IP。
查自己的公网 IP:
curl -4 ifconfig.me
如果列表里有你的 IP,就不是 SSH 服务坏了,而是被 Fail2Ban ban 了。
如果你还能通过另一个 IP、另一个用户、跳板机或保留会话进入 VPS,直接解封:
sudo fail2ban-client set sshd unbanip 你的IP
有些版本也支持从所有 jail 解封某个 IP:
sudo fail2ban-client unban 你的IP
如果你只是测试环境,想临时清空所有 ban:
sudo fail2ban-client unban --all
生产环境不要轻易 unban --all,因为它会把真正的攻击 IP 也放出来。
解封后重新测试:
ssh root@你的服务器IP
或者:
ssh 用户名@你的服务器IP
如果所有 SSH 都进不去,就需要带外登录:
- 云厂商网页控制台;
- VNC / noVNC;
- Serial Console;
- Rescue Mode;
- IPMI / KVM 控制台。
登录后先不要乱删规则,优先执行:
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 你的IP
如果 fail2ban-client 不可用,临时停掉服务:
sudo systemctl stop fail2ban
这只是临时自救。能 SSH 进去后,要马上修配置,否则 Fail2Ban 重启后可能再次把你封掉。
正确位置通常是:
sudo nano /etc/fail2ban/jail.local
在 [DEFAULT] 里加:
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 你的固定IP 你的VPN出口IP
如果你有公司/家里固定网段,也可以写 CIDR:
ignoreip = 127.0.0.1/8 ::1 203.0.113.10 198.51.100.0/24
保存后重载:
sudo fail2ban-client reload
或者:
sudo systemctl reload fail2ban
注意:ignoreip 只保护未来的封禁,不一定自动解除已经 ban 的 IP。已经被封的 IP 仍然要先 unbanip。
Fail2Ban 里常见文件:
/etc/fail2ban/jail.conf
/etc/fail2ban/jail.local
/etc/fail2ban/jail.d/*.local
/etc/fail2ban/fail2ban.conf
原则很简单:
jail.conf是默认配置,不建议编辑,升级可能覆盖;jail.local放本机覆盖配置;jail.d/*.local适合按服务拆分;fail2ban.conf是 Fail2Ban 自身配置,里面有数据库相关选项。
SSH 单独配置可以这样写:
[sshd]
enabled = true
port = ssh
maxretry = 3
findtime = 10m
bantime = 1h
如果你把 SSH 改到了非 22 端口,要同步改:
port = 2222
否则 Fail2Ban 可能监控和防火墙动作不符合你的实际 SSH 端口。
三个核心参数:
| 参数 | 含义 | 常见值 |
|---|---|---|
maxretry | 时间窗口内允许失败次数 | SSH 常用 3-5 |
findtime | 统计失败次数的时间窗口 | 10m |
bantime | 封禁多久 | 1h、24h |
如果你设置成:
maxretry = 1
findtime = 1h
bantime = 1w
那就很容易把自己封一周。
对个人 VPS,比较稳的起点:
[sshd]
enabled = true
maxretry = 5
findtime = 10m
bantime = 1h
如果确实攻击很多,再考虑累进封禁,而不是一开始就把 bantime 拉到几周。
有一种很坑的情况:你已经把自己加入 ignoreip,也解封了,但重启 Fail2Ban 或服务器后,又被封了。
原因可能是 Fail2Ban 的数据库里还保留着旧 ban 记录。
看配置:
sudo grep -n 'dbpurgeage\|dbfile' /etc/fail2ban/fail2ban.conf
dbpurgeage 控制数据库里记录保留多久。如果旧记录仍在,重启后可能恢复旧 ban。
排查思路:
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 你的IP
sudo systemctl reload fail2ban
如果仍反复出现,可以暂时停止 Fail2Ban,确认数据库和配置,再启动:
sudo systemctl stop fail2ban
sudo systemctl start fail2ban
不要在不了解影响的情况下随便删除数据库文件。生产环境里它也保存着真实攻击 IP 的记录。
Ubuntu 22.04/24.04、Debian 12 这类系统很多日志都在 journald 里。
可以在 [DEFAULT] 设置:
backend = systemd
然后重载:
sudo systemctl reload fail2ban
如果后端不匹配,可能出现两种问题:
- Fail2Ban 没读到 SSH 登录失败日志,完全不封;
- 自定义 jail 读错日志,把正常请求当成攻击。
改日志后端前,先看 Fail2Ban 日志:
sudo journalctl -u fail2ban -n 100 --no-pager
sudo tail -n 100 /var/log/fail2ban.log
不同发行版日志路径可能不一样,systemd 环境优先看 journalctl。
很多自锁不是 SSH,而是 Nginx、Traefik、Caddy、应用登录页的自定义 jail。
比如你调试后台登录,连续 401/403,被 Fail2Ban 识别成攻击:
sudo fail2ban-client status
sudo fail2ban-client status nginx-http-auth
sudo fail2ban-client status 自定义jail名
解封不是永远只看 sshd,要看具体 jail:
sudo fail2ban-client set nginx-http-auth unbanip 你的IP
如果你通过 Cloudflare、反向代理或负载均衡访问源站,还要确认应用拿到的是真实客户端 IP 还是代理 IP。否则 Fail2Ban 可能封错对象。
Cloudflare 回源问题可以看:VPS 网站出现 Cloudflare 521 / 522 怎么办。
启用 Fail2Ban 前,建议先做三件事:
- 确认云厂商控制台/VNC 能登录;
- 把固定 IP 或 VPN 出口加入
ignoreip; - 保留一个当前 SSH 会话,不要马上断开。
启用后测试:
sudo fail2ban-client status
sudo fail2ban-client status sshd
sudo journalctl -u fail2ban -n 50 --no-pager
不要在只有一个网络出口、没有控制台权限、没有白名单的情况下,把 maxretry 设得很低、bantime 设得很长。
如果你怀疑 Fail2Ban 把自己封了,按这个顺序:
- 换网络或用保留 SSH 会话登录 VPS。
fail2ban-client status看有哪些 jail。fail2ban-client status sshd看自己 IP 是否被 ban。fail2ban-client set sshd unbanip 你的IP解封。- 如果 SSH 完全进不去,用云厂商 VNC/控制台/救援模式。
- 在
/etc/fail2ban/jail.local的[DEFAULT]加ignoreip。 - 检查
maxretry/findtime/bantime是否过激。 - 检查是否有自定义 Nginx/Traefik jail 误封。
- 如重启后又封,检查
dbpurgeage和数据库持久化。 - 重载后保留一个 SSH 会话测试,不要立刻断开。
Fail2Ban 自锁不是小概率事件,尤其是在新 VPS、安全加固、SSH 改端口、反向代理调试时很常见。
救急时先用 fail2ban-client status 找 jail,再用 set sshd unbanip 解封;SSH 完全进不去就走云厂商控制台。长期修复要靠 ignoreip、合理的 maxretry/findtime/bantime、正确的 jail.local 和对数据库持久化的理解。Fail2Ban 是好工具,但前提是别让它先把你自己挡在门外。
