Phorge 现代化改造实战(三):接入 Stargate,把 Forward Auth 的信任边界做完整

💡 原文中文,约13400字,阅读约需32分钟。
📝

内容提要

本文介绍Phorge现代化改造实战第三篇,聚焦于通过Traefik Forward Auth与Stargate集成,实现认证网关到Phorge本地账号的信任传递。文章详细说明了r3版本中身份头清洗、端口重置等安全修正,强调认证链需严格顺序,并提供了部署配置、测试方法及安全注意事项,确保外部身份正确映射至Phorge。

🔎

延伸解读

信任链的接缝:认证网关与业务应用的分工

文章强调,接入 Forward Auth 不只是加一个认证 URL,而是建立一条有严格顺序的信任链。Stargate 负责回答“请求能否进入”,Phorge 负责“进入者是谁”并映射到本地账号。这种分工保留了 Phorge 自身的项目权限和审计能力。理解这一边界,有助于避免将认证网关的返回值直接当作权限依据,防止出现“返回 admin 字符串就自动获得管理员权限”的误解。

返工教训:头清洗的位置决定安全边界

r3 版本返工的核心是修正身份头的清洗位置。最初在 Apache 中清洗 X-Auth-* 头,但 Apache 无法区分头来自浏览器还是 Traefik 注入,导致可信头被误删。最终改为在 Traefik 中先清洗再注入,并明确中间件顺序。这提醒我们,安全配置必须考虑组件间的执行顺序,否则看似正确的设置可能破坏整个信任链。

端口重置:Compose 合并规则的陷阱

文章指出,Docker Compose 合并 ports 时以 {ip, target, published, protocol} 为唯一键,基础配置的 IP 为空,叠加配置的 IP 为 127.0.0.1,两者不会覆盖,可能导致端口冲突或未隔离。r3 使用 !reset [] 清空端口序列,确保 Phorge 不暴露宿主机端口。这提醒我们,验证 Compose 配置不能只看语法正确,还需检查合并后的语义是否符合预期。

认证模式决定身份质量

文章区分了共享密码模式和个人身份模式。共享密码模式只能确认“已认证”,无法提供稳定用户 ID,导致 Phorge 无法映射到具体账号。完整联动需要 Warden 用户记录和 Herald 验证码等,才能产生 X-Auth-User 等头。这提醒我们,选择认证模式时,必须明确后端需要的是布尔结果还是真实身份,否则会出现账号混用和审计缺失的风险。

Q&A

Phorge 如何通过 Traefik Forward Auth 与 Stargate 集成,实现外部身份到本地账号的映射?

Phorge 通过新增的 PhabricatorTraefikAuthProvider 和 PhutilTraefikAuthAdapter 读取 Traefik 转发请求中的 X-Auth-User、X-Auth-Email、X-Auth-Name 头,将外部稳定 ID 映射到本地账号。Traefik 先调用 Stargate 的 /_auth 进行认证,认证通过后将响应中的身份头注入到发往 Phorge 的请求中。Phorge 的 Provider 以 X-Auth-User 为锚点,创建或关联本地 External Account,从而保留 Phorge 自身的权限和审计功能。

在 Phorge 与 Stargate 集成时,为什么不能使用共享密码模式?

共享密码模式只能确认会话已认证,但无法识别具体用户,Stargate 返回的 X-Auth-User 为空。Phorge 的 Provider 要求 X-Auth-User 非空,否则无法建立本地账号映射。若将 X-Forwarded-User: authenticated 作为备用 ID,会导致所有使用共享密码的用户映射到同一个 Phorge 账号,造成审计缺失和账号混用风险。因此必须使用能产生个人身份的认证路径,如 Warden 用户记录配合 Herald 验证码或 TOTP。

Phorge r3 版本中如何清洗伪造的 X-Auth-* 头?

r3 将清洗前移到 Traefik,通过中间件顺序实现:先使用 phorge-strip-auth-headers 中间件删除请求中可能存在的 X-Auth-User、X-Auth-Email、X-Auth-Name 头,再执行 phorge-forwardauth 中间件,由 ForwardAuth 将 Stargate 响应中的可信身份头写入请求。这样即使客户端伪造同名头,也会在认证前被清除,确保后端只信任认证服务注入的身份。

Phorge r3 如何解决 Docker Compose 叠加时端口无法覆盖的问题?

基础 docker-compose.yml 中定义了端口映射,但叠加文件无法通过再次声明端口来覆盖,因为 Compose 合并时端口以 IP、target 等作为唯一键,不同 IP 不会覆盖。r3 使用 Docker Compose 2.24.4+ 的 !reset 语法,在叠加文件中设置 ports: !reset [],明确清空基础文件的端口序列,使 Phorge 不再发布宿主机端口,仅通过 Docker 网络与 Traefik 通信。

Phorge r3 中如何解决 HTTPS 检测问题?

由于 Traefik 对外提供 HTTPS,但转发到 Apache 时使用 HTTP,Phorge 会误判为 HTTP。r3 新增 support/preamble.proxy-https.php,通过只读挂载为 support/preamble.php,该文件检查 X-Forwarded-Proto 头,若为 https 则设置 $_SERVER['HTTPS']='on' 和 SERVER_PORT=443,使 Phorge 正确识别 HTTPS 请求。

Phorge r3 中如何配置 Stargate 的 TRUSTED_PROXIES?

Stargate 要求通过 TRUSTED_PROXIES 声明直接连接它的可信代理,未命中该范围的 X-Forwarded-* 头不会被信任。建议为代理网络指定明确且不冲突的 CIDR,例如 172.31.30.0/24,并在 docker-compose 中为 Traefik 和 Stargate 配置该网络。如果已有公共 Traefik 网络,应使用 docker network inspect 获取实际 CIDR 进行配置。

Phorge r3 中如何启用 Traefik Auth 认证方式?

需要先使用现有管理员账号登录 Phorge,进入 Auth → Auth Providers → Add Authentication Provider → Traefik Auth,然后根据场景开启 Allow Login、Allow Registration、Allow Linking。建议按安全顺序上线:先保留原 Provider,逐步切换,避免将管理员锁在门外。

Phorge r3 中如何测试 Forward Auth 集成是否安全?

测试应包括:正常登录、未登录访问、伪造头、后端直连和账号撤销。具体检查:docker compose config 确认 phorge.ports 为空;Stargate 的 /healthz 和 /readyz 正常;未登录请求应跳转或返回 401;伪造 X-Auth-User 头但无 Stargate Session 时应被拒绝;使用 Warden 测试用户登录后观察 X-Auth-* 头;从外部访问宿主机端口应失败。

🏷️

标签

➡️

继续阅读