Fail2ban 误封导致 SSH 连接被立即关闭
SSH 报 kex_exchange_identification: Connection closed by remote host 时,多为 fail2ban 封了客户端 IP;给出诊断、救急与放宽策略。
[!warning] 先确认不是真被攻击 同样的「连接被立即关闭」也可能是 sshd 崩溃或防火墙 RST。先用
fail2ban-client status sshd看到自己的 IP 在封禁列表里,才能确定是误封。
Fail2ban 误封导致 SSH 连接被立即关闭
现象
本地 ssh -vvv 显示 TCP 握手成功,但在协议 banner 交换前被断开:
debug1: Connection established.
debug1: Local version string SSH-2.0-OpenSSH_for_Windows_9.5
kex_exchange_identification: Connection closed by remote host
Connection closed by 129.225.x.x port 22
特征:端口能通(不是超时),但 SSH 协议层还没开始就被踢。密钥、密码都还没验证,所以不是认证问题。
快速判断
在能登录的通道(带外控制台、已建立的旧会话、Tailscale)里执行:
sudo fail2ban-client status sshd
sudo fail2ban-client get sshd banned
若 Currently banned 大于 0 且列表里有你的公网 IP(curl ifconfig.me 查),即为误封。
根因
fail2ban 默认策略约为 findtime=600(10 分钟)内 maxretry=5(5 次失败)即 bantime=3600(封 1 小时)。多个 ssh -N -L 隧道并发、频繁重连或脚本反复尝试,会在短时间内堆高失败计数,触发封禁。封禁有到期时间,到期后自动恢复——这正是「过一会儿又能连上」的原因。
救急
封禁默认不持久化,重启即清:
# 在带外通道执行
sudo systemctl restart fail2ban # 清空内存封禁
# 或直接重启实例(OCI)
oci compute instance action --instance-id <OCID> --action SOFTRESET
也可只解封单个 IP:
sudo fail2ban-client set sshd unbanip <你的公网IP>
预防:放宽 + 白名单 + 累犯加重
# /etc/fail2ban/jail.d/sshd.local
[sshd]
enabled = true
maxretry = 20
findtime = 300
bantime = 600
# /etc/fail2ban/jail.d/recidive.local
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
bantime = 604800 # 7 天
findtime = 86400
maxretry = 5
白名单写在 [DEFAULT] 的 ignoreip:
[DEFAULT]
ignoreip = 127.0.x.x/8 ::1 <你的公网IP>/32
动态公网 IP 会变化,因此放宽全局策略比依赖白名单更稳;白名单只作为当前 IP 的额外保险。
陷阱:jail.d 优先级高于 jail.local
fail2ban 加载顺序为 jail.conf → jail.local → jail.d/*,后者覆盖前者。把配置写在 jail.local 里可能不生效,因为 jail.d/*.conf(含发行版自带的 defaults-debian.conf、sshd.local)会覆盖同名 section。改配置要改 jail.d/ 下的文件,改完 systemctl restart fail2ban 并用 fail2ban-client get sshd maxretry 复核。
回归验证
sudo fail2ban-client status sshd
sudo fail2ban-client get sshd ignoreip
sudo fail2ban-client get sshd maxretry
确认 ignoreip 含你的 IP、maxretry 为放宽后的值,再从本地新建 SSH 会话验证可连。
Related notes
- 所属 MOC:甲骨文云服务器 MOC
- 连通性排查:OCI SSH 与端口连通性排查
- 加固主流程:安全加固 OCI Linux 服务器
- 救急通道:使用控制台连接恢复 OCI 实例