SSH 被暴力破解怎么办:fail2ban 与密钥登录加固实战 核心要点图解,SSH 暴力破解无法根除,只能通过密钥登录+禁用密码认证从源头消除风险。;fail2ban 读取 auth.log 自动封禁多次失败的 IP,是低成本高收益的第一道防线。;禁用密码登录前必须先验证密钥可登录,否则容易把自己锁在服务器外。;配合 PermitRootLogin no、改端口、限来源 IP,可进一步压缩攻击面。
SSH 被暴力破解怎么办:fail2ban 与密钥登录加固实战 · 核心要点一图读懂(AegisX)

核心要点(TL;DR)

  • SSH 暴力破解无法根除,只能通过密钥登录+禁用密码认证从源头消除风险。
  • fail2ban 读取 auth.log 自动封禁多次失败的 IP,是低成本高收益的第一道防线。
  • 禁用密码登录前必须先验证密钥可登录,否则容易把自己锁在服务器外。
  • 配合 PermitRootLogin no、改端口、限来源 IP,可进一步压缩攻击面。

打开 /var/log/auth.log,满屏的 Failed password for root 是不是让你心里一紧?SSH 一旦暴露在公网,暴力破解就是常态,区别只在于你的服务器是被当成背景噪音,还是已经被攻破。本文面向需要立刻动手的运维和站长,用 fail2ban 加 SSH 密钥登录两条主线,把爆破风险压到最低,所有步骤都可直接复制执行。

一、先确认:你的 SSH 正在被怎么打

动手前先摸清攻击规模,避免盲目加固。执行以下命令统计失败来源:

sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20
sudo grep "Failed password" /var/log/auth.log | wc -l
grep "Accepted" /var/log/auth.log | tail -20

重点关注三件事:失败次数是否持续增长、是否有陌生 IP 成功登录(Accepted 记录)、被尝试的用户名是否包含 root、admin、test 等常见弱口令账户。若出现成功登录记录而你不认识来源 IP,应视为已被入侵,先隔离取证再谈加固。

二、第一道防线:fail2ban 自动封禁爆破 IP

fail2ban 的原理很直接:持续读取认证日志,匹配失败模式,超过阈值就调用防火墙封禁来源 IP。安装与最小配置如下(Debian/Ubuntu):

sudo apt update && sudo apt install -y fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo tee /etc/fail2ban/jail.d/sshd.local <<'EOF'
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 4
findtime = 10m
bantime = 1h
ignoreip = 127.0.0.1/8 你的办公出口IP
EOF
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

参数含义:maxretry 为窗口内允许失败次数,findtime 为统计窗口,bantime 为封禁时长。生产环境建议 bantime 不低于 1 小时,并开启 dbpurgeage 持久化,避免重启后封禁记录清零。用 fail2ban-client set sshd unbanip x.x.x.x 可手动解封误伤 IP。

三、根本解法:SSH 密钥登录并禁用密码认证

fail2ban 只是抬高攻击成本,真正消除密码爆破面的是密钥认证。分四步走,每一步都要验证:

  1. 本地生成密钥:ssh-keygen -t ed25519 -C "ops@company",为私钥设置口令。
  2. 上传公钥:ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server,确认服务器 ~/.ssh/authorized_keys 权限为 600、目录为 700。
  3. 验证密钥登录:新开终端执行 ssh -i ~/.ssh/id_ed25519 user@server,能免密进入再继续。
  4. 关闭密码认证:编辑 /etc/ssh/sshd_config,设置 PasswordAuthentication no、PubkeyAuthentication yes,然后 sudo sshd -t 检查语法、sudo systemctl reload sshd 生效。
关键提醒:修改配置时保持当前 SSH 会话不退出,另开窗口测试新登录。一旦配置有误,旧会话就是你的救生艇。

四、顺手加固:sshd 关键参数与对比

在 sshd_config 中同步调整以下参数,进一步压缩攻击面:

参数建议值作用
PermitRootLoginno禁止 root 直接登录,改用普通用户加 sudo
MaxAuthTries3降低单连接认证尝试次数
LoginGraceTime30s缩短未认证连接占用时间
Port非 22 端口减少自动化扫描噪音
AllowUsers指定账户白名单化可登录用户

改端口后记得同步 fail2ban 的 port 字段与云安全组规则。若服务器有固定办公出口,建议在防火墙层直接限制 22 端口来源 IP,这比任何软件层防护都更彻底。

五、上线前检查清单

  • 已用新会话验证密钥登录成功,且旧会话仍保持;
  • sshd -t 语法检查通过,reload 而非 restart 减少断连风险;
  • fail2ban 状态为 active,fail2ban-client status sshd 能看到封禁计数;
  • 云安全组与主机防火墙规则一致,未误封运维出口 IP;
  • 已备份 sshd_config 与 jail.local,并记录回滚步骤。

在防护建议层面,如果不想逐台手工维护规则,可以借助 AegisX 这类平台对 SSH 登录失败、异常来源 IP 做统一告警与联动封禁,把 fail2ban 的单机能力扩展为可观测的集中防线。

行动建议

今天就做三件事:先用日志确认攻击现状,再部署 fail2ban 并调大 bantime,最后完成密钥登录验证后关闭密码认证。三步完成后,你的 SSH 日志会明显安静下来,服务器也从「随时可能被撞开」变成「需要密钥才能进」。加固不是一次性任务,建议每月复查一次 auth.log 与 fail2ban 封禁统计,及时发现新的攻击模式。

常见问题(FAQ)

fail2ban 封禁 IP 后为什么日志里还有大量失败记录?

因为 fail2ban 只封禁触发阈值的 IP,扫描器会不断更换源地址,日志中仍会持续出现新 IP 的失败尝试。这属于正常现象,说明防护在工作。要彻底减少记录量,应结合禁用密码登录、修改默认端口和防火墙白名单,让攻击者连认证环节都进不来。

配置 SSH 密钥登录后还能用密码登录吗?

可以,但取决于 sshd_config 中的 PasswordAuthentication 设置。密钥配置完成并验证通过前,建议保留密码登录作为退路;验证新会话能用密钥成功登录后,再改为 PasswordAuthentication no 并重启 sshd,才能真正关闭密码爆破入口。

禁用密码登录后把自己锁在外面怎么办?

优先通过云厂商控制台的 VNC 或救援模式登录,改回 PasswordAuthentication yes 后重启 sshd。预防办法是修改配置前保持一个已登录会话不退出,用 ssh -t 另开窗口测试新配置,确认无误再关闭旧会话,同时提前备份 sshd_config。

fail2ban 默认封禁多久,需要调整吗?

默认 bantime 为 10 分钟,对持续扫描的僵尸网络偏短。建议在 jail.local 中把 bantime 调到 1 小时以上甚至 1 天,findtime 设为 10 分钟、maxretry 设为 3 到 5 次,并开启 persistent 数据库,避免服务重启后封禁记录丢失。

修改 SSH 端口能代替 fail2ban 吗?

不能代替,只能减少扫描噪音。改端口可避开大部分自动化扫描,但定向攻击仍能发现新端口。正确做法是改端口、禁密码登录、fail2ban 三者叠加,形成从网络层到认证层的纵深防御,而不是依赖单一措施。