
核心要点(TL;DR)
- SSH 被爆破的根治方案是密钥登录 + 禁用密码认证,fail2ban 只是降低噪声的辅助层。
- 先确认 sshd 配置与日志路径,再改配置,改完必须保留一个已登录会话做回滚验证。
- fail2ban 用 jail.local 覆盖默认配置,务必把本机与办公 IP 加入 ignoreip。
- 加固后复查 sshd -T 输出与日志,确认密码认证确实关闭、封禁记录正常产生。
凌晨收到告警,登录服务器一看 /var/log/auth.log 里刷满了 Failed password for root,来源 IP 遍布各地——这是几乎所有公网 Linux 主机都会遇到的场景。SSH 暴力破解本身不可怕,可怕的是它长期消耗资源、污染日志,并在你疏忽时成为入侵入口。本文给出一套可直接照做的加固流程:先上密钥登录关掉密码认证,再用 fail2ban 压制扫描噪声,最后用检查清单确认没有留下回滚陷阱。
一、先判断:你的 SSH 到底暴露到什么程度
动手前先摸清现状,避免改完配置才发现连不上。执行以下命令确认监听端口、认证方式与爆破规模:
ss -tlnp | grep sshd
sshd -T | grep -Ei 'passwordauth|permitroot|port|pubkey'
grep -c 'Failed password' /var/log/auth.log
journalctl -u ssh --since today | grep -c 'Failed password'如果 passwordauthentication yes 且端口为 22,说明攻击面最大。统计失败次数可以判断是否已被持续针对。注意不同发行版日志路径不同:Debian/Ubuntu 用 /var/log/auth.log,CentOS/RHEL 多用 /var/log/secure 或 journald。
二、第一步:配置 SSH 密钥登录并禁用密码
密钥登录是根治手段,fail2ban 只是辅助。先在本地生成密钥并上传公钥:
ssh-keygen -t ed25519 -C "ops@example"
ssh-copy-id -i ~/.ssh/id_ed25519.pub ops@your-server服务端确认权限正确,否则 sshd 会静默拒绝密钥:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R ops:ops ~/.ssh用 ssh -i ~/.ssh/id_ed25519 ops@your-server 验证能免密登录后,再编辑 /etc/ssh/sshd_config.d/99-hardening.conf(或主配置):
PubkeyAuthentication yes
PasswordAuthentication no
PermitRootLogin prohibit-password
MaxAuthTries 3
LoginGraceTime 20
ClientAliveInterval 300
ClientAliveCountMax 2执行 sshd -t 校验语法,再 systemctl reload sshd。务必保留一个已登录会话不关闭,另开窗口测试新连接,失败可立即回滚。
三、第二步:用 fail2ban 自动封禁爆破源
安装后不要直接改 jail.conf,新建 /etc/fail2ban/jail.local 覆盖默认值:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s启动并验证:
systemctl enable --now fail2ban
fail2ban-client status sshd
fail2ban-client set sshd unbanip 198.51.100.7若使用 firewalld,确认 banaction 为 firewallcmd-rich-rules;使用 nftables 则选对应动作。封禁是否生效,用 fail2ban-client status sshd 的 Banned IP list 与防火墙规则双向核对。
| 措施 | 作用 | 是否必需 |
|---|---|---|
| 密钥登录 + 禁密码 | 消除密码猜解面 | 必需 |
| 禁用 root 直接登录 | 降低高权限账号风险 | 必需 |
| fail2ban | 压制扫描与探测噪声 | 强烈建议 |
| 改默认端口 | 减少自动化扫描命中 | 可选 |
四、第三步:上线后的检查清单
sshd -T | grep -E 'passwordauthentication|permitrootlogin'输出应为 no 与 prohibit-password。- 用另一台机器尝试密码登录,应被拒绝且日志有记录。
fail2ban-client status sshd能看到封禁计数增长。- 确认
ignoreip已包含跳板机与监控探针出口 IP。 - 重启一次 sshd,验证配置在重启后依然生效。
常见坑:只改主配置却被 sshd_config.d/ 下的文件覆盖;authorized_keys 权限过宽导致密钥失效;fail2ban 后端选错读不到日志。五、行动建议:把防护做成常态
完成上述步骤后,SSH 爆破基本只剩日志噪声。建议每月复查一次 fail2ban 封禁统计与 sshd 配置,新机器上线即套用同一份加固模板。若需要统一管理多台主机的登录策略与异常登录告警,可结合 AegisX 的主机安全能力做集中审计,减少逐台手工核对的成本。今晚就从一个已登录会话开始,先把密码认证关掉。
常见问题(FAQ)
我已经用了强密码,还需要改成密钥登录吗?
建议改。强密码能提高单次猜解成本,但 SSH 暴露在公网时每天会承受大量尝试,密码认证本身仍是可被持续攻击的入口。密钥登录把认证凭据换成私钥,服务端不存储可被猜解的密码,配合禁用密码认证可直接消除爆破面。改完后 fail2ban 仍建议保留,用于拦截扫描与探测行为。
fail2ban 会不会把我自己锁在服务器外面?
有可能,但可以规避。关键是把公司出口 IP、跳板机与自己的固定 IP 写入 ignoreip,并在修改 jail 配置前保持一个已登录的 SSH 会话不关闭。同时确认防火墙后端与 fail2ban 动作匹配(如 firewalld 或 iptables),先在测试机验证封禁与解封命令,再上生产。云主机还需注意安全组与系统防火墙不要重复拦截。
禁用密码登录后,新电脑上没有私钥怎么办?
提前准备再禁用。先把公钥追加到目标用户的 ~/.ssh/authorized_keys,权限设为 700 目录、600 文件,并用 ssh -i 私钥 测试登录成功。确认无误后再改 sshd 配置禁用密码。日常可把私钥放在加密介质或使用 ssh-agent,多台机器建议各自生成密钥对,避免一把私钥到处复制。
fail2ban 封禁了正常用户或监控探针怎么办?
先加白名单再调阈值。用 fail2ban-client status sshd 查看当前封禁列表,确认被误封的 IP 后用 fail2ban-client set sshd unbanip 解封,并把该 IP 段写入 ignoreip。监控探针、负载均衡健康检查地址应固定出口 IP 并加入白名单,避免周期性探测触发 maxretry。
怎么确认 SSH 加固真的生效了?
用配置输出和日志双重验证。执行 sshd -T 检查 passwordauthentication 是否为 no、permitrootlogin 是否为 prohibit-password;再用另一台机器尝试密码登录,应被拒绝。同时观察 /var/log/auth.log 或 journalctl -u ssh,确认失败尝试仍被记录且 fail2ban 有封禁动作,最后重启一次 sshd 验证配置持久有效。