SSH 一直被暴力破解怎么办?fail2ban 加密钥登录加固实操 核心要点图解,SSH 爆破应先看日志确认规模,再上 fail2ban 自动封禁,最后关闭密码登录。;fail2ban 默认 sshd 规则即可用,重点是把 maxretry 和 bantime 调到合适值。;密钥登录要先用 ssh-copy-id 验证成功,再改 PasswordAuthentication no。;改 sshd_config 前先备份并保留一个已登录会话,用 sshd -t 校验后再 reload。
SSH 一直被暴力破解怎么办?fail2ban 加密钥登录加固实操 · 核心要点一图读懂(AegisX)

核心要点(TL;DR)

  • SSH 爆破应先看日志确认规模,再上 fail2ban 自动封禁,最后关闭密码登录。
  • fail2ban 默认 sshd 规则即可用,重点是把 maxretry 和 bantime 调到合适值。
  • 密钥登录要先用 ssh-copy-id 验证成功,再改 PasswordAuthentication no。
  • 改 sshd_config 前先备份并保留一个已登录会话,用 sshd -t 校验后再 reload。

凌晨三点,auth.log 里刷出上千条 Failed password for root,CPU 和带宽被扫描流量白白吃掉——这是几乎所有公网服务器的日常。SSH 暴力破解不会因为你改了端口就消失,真正有效的是自动封禁 + 密钥登录 + 配置收紧三件套。本文按「先看清、再止血、后加固」的顺序给出可直接复制的命令,照着做一遍,半小时内就能把爆破噪音压下去。

一、先确认:你的 SSH 到底被打了多狠

动手之前先取证,避免盲目改配置。以 Debian/Ubuntu 为例:

# 统计失败登录来源 IP 前 10
sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head

# 统计失败总次数与尝试的用户名
sudo grep -c "Failed password" /var/log/auth.log
sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-5)}' | sort | uniq -c | sort -rn | head

CentOS/RHEL 系日志在 /var/log/secure。若日志已被 logrotate 切走,用 zgrep 查归档文件。判断标准很简单:一天内失败次数上千、来源 IP 分散、用户名集中在 root/admin/test,基本就是自动化字典爆破。

同时看一眼当前连接:

ss -tnp state established '( sport = :22 )' | wc -l
lastb | head -20

lastb 能直接列出失败登录记录,是最快的体感指标。

二、止血:fail2ban 安装与 sshd jail 配置

fail2ban 的原理是持续读取认证日志,匹配失败模式后调用防火墙封禁来源 IP。安装:

# Debian/Ubuntu
sudo apt update && sudo apt install -y fail2ban
# CentOS/RHEL(需 EPEL)
sudo yum install -y epel-release && sudo yum install -y fail2ban

不要直接改 jail.conf,新建 /etc/fail2ban/jail.local 覆盖:

[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1 你的办公公网IP
backend  = systemd

[sshd]
enabled  = true
port     = ssh
logpath  = %(sshd_log)s
maxretry = 5
bantime  = 1d

三个参数的含义与建议值:findtime 是统计窗口,maxretry 是窗口内允许的失败次数,bantime 是封禁时长。公网机器建议 maxretry=3~5、bantime 先设 1 天观察误封,稳定后再拉长。

启动并验证:

sudo systemctl enable --now fail2ban
sudo fail2ban-client status
sudo fail2ban-client status sshd

输出里能看到 Currently banned 与 Total banned。若 Total failed 一直为 0,多半是 backend 或 logpath 不匹配,用 fail2ban-client -d 排查。注意 fail2ban 依赖防火墙后端,确认 banaction 对应的 iptables/nftables/firewalld 处于运行状态,否则规则加了也不生效。手动解封用 fail2ban-client set sshd unbanip 1.2.3.4。

三、根治:切换到 SSH 密钥登录

封禁只是减少噪音,关闭密码认证才是断根。本地生成密钥(已有可跳过):

ssh-keygen -t ed25519 -C "ops@example" -f ~/.ssh/id_ed25519

上传公钥并验证:

ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
ssh -i ~/.ssh/id_ed25519 user@server   # 能免密登录再往下走

确认服务端权限正确,否则 sshd 会静默拒绝密钥:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R $USER:$USER ~/.ssh

关键顺序:必须先验证密钥登录成功,再关闭密码认证,否则可能把自己锁死。切换前保留一个已登录的 SSH 会话不要断开,作为救生通道。

四、收紧 sshd_config 的六个必改项

编辑 /etc/ssh/sshd_config(部分发行版在 sshd_config.d/ 下有覆盖文件,注意优先级):

配置项建议值作用
PasswordAuthenticationno关闭密码登录,断根
PermitRootLoginprohibit-password禁止 root 密码登录
PubkeyAuthenticationyes启用密钥认证
MaxAuthTries3限制单连接认证次数
LoginGraceTime30缩短未认证连接占用
AllowUsers指定账号白名单收敛入口

改完先校验语法,再平滑重载:

sudo sshd -t
sudo systemctl reload sshd   # Debian/Ubuntu 为 ssh

新开一个终端测试登录,确认无误后再关闭旧会话。若同时开着防火墙,记得放行新端口(如改过 Port),并同步更新 fail2ban 的 port 配置,否则封禁规则会失效。

五、加固后的检查清单

  • fail2ban 服务已 enable,status sshd 中 Total failed 持续增长;
  • 密钥登录验证成功,密码登录返回 Permission denied (publickey);
  • sshd -t 无报错,reload 后旧会话仍在线;
  • root 无法用密码登录,普通账号可用 sudo 提权;
  • fail2ban 的 ignoreip 已包含自己的固定出口 IP;
  • 日志留存与告警可用,能定期回看封禁趋势。

在主机层之外,还可以叠加网络层的防护:例如 AegisX 的 WAF 与访问控制能力可在流量入口做来源信誉与异常连接拦截,与主机侧的 fail2ban、密钥认证形成分层防御,减少到达 22 端口的恶意流量。

行动建议

今天就做三件事:先跑一遍日志统计确认爆破规模,再装 fail2ban 并写好 jail.local,最后完成密钥登录切换并关闭密码认证。改配置前备份 sshd_config、保留一个在线会话,是所有操作的安全底线。加固不是一次性动作,建议每月回看一次封禁统计与登录审计,发现异常来源及时调整策略。

常见问题(FAQ)

fail2ban 会不会把我自己锁在外面?

有可能,但可以规避。fail2ban 按失败次数封禁来源 IP,如果你自己也输错多次密码,同样会被封。建议先把本机公网 IP 加入 ignoreip,或提前配置好密钥登录,避免依赖密码;同时确认防火墙放行规则与 fail2ban 的 banaction 一致,防止误封后无法从其他途径登录。

已经配置了密钥登录,还需要 fail2ban 吗?

需要。关闭密码登录后,爆破者仍会不断尝试连接并消耗连接资源,日志也会被大量填充。fail2ban 能在连接层直接丢弃恶意来源 IP,减少噪音和资源消耗,同时为其他可能开放的密码类服务提供兜底,两者是互补关系而非替代关系。

fail2ban 封禁的 IP 会永久生效吗?

默认不会。bantime 决定封禁时长,到期后自动解封;设为 -1 才是永久封禁。生产环境建议先用较长但有限的时长(如 1 天到 1 周),观察误封情况,再决定是否加长。也可以用 fail2ban-client status sshd 查看当前封禁列表,用 unban 命令手动解封。

修改 sshd_config 后需要重启 SSH 服务吗?

不需要重启,reload 即可。执行 sshd -t 先做语法校验,通过后 systemctl reload sshd(Debian/Ubuntu 为 ssh)让新配置生效,这样不会中断已有连接。切勿直接 restart,一旦配置有误可能导致新连接全部失败,把自己关在门外。

怎么确认暴力破解真的被挡住了?

看三个地方:fail2ban-client status sshd 的当前封禁数与总封禁数是否增长;auth.log 中 Failed password 记录是否明显下降;ss 或 netstat 观察 22 端口连接数是否回落。持续观察一到两天,若失败记录仍大量出现,检查 jail 是否启用、日志路径是否匹配、防火墙后端是否生效。