最近看服务器后台日志,是不是偶尔也会觉得脊背发凉?

服务器日志监控示意图

服务器日志中出现的未知请求记录

明明自己的服务没怎么公开推广,却总收到一堆莫名其妙的请求。比如最近有朋友反馈,他的 CPA(可能是指某个中转代理服务)突然被“扫”了,日志里全是些从未见过的来源请求。

一、 这些“怪请求”长啥样?

先来看看这些请求的特征,大家以后遇到了可以一眼识破。

从日志来看,攻击者的目标非常明确:探测 API 是否可用,以及是否会消耗你的额度

  1. 万能的开始: “你是谁?谁开发的?” 这句话几乎是所有 AI 模型探测的标准开场白。如果模型正常回答,说明接口通了。

  2. 带参数的数学题: “计算 27 + 66 等于多少...” 注意看,这不仅仅是闲聊。这里的数字是随机变化的。这意味着攻击者不是在做简单的重复请求,而是在试图绕过缓存校验,确认每次请求都能真正到达模型进行计算。

  3. 尝试不同模型: 有的请求指向 gemini-pro,有的指向 claude-opus 甚至是不存在的版本。对方在拿着字典盲猜你服务器上部署了哪些模型。

  4. User-Agent 极其逼真: 日志里的 UA 是标准的 Chrome 浏览器字符串。这说明这不是低级的脚本,很可能是一个经过伪装的扫描器,甚至可能是浏览器端的半自动化脚本。

虽然目前的日志显示返回状态码是 401(Invalid API key),说明你的密钥暂时没泄露,或者对方还没蒙对。但这就好比有人一直在你家门口拧门把手,虽然现在还没拧开,但看着也膈应,而且万一哪天真的撞对了 key,损失就大了。

二、 核心风险在哪里?

这种“探路”行为有两个主要危害:

  1. 资源消耗: 即使大部分请求被 Key 检验拦截,但请求依然经过了你的 Nginx/网关层,占用了带宽和连接数。如果量大起来,那就是小型的 DDoS。
  2. 信息泄露: 通过错误信息的细微差别(虽然你的案例里返回得很规范),攻击者可能会推断出你使用的网关类型、版本号,甚至是否存在其他未授权的路由。

三、 博主实测:几招教你把门焊死

遇到这种情况,光靠“没泄露”安慰自己是不行的,得主动出击。这里给出几个不同层级的防御方案,按难度从低到高排列。

1. 终极杀招:直接上“白名单”

如果你的 API 服务只是给自己或者前端特定的几个项目用,最有效、成本最低的方法就是 IP 白名单。

  • 操作逻辑: 在 Nginx 或者防火墙上,只允许你前端服务器的 IP、或者你自己家里的固定 IP 访问 API 端口(如 /v1/chat/completions)。
  • 效果: 直接从物理连接上切断其他所有来源。任他扫描脚本再厉害,连握手的资格都没有。

2. 接入层防御:Nginx 加点“佐料”

如果必须公网访问,不能锁死 IP,那么就在 Nginx 层做限制。

  • 限制请求频率(Rate Limiting): 正常用户不可能一秒钟发几十次请求。配置 ngx_http_limit_req_module,对单个 IP 或 API 端点进行限流。超过阈值直接返回 444 或 503。

    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=5r/s;
    server {
        location /v1/ {
            limit_req zone=api_limit burst=10 nodelay;
            # ...
        }
    }
    
  • 验证 Referer 头: 检查请求来源。如果你的 API 是给自家网页用的,务必检查 Referer 是否包含你的域名。裸奔的脚本请求通常没有 Referer 或者来源可疑。

  • 拦截特征字符串: 虽然麻烦点,但你可以写个 Lua 脚本或者利用 Nginx 的正则匹配,如果 Post Body 里包含“你是谁”或者连续的计算题 pattern,直接拦截。不过这点要注意误伤正常用户,慎用。

3. 应用层加固:增加“暗号”验证

不要直接把原始的 API Key 暴露在公网接口上即使你用了 Key。建议在网关层自己实现一套简单的鉴权逻辑。

  • 自定义 Header 或 Token: 不要只靠 Authorization: Bearer sk-xxx。要求请求必须携带一个自定义的 Header,比如 X-Secret-Token: my-internal-salt。攻击者不知道这个 Token,就算猜对了 API Key 也没用。
  • 请求签名: 对参数进行时间戳 + 签名验证,防止重放攻击,这招对专业羊毛党有效。

4. 既然是“扫”,那就用 WAF 自动化挡

如果你服务器上跑着 Cloudflare 或者宝塔面板之类的 WAF(Web应用防火墙),现在就可以去规则库里加一条规则了。

  • 特征规则: 拦截 URI 包含 generateContent 且 User-Agent 为空,或者请求频率极高的 IP。
  • 人机验证: 对于异常频繁的 IP,直接触发 5 秒钟的 JavaScript 质询(Cloudflare 的 Turnstile),脚本通常过不了这一关。

四、 结语

互联网就是这样,只要你把服务暴露在公网,就永远有机器人在不知疲倦地“拧门把手”。

看到日志里的 401 错误虽然说明账号安全,但别掉以轻心。花个半个小时,配置一下 IP 白名单或者限流规则,把这些“不速之客”拒之门外,给自己的服务器省点资源,也让自己晚上能睡个安稳觉。

安全无小事,早防早安心!

标签: none

评论已关闭