密码喷洒是一种用少量常见密码尝试大量用户名的低频广域暴力攻击,旨在规避单账户锁定机制;其核心特征是“一密多用、多户并发”,需通过限制登录用户范围、增强fail2ban规则、强制密钥认证、速率控制及日志审计进行多层防御。

密码喷洒(Password Spraying)是一种低频、广域的暴力攻击变种:攻击者用少量常见密码(如 Password123、admin123、Qwerty123)尝试大量用户名,规避传统“单IP多次失败即封禁”的防护逻辑。它不像传统爆破那样集中攻击一个账号,而是分散试探多个账户,更难被 fail2ban 等基于失败次数的工具捕获。
要有效防御密码喷洒,不能只靠“改端口”或“禁密码”,而需构建多层识别 + 主动阻断 + 认证降噪的组合策略:
限制可登录的用户范围
攻击者常利用枚举出的有效用户名(如通过邮箱前缀、LDAP泄露、或默认账户名 admin/test/deploy)发起喷洒。若服务器上存在大量闲置或测试账户,等于主动提供靶子。
- 在
/etc/ssh/sshd_config中明确指定允许登录的用户或组:AllowUsers deployer ops jenkins # 或 AllowGroups ssh-access
- 配合系统级清理:删除无用账户(
sudo userdel -r username),禁用 shell(sudo usermod -s /usr/sbin/nologin username)而非仅删密码。
启用并调优 fail2ban 的喷洒感知规则
默认 sshd jail 只统计单 IP 的失败次数,对跨 IP 喷洒无效。需启用 sshd-ddos 或自定义 jail,监控全局用户名命中率:
- 编辑
/etc/fail2ban/jail.local,添加:[sshd-spray] enabled = true filter = sshd-spray logpath = /var/log/auth.log maxretry = 5 findtime = 600 # 10分钟内 bantime = 1h chain = INPUT
- 创建
/etc/fail2ban/filter.d/sshd-spray.conf,匹配“同一密码被多个用户尝试”的日志模式(例如Failed password for .* from+ 密码字段聚合分析),或使用社区成熟规则(如fail2ban-regex配合自定义正则提取高频密码)。
强制密钥认证 + 禁用密码登录(根本性切断)
密码喷洒的前提是密码认证开启。只要 PasswordAuthentication yes 存在,无论密码多强,都可能成为喷洒目标。
- 在
/etc/ssh/sshd_config中确保:PasswordAuthentication no ChallengeResponseAuthentication no PubkeyAuthentication yes
-
关键细节:修改后必须
sudo systemctl restart sshd,且提前验证密钥能正常登录(建议保留一个本地控制台会话备用); - 私钥权限必须严格(
chmod 600 ~/.ssh/id_ed25519),服务端~/.ssh/authorized_keys权限应为644,目录为700,否则 sshd 拒绝加载。
启用登录速率限制与连接数控制
OpenSSH 自带 MaxStartups 和 LoginGraceTime 参数,可抑制并发喷洒连接:
- 在
/etc/ssh/sshd_config中添加:MaxStartups 3:30:5 # 最多3个未认证连接,超限后按30%概率丢弃,上限5个 LoginGraceTime 30 # 登录窗口仅30秒,超时断连,压缩攻击窗口
- 配合防火墙限制新连接速率(如
iptables):sudo iptables -A INPUT -p tcp --dport 2222 -m state --state NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 2222 -m state --state NEW -j DROP
(假设已将 SSH 改为 2222 端口)
补充:日志审计与快速响应
密码喷洒会在 /var/log/auth.log 留下特征痕迹:短时间内大量 Failed password for invalid user 或 Failed password for <valid_user></valid_user> 交替出现。
-
实时筛查命令示例:
# 统计10分钟内失败最多的5个用户名 journalctl -u sshd --since "10 minutes ago" | grep "Failed password" | awk '{print $9}' | sort | uniq -c | sort -nr | head -5 # 查看是否同一密码被反复使用(需解析日志中的密码字段,部分发行版不记录明文密码,但可观察失败模式) 建议接入简单日志告警(如
swatch或logwatch),发现异常峰值立即人工核查。
不复杂但容易忽略











