
核心要点(TL;DR)
- SSH 防爆破的核心是禁用密码登录,改密钥认证后爆破基本失效。
- fail2ban 通过扫描 auth 日志自动封禁高频失败 IP,需先确认日志路径。
- 改端口只能减少噪音,不能替代密钥登录与封禁策略。
- 改 sshd 前先备份并保留一个已登录会话,避免把自己锁在门外。
为什么你的 SSH 日志里全是失败登录
如果你在 /var/log/auth.log 或 /var/log/secure 里看到成片的 Failed password for root,说明服务器已被自动化爆破盯上。这类扫描全天候运行,靠字典轮询常见用户名和弱口令。本文按「先止血、再加固、后验证」的顺序,给出可直接复制执行的命令,帮你把 SSH 暴力破解风险压到最低。
第一步:确认爆破规模与来源
先判断是零星误试还是持续爆破,再决定处置力度。
# Debian/Ubuntu
sudo grep 'Failed password' /var/log/auth.log | tail -20
# CentOS/RHEL
sudo grep 'Failed password' /var/log/secure | tail -20
# 统计失败次数最多的来源 IP
sudo grep 'Failed password' /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head
# 查看失败登录用户
sudo lastb | head -20若同一 IP 在几分钟内出现几十次失败,或来源 IP 分散且用户名集中在 root、admin、test,即可判定为自动化爆破。此时不要急着改配置,先记录当前 SSH 端口与已登录会话,后续操作全程保留一个活动连接作为回滚通道。
第二步:改用密钥登录并禁用密码认证
这是收益最大的一步。密钥认证下,爆破字典完全失效。
- 本地生成密钥(已有可跳过):
ssh-keygen -t ed25519 -C "ops@example"。 - 上传公钥:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server。 - 验证免密登录成功后再改服务端配置。
- 编辑
/etc/ssh/sshd_config,设置:
PubkeyAuthentication yes
PasswordAuthentication no
PermitRootLogin prohibit-password
ChallengeResponseAuthentication no
UsePAM yes保存后先做语法检查再重载,避免配置错误导致 sshd 起不来:
sudo sshd -t && sudo systemctl reload sshd务必保留当前已登录会话不要断开,另开一个终端测试新连接。确认密钥登录正常后,再关闭旧会话。
第三步:用 fail2ban 自动封禁高频失败 IP
禁用密码登录后爆破虽已无效,但日志仍会被刷屏。fail2ban 可自动封禁反复失败的 IP,减少噪音与资源消耗。
sudo apt install fail2ban # Debian/Ubuntu
sudo yum install fail2ban # CentOS/RHEL
sudo systemctl enable --now fail2ban新建 /etc/fail2ban/jail.local,不要直接改 jail.conf:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 你的办公IP
[sshd]
enabled = true
port = ssh
logpath = /var/log/auth.log
backend = systemdCentOS 需把 logpath 改为 /var/log/secure;使用 systemd 日志的系统可保留 backend = systemd。重载并验证:
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd输出中能看到当前封禁列表与失败计数。若误封自己,执行 sudo fail2ban-client set sshd unbanip 你的IP 解封。
第四步:端口调整与防火墙收敛
改端口能减少无效扫描,但只是辅助手段,不能替代密钥登录。修改 sshd_config 中的 Port 2222 后重载,并同步放行新端口:
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
# 或 ufw
sudo ufw allow 2222/tcp更稳妥的做法是配置来源白名单,只允许固定出口 IP 访问 SSH。下表对比三种措施的实际效果:
| 措施 | 阻断爆破 | 降低日志噪音 | 操作风险 |
|---|---|---|---|
| 密钥登录+禁密码 | 强 | 中 | 中(需先验证密钥) |
| fail2ban 封禁 | 中 | 强 | 低 |
| 改端口/白名单 | 弱到中 | 强 | 低 |
在主机层防护之外,可在边界设备或云安全组启用入侵检测与异常登录告警能力,例如 AegisX 提供的暴力破解识别与源 IP 阻断策略,可与主机侧 fail2ban 形成互补,减少漏封与误封。
第五步:验证与回滚清单
- 新开终端用密钥登录成功,密码登录被拒绝。
sudo sshd -t无报错,systemctl status sshd为 active。fail2ban-client status sshd显示 jail 已启用且有封禁记录。- 防火墙放行新端口,旧端口已关闭或限制来源。
- 保留一个 sudo 备用账号与一个活动会话,确认无误后再清理。
行动建议
按「密钥登录 → 禁用密码 → fail2ban → 端口与白名单」的顺序推进,每步验证后再进入下一步。改配置前备份 sshd_config,并始终保留一个已登录会话作为回滚通道。完成后再观察一天日志,确认失败记录显著下降,即说明防护已生效。
常见问题(FAQ)
改了 SSH 端口后 fail2ban 还需要配置吗?
需要。改端口只是减少扫描噪音,攻击者仍可通过全端口扫描找到新端口并发起爆破。fail2ban 依然要监听 sshd 日志并封禁失败次数过多的 IP。建议改端口与 fail2ban 同时启用,并把防火墙默认策略设为拒绝,只放行必要端口,形成多层防护。
禁用密码登录后,原来的普通用户还能登录吗?
可以,但前提是该用户已配置公钥。禁用密码登录只影响认证方式,不影响账号本身。操作前先给每个需要登录的账号在 ~/.ssh/authorized_keys 写入公钥并验证成功,再设置 PasswordAuthentication no。建议保留一个 sudo 用户做备用通道,验证无误后再关闭其他账号的密码登录。
fail2ban 封禁后会不会误封自己?
有可能,尤其是多次输错密码或使用自动化脚本时。建议把常用办公 IP 加入 ignoreip 白名单,并在正式启用前用 fail2ban-client status sshd 观察封禁记录。若被误封,可在控制台通过 fail2ban-client set sshd unbanip 你的IP 解封,或直接调整 maxretry 与 findtime 参数放宽阈值。
怎么确认 SSH 正在被暴力破解?
查看认证日志中的失败记录即可判断。Debian/Ubuntu 用 grep 'Failed password' /var/log/auth.log,CentOS/RHEL 用 grep 'Failed password' /var/log/secure。若短时间内出现大量来自不同 IP 的失败登录,且用户名多为 root、admin 等常见名,基本可判定为自动化爆破。配合 lastb 命令还能看到失败登录统计。
只改端口不改密钥登录够安全吗?
不够。改端口属于隐蔽性措施,攻击者用端口扫描可在几分钟内发现新端口,随后继续爆破。真正的防线是禁用密码登录改用密钥认证,再叠加 fail2ban 封禁与防火墙白名单。只改端口而不做认证加固,等于把门牌换了但锁没换,风险依然存在。