9Router:评估 AI 网关,不把路由误认为无限权限
阅读 9Router 转发头信任规则
检查 loopback 判断、内部头替换和入口差异,理解为什么启动方式会改变请求边界。
你将学会
- 以 socket 地址为起点
- 替换内部元数据
- 测试真实部署路径
开始前需要
- 基本命令行与配置阅读能力
- 能够在独立且获准的环境中试验
分别记录请求模型、实际尝试和客户端验收,在不保留秘密的前提下解释一次请求的完整路径。
先看结论
- 转发 IP 只在 loopback 分支被信任。
- via-proxy 不是完整信任判断。
- 不同启动路径可能省略包装层。
以 socket 地址为起点
包装层读取 req.socket.remoteAddress,将 127.0.0.1、::1 和 ::ffff:127.0.0.1 视为 loopback 代理。只有这些对端可使用 x-real-ip 或逗号分隔的 x-forwarded-for 首项。
远端直连且非 loopback 时,提供转发地址不会替换此分支中的 socket 地址。这阻止该处身份推导直接相信任意远程调用者自称的客户端 IP。
替换内部元数据
进入应用前移除 x-9r-real-ip、x-forwarded-for、x-9r-via-proxy 和 x-9r-peer-token,再写入推导 IP 与每进程随机 token。原请求是否包含转发头,另外决定 via-proxy 标记。
不能只凭这个标记推断转发地址已被信任,因为信任分支还检查 loopback。包装层也不能证明每个下游消费者都正确使用这些字段,后续仍需要单独审阅。
测试真实部署路径
拟议测试包括远端直连伪造转发值、本地代理清洁头、完全无转发头以及容器网络代理,分别检查推导字段与被删除输入,避免只验证一个成功案例。
文件注释指出裸 Next 启动不会加载该包装层,所以应通过生产入口和真实代理拓扑测试。本次没有执行这些夹具,也没有审计另一个 h2c 升级处理路径。
如何选择
| 比较维度 | 方案 A | 方案 B |
|---|---|---|
| Best when | You need predictable behavior and easy auditing | You need adaptive optimization and have reliable telemetry |
| Main risk | May leave performance on the table | Can become difficult to explain or debug |
实施步骤
- 1
先读 socket 与 loopback 条件,再看头优先级。
- 2
检查客户端内部字段被替换。
- 3
通过真实入口和代理拓扑测试。
可复制示例
{
"proposedFixture": true,
"peer": "203.0.113.10",
"forwardedFor": "198.51.100.20",
"expectedDerivedIp": "203.0.113.10",
"executed": false
}常见问题
任意 x-forwarded-for 都能决定身份吗?
这里不是,非 loopback 对端保留 socket 地址。
整个网关已通过安全验证吗?
没有,只审阅一个请求边界,未执行集成测试。
资料来源
- 9Router / custom-server.js来源核查 2026-09-18