Smail/docs/可信代理地址整改记录.md
smail d193324e6d
Some checks are pending
Security Checks / security (push) Waiting to run
整改基线:封存公网端口分离与远程后端回归候选
2026-09-18 01:05:50 +08:00

4.5 KiB
Raw Blame History

可信代理地址整改记录

范围与状态

本轮针对 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 并推送;尚未据此签署最终发布验收。