我的服务器被暴力破解 10 万次后,我才真正理解公网安全

简喵上线后,我做了一次服务器安全检查,本来只是想确认部署是否稳定,结果先看到的不是业务日志,而是 SSH 登录日志里密密麻麻的攻击痕迹。

在当前 auth.log 里,时间范围是 2026-07-05 00:03:17 到 2026-07-07 14:45:03。这段时间内出现了:

  • Failed password: 11700
  • Invalid user: 7904
  • 解析到的认证相关事件总数:26812

更早的轮转日志里,认证事件总量超过 10 万条。高峰小时里,单小时攻击尝试超过 1800 次。

最常被猜的用户名也很典型:adminubuntuusertestdeploydebianpipostgresgitmysqljenkins。这些不是我的简喵业务设计的账号,而是互联网上自动化扫描 SSH 时常见的字典。

攻击证据截图如下:

image.png (其余被攻击日志过长仅展示这一部分)

这件事给我的第一个结论就是服务器一旦暴露到公网,就会自动进入全球扫描流量池。

从日志上看这更像是公网 SSH 的无差别自动化撞库。

原因有三个,第一,攻击用户名高度通用。攻击者没有尝试我的业务账号、项目名、域名相关名称。第二,来源 IP 分散,行为模式重复。大量日志是 Invalid user xxx from 某 IP,随后紧跟 Failed password for invalid user。第三,我的登录记录和攻击记录可以明显区分。我自己的来源 IP 在日志里是 Accepted publickey,并且 failed_or_invalid=0。也就是说,我没有在反复输错密码;失败记录来自外部公网 IP。

攻击者到底想要什么?进入服务器后,他们不一定关心我的产品是什么。对攻击者来说,一台云服务器本身就是资源:

  1. 可以拿来挖矿,消耗你的 CPU、内存和云账单。
  2. 可以变成跳板机,继续扫描别人。
  3. 可以偷 .env、数据库密码、JWT 密钥、对象存储密钥、第三方 API Key。
  4. 可以植入 cron、systemd 后门,长期潜伏。
  5. 可以篡改前端静态文件或后端服务,投毒用户访问链路。
  6. 可以打包数据库和用户文件,造成真实数据泄露。
  7. 可以把你的 IP 打进黑名单,影响邮件、搜索、支付、接口调用等外部信誉。

对我来说,最严重的不是服务器宕机,而是如果 SSH 被拿下,攻击者可以绕开应用层权限,直接读取部署目录、环境变量、数据库连接信息和用户简历数据。

应用安全挡不住服务器失守。只要运维入口被拿下,后端鉴权写得再好,也可能被从内部绕过。

为什么10W次攻击都没有成功? 第一,没有弱口令被猜中。
第二,我实际运维使用的是 SSH 公钥登录。
第三,大量用户名本来就不存在。
第四,后续我把 SSH 密码登录彻底关闭了。

我不想把这件事包装成“上线前我们已经万无一失”。更准确的说法是:上线时没有被撞开,说明基础密码风险没有暴露;但日志里出现大量 Failed password,说明密码登录攻击面仍然存在,必须立刻收掉。

这次过后我做了什么防护?第一层,也是最关键的一层:关闭 SSH 密码登录。

最终 SSH 策略收敛成:

text
复制代码
PasswordAuthentication no PubkeyAuthentication yes PermitRootLogin prohibit-password MaxAuthTries 3

SSH 不再接受密码,只接受密钥。MaxAuthTries 也降低了单连接认证尝试次数。 第二层:启用 fail2ban,发现同一来源持续失败后自动封禁。 第三层:收紧 Web 源站暴露面。我用 Cloudflare 保护 Web 流量,但 Cloudflare 默认只保护 HTTP/HTTPS,不保护 SSH。因此我把 80/443 的源站访问改成只允许 Cloudflare 官方 IP 段回源,避免攻击者绕过 Cloudflare 直接打源站。 第四层:收紧敏感文件权限。后端 .env、部署备份目录都做了权限收敛。因为一旦普通进程或低权限账号出问题,.env 往往就是攻击者横向移动的第一目标。 第五层:保留回滚和备用入口。我在调整 SSH 前做了配置备份和回滚脚本,并保留了备用运维账号,做到改完还能验证,出错还能回退。

这件事对我的警示:第一,公网服务器不是上线后才被攻击,而是上线那一刻就被扫描。 只要有公网 IP、有开放端口,就会被批量探测。 第二,Cloudflare 不是万能护盾。 它能保护 Web 入口,但 SSH、数据库、Docker API、管理后台、对象存储密钥这些都要单独处理。 第三,不要把“没被攻破”误判成“没有风险”。 这次没成功,不代表攻击不存在。日志里的上万次失败就是风险本身。 第四,密码登录应该从默认能力变成例外能力。 对服务器运维来说,SSH 密钥、固定来源、VPN/Zero Trust、最小权限,应该是上线前的基础门槛。 第五,独立开发者也要按生产环境标准对待安全。 攻击者不会因为你是个人项目就放过你。自动化脚本不认识公司规模,它只认识开放端口和弱配置。具体的上线前应用防护可以见我写的上一篇文章:blog

如果你也在部署自己的产品,我建议至少做这些:

  1. SSH 禁用密码登录,只允许公钥。
  2. 不使用弱口令,不暴露默认账号。
  3. 限制 SSH 来源,最好走 VPN、Tailscale、Cloudflare Tunnel 或固定 IP。
  4. 开启 fail2ban 或同类自动封禁。
  5. Web 源站只允许 CDN/反代回源,不让公网直接绕过。
  6. .env、备份、私钥、部署脚本权限收紧。
  7. 日志里定期看 Failed passwordInvalid userAccepted
  8. 每次安全改动前留回滚路径。
  9. 把密钥轮换、备份恢复、最小权限当成上线流程的一部分。
  10. 不要等到数据泄露后才开始做安全。

结语:

这次事件不是“我的简喵被某个黑客盯上了”,而是更现实的一课:

只要把服务器放到公网上,你就已经站在攻击面上。

攻击者不需要认识你,也不需要理解你的业务。他们只需要脚本扫到你的 22 端口,然后一遍遍尝试 rootadminubuntu 和常见密码。

真正的安全不是指望没人来,而是在他们来的时候,没有可撞开的门。 我最大的感受就是很多安全意识不是在课本里直接学会的,而是在项目真正上线、服务器真正暴露到公网之后,被日志和攻击流量一点点逼出来的。 我是 Ryan,CS 在读本科生,正在记录自己从 0 到 1 做 AI 应用工程、项目上线、部署运维和安全加固的成长过程。后续我会继续把真实踩坑、修复过程和工程复盘写下来。

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
Ryan
下载 APP