4.5 KiB
可信代理地址整改记录
范围与状态
本轮针对 Nginx 反代后登录 IP 限流、验证码绑定和自助恢复来源均被识别为回环地址的问题。基线提交为 05b2445,修改前已推送远程仓库。所有测试执行在 47.108.78.12;本机只编辑、静态检查、交叉编译 Linux 测试程序和上传,不运行测试程序。
- [✓] 明确配置的可信代理才允许传递客户端地址,空配置不隐式信任回环来源。
- [✓] 登录限流和安全验证统一使用客户端地址解析,不修改请求的原始连接地址。
- [✓] 26 个解析场景、空请求和真实隔离 Nginx 双来源测试通过。
- [✓] 控制器 85 项、HTTP 层 65 项完整逐用例回归通过;浏览器专用夹具 1 项跳过,不计作浏览器验收。
- 最新应用构建、隔离安装、可信代理配置迁移、实际登录和验证码流程、生产部署及回退验收。
本轮未清理生产数据库、未改生产程序、未调整邮件端口、未开启公共管理接口。当前生产应用仍为此前部署版本,不能把候选测试通过描述为线上 IP 限流问题已解决。
实现边界
backend/utils/clientip 接收请求和 http.trustedProxyCidrs,先检查真实 TCP 来源是否位于显式配置的可信网段。只有可信来源的单个 X-Forwarded-For 头可参与解析;不将 X-Real-IP 或 Forwarded 当作回退来源。
多级代理链从右向左检查,停在首个非可信地址,不使用任意客户端可添加的最左侧地址。重复头、非法或空链元素、带端口或区域标识的地址、未指定地址、多播地址、超长头和超过 32 跳的链均回退到真实连接来源。IPv4 映射 IPv6 先规范化,避免同一来源形成多个限流键。配置中包含非法网段时也不信任转发头。
控制器 remoteIP 和 loginRemoteHost 共用同一解析结果,因此验证码签发、验证、恢复和登录限流对来源的理解一致。账号维度限流保持不变。没有修改 RemoteAddr,首次安装来源限制、原有 TLS 模式识别和本机管理 IPC 边界保持不变。
上线时应仅配置真实代理网段。本服务器上游为 127.0.0.1:8002,可使用 127.0.0.1/32;仅在确实使用 IPv6 回环上游时再加入 ::1/128。不得为了兼容而配置 0.0.0.0/0 或 ::/0。Nginx 必须继续使用 proxy_set_header X-Forwarded-For $remote_addr 覆盖客户端头,而非无条件信任已有转发链。若以后接入 CDN,需要重新确定代理信任边界并验收,不能直接扩大网段。
更正真实 IP 可能使部署前按回环地址绑定的待验证挑战失效,应重新发起验证;不得为迁移兼容而跳过 IP 绑定。该变更本身不声称已经撤销所有旧会话或完成管理员恢复验收。
已有证据
首轮目录:/var/tmp/smail-review-proxy-20260918。单元 smail-tests-20260918-004126 在 128 MiB 上限、独立网络、只读系统、禁止访问生产应用和管理接口的环境执行。39 个顶层针对性测试通过;浏览器专用夹具 TestSecuritySetupBrowserFixture 跳过,不能计作浏览器验收。运行 450 毫秒,峰值 16.5 MiB,交换为零。
最终候选目录:/var/tmp/smail-review-proxy-final-20260918。三个测试程序上传后核对 SHA-256,清单保存于 manifest.json,未覆盖首轮产物。
客户端地址单元 smail-tests-20260918-004453:三个顶层测试通过、无跳过;包含 26 个解析子场景及两条真实 Nginx 来源链路。测试在独立网络创建自己的 Nginx 和后端,仅连接该网络中的回环地址;不读取宿主机 Nginx 配置,不连接线上后端。来自 127.0.0.2 和 127.0.0.3 的重复伪造转发头经 Nginx 覆盖后,后端仍分别识别真实来源,连接来源保持 127.0.0.1。
完整回归单元:smail-tests-20260918-004454,使用 192 MiB 上限,逐用例独立进程,避免历史全局状态干扰;结果位于 results-20260918-004454。控制器 85 项通过、无跳过,HTTP 层 65 项通过、浏览器专用夹具 1 项跳过;两包均无失败。单元成功退出,运行 1 分 59.158 秒,峰值 143.7 MiB,交换为零。客户端解析单元运行 403 毫秒,峰值 12 MiB,交换为零。
收尾直接读取远程两份 results.json 复核,Nginx 主进程 578671、Smail 主进程 574584 未变化,均为运行状态且自动重启计数为零。代码候选已封存为 a4280e7 并推送;尚未据此签署最终发布验收。