SSH 22 端口被暴力破解:排查与防护实战步骤 核心要点图解,先查 auth.log 与 lastb 确认是否已有成功登录,再谈封禁。;禁用密码登录改公钥认证,是阻断 SSH 爆破最有效的一步。;fail2ban 配合 nftables/iptables 可自动封禁高频失败 IP。;改默认端口只能减少噪音,不能替代密钥认证与限流。
SSH 22 端口被暴力破解:排查与防护实战步骤 · 核心要点一图读懂(AegisX)

核心要点(TL;DR)

  • 先查 auth.log 与 lastb 确认是否已有成功登录,再谈封禁。
  • 禁用密码登录改公钥认证,是阻断 SSH 爆破最有效的一步。
  • fail2ban 配合 nftables/iptables 可自动封禁高频失败 IP。
  • 改默认端口只能减少噪音,不能替代密钥认证与限流。

凌晨收到一堆 SSH 登录失败告警,auth.log 每分钟刷出上百条 Failed password for root——这是 22 端口暴露在公网后最常见的场景。本文按「先取证、再止血、后加固」的顺序给出可直接复制的命令与检查清单,帮你在一小时内把爆破压下去,并确认服务器没有被攻破。

一、先确认:是噪音还是已经出事

不要急着封 IP,先判断有没有成功登录的痕迹。爆破本身不可怕,可怕的是其中一次猜中了。

# 今日失败次数(systemd 系统)
sudo journalctl -u ssh --since today | grep -c 'Failed password'
# Debian/Ubuntu 传统日志
sudo grep -c 'Failed password' /var/log/auth.log
# 统计攻击源 TOP10
sudo grep 'Failed password' /var/log/auth.log \
  | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head
# 关键:查是否有成功登录
last -a | head -20
sudo grep 'Accepted' /var/log/auth.log | tail -20

同时检查 lastb(失败记录)、/root/.ssh/authorized_keys 是否被追加陌生公钥、crontab -l 与 /etc/cron.d/ 是否有可疑任务。只要出现来源不明的 Accepted publickey,就按入侵事件处理,先隔离再排查。

二、止血:自动封禁高频失败 IP

手工 iptables 封 IP 追不上扫描速度,用 fail2ban 做自动封禁。安装后写 /etc/fail2ban/jail.local:

[sshd]
enabled  = true
port     = ssh
filter   = sshd
backend  = systemd
maxretry = 5
findtime = 10m
bantime  = 1h
ignoreip = 127.0.0.1/8 你的办公IP

然后 sudo systemctl enable --now fail2ban,用 sudo fail2ban-client status sshd 查看当前封禁列表。若服务器用 nftables,把 banaction 设为 nftables-multiport,否则规则会写进不生效的 iptables 链。封禁只是止血,下面才是根治。

三、根治:关掉密码认证,只留公钥

绝大多数爆破成功案例都源于弱口令。正确顺序是:先配密钥并验证,再关密码。

  1. 本地生成密钥:ssh-keygen -t ed25519 -C "ops@host"。
  2. 上传公钥:ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server。
  3. 新开终端验证 ssh -i ~/.ssh/id_ed25519 user@server 能免密登录。
  4. 编辑 /etc/ssh/sshd_config:PasswordAuthentication no、PubkeyAuthentication yes、PermitRootLogin no、MaxAuthTries 3、LoginGraceTime 20。
  5. sudo sshd -t 校验语法,再 sudo systemctl reload ssh。保留一个已登录会话,防止配置失误锁死。

权限同样关键:chmod 700 ~/.ssh、chmod 600 ~/.ssh/authorized_keys,属主必须是目标用户,否则 sshd 会拒绝密钥。

四、收敛攻击面:端口、来源与限流

改端口只能减少扫描噪音,不能替代认证加固,但配合来源限制收益明显。在 sshd_config 中设 Port 2222,并在防火墙只放行可信网段:

sudo nft add rule inet filter input tcp dport 2222 \
  ip saddr != 203.0.113.0/24 drop

也可用 AllowUsers deploy ops 做账号白名单。若必须保留 22 端口给外部,至少在云安全组层面限制来源 IP。改端口后记得同步 fail2ban 的 port 字段与监控告警。

五、验证与检查清单

检查项命令/位置期望结果
失败频率下降journalctl -u ssh --since -10m | grep -c Failed接近 0
密码登录已关闭sshd -T | grep passwordauthno
root 禁止登录sshd -T | grep permitrootloginno
fail2ban 生效fail2ban-client status sshd有 Banned IP 列表
无异常公钥cat ~/.ssh/authorized_keys仅自己维护的密钥

防护建议:在完成上述配置后,可把登录失败告警、异常 IP 封禁与基线核查接入 AegisX 的持续监测能力,让爆破趋势与配置漂移在一个面板里可见,避免下次靠翻日志才发现问题。

六、行动建议

今天先做三件事:统计失败次数确认是否被爆破、检查 last 有无异常成功登录、部署 fail2ban 并设 bantime 至少 1 小时。本周内完成密钥登录切换与 PasswordAuthentication no,并把 22 端口的来源限制写进安全组。爆破不会停,但你可以让它永远猜不中。

常见问题(FAQ)

怎么快速判断 SSH 是不是正在被暴力破解?

看失败登录频率即可确认。执行 sudo journalctl -u ssh --since today | grep -c 'Failed password',数字上千基本就是被爆破;也可用 lastb | head 查看失败记录,或 grep 'Failed password' /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head 统计攻击源 IP。

只把 SSH 端口从 22 改成别的就安全了吗?

不够。改端口只是减少自动化扫描噪音,针对性扫描仍能发现新端口。真正有效的是禁用密码登录、仅允许公钥认证,并配合 fail2ban 或防火墙限流。建议顺序为:先配好密钥并验证可登录,再改 Port、设 PasswordAuthentication no,最后重启 sshd 并保留一个已登录会话做回滚。

fail2ban 封禁后为什么攻击日志还在涨?

多半是 jail 未真正匹配到日志或后端防火墙未生效。用 fail2ban-client status sshd 查看当前封禁数与日志路径,确认 /etc/fail2ban/jail.local 中 logpath 与实际日志一致(systemd 系统用 backend=systemd),再 fail2ban-client reload。若用 nftables,需确认 banaction 指向 nftables 而非默认 iptables。

禁用密码登录后自己登不上了怎么办?

先别断开现有会话。SSH 配置错误时,已建立的连接仍可用,可在其中修复 authorized_keys 权限(700 目录、600 文件)与属主,然后 sshd -t 校验配置再 systemctl reload ssh。云主机可借助控制台 VNC 登录救援。上线前务必用新终端实测密钥登录成功,再关闭密码认证。

还有哪些低成本加固手段值得一起做?

限制来源与权限最划算:防火墙只放行可信 IP 段访问 22 端口,sshd_config 设 PermitRootLogin no、MaxAuthTries 3、LoginGraceTime 20,并启用 AllowUsers 白名单。再叠加 fail2ban 的 recidive 规则封禁惯犯 IP,配合系统更新与登录告警邮件,形成持续防护。