security: 增加 Provider 出站端口白名单配置 #55

Closed
opened 2026-08-25 11:51:33 +08:00 by ila · 4 comments
Owner

基本信息

  • 类型:安全配置变更
  • 所属 Epic:#3
  • 所属 MVP / 版本:#35 / MVP-2
  • 阶段:已完成
  • 前置工单:无;#54 的真实 Provider 验证依赖本工单

原始需求

  • 来源:用户对话
  • 提出与确认时间:2026-08-25
  • 脱敏摘要:真实 OpenAI-compatible Provider 使用非标准公开端口;用户明确允许扩展 Chorus Provider 出站端口白名单,同时保留现有 SSRF 防护。

目标

新增显式 Provider 出站端口白名单配置,使受信任部署可在默认 80/443 之外允许指定公开端口,并确保 Portal worker 与管理端连通性探针使用一致策略。

非目标

  • 不允许回环、私网、链路本地、保留或非全局单播地址。
  • 不关闭 DNS 解析后、连接前的 DialContext 校验。
  • 不改变重定向、跨 origin Authorization、结果 URL 或 retryable 规则。
  • 不按 Provider 自动放行任意端口,不记录 Provider 凭据。

已确认方案

  • 新增 CHORUS_PROVIDER_ALLOWED_PORTS,逗号分隔,默认 80,443。
  • 配置仅接受 1..65535 的去重端口;空项、非数字、零和越界均拒绝启动。
  • Portal worker 和管理端连通性探针均把同一白名单传入 SafeHTTP。
  • 本机运行环境显式设置 80,443,8080;仓库中的示例和长期文档只说明通用配置,不记录真实 Provider 地址或凭据。

风险与回退

  • 风险:加入端口后,管理员配置的任意公共 Provider 主机可访问该端口;IP/DNS/redirect 防线仍生效。
  • 回退:删除环境变量或恢复 80,443 并重启服务;不需要数据库迁移。

验收标准

  • 未设置时默认只允许 80/443。
  • 合法自定义端口能传入 Portal 与管理端 SafeHTTP。
  • 非法端口配置导致服务启动失败并给出可定位错误。
  • 现有私网、DNS、redirect、跨 origin 和结果 URL SSRF 测试保持通过。
  • 本机 Supervisor 环境配置允许所需非标准端口,服务可正常启动。
  • Wiki 配置、架构和排错说明更新并同步核心镜像。

验证

  • go test ./internal/config/... ./internal/platform/http/... ./portal/... ./admin/...
  • python dev_scripts/harness.py check --strict
  • python dev_scripts/harness.py sync --check
  • 重启 Supervisor 后检查三个实例;真实调用由 #54 单独受控执行。

文档影响

更新 Wiki 的 Architecture-and-Code-Map、Local-Development-and-Verification、Deployment-and-Operations、Troubleshooting,随后同步核心 docs/ 镜像。

## 基本信息 - 类型:安全配置变更 - 所属 Epic:#3 - 所属 MVP / 版本:#35 / MVP-2 - 阶段:已完成 - 前置工单:无;#54 的真实 Provider 验证依赖本工单 ## 原始需求 - 来源:用户对话 - 提出与确认时间:2026-08-25 - 脱敏摘要:真实 OpenAI-compatible Provider 使用非标准公开端口;用户明确允许扩展 Chorus Provider 出站端口白名单,同时保留现有 SSRF 防护。 ## 目标 新增显式 Provider 出站端口白名单配置,使受信任部署可在默认 80/443 之外允许指定公开端口,并确保 Portal worker 与管理端连通性探针使用一致策略。 ## 非目标 - 不允许回环、私网、链路本地、保留或非全局单播地址。 - 不关闭 DNS 解析后、连接前的 DialContext 校验。 - 不改变重定向、跨 origin Authorization、结果 URL 或 retryable 规则。 - 不按 Provider 自动放行任意端口,不记录 Provider 凭据。 ## 已确认方案 - 新增 `CHORUS_PROVIDER_ALLOWED_PORTS`,逗号分隔,默认 `80,443`。 - 配置仅接受 1..65535 的去重端口;空项、非数字、零和越界均拒绝启动。 - Portal worker 和管理端连通性探针均把同一白名单传入 SafeHTTP。 - 本机运行环境显式设置 `80,443,8080`;仓库中的示例和长期文档只说明通用配置,不记录真实 Provider 地址或凭据。 ## 风险与回退 - 风险:加入端口后,管理员配置的任意公共 Provider 主机可访问该端口;IP/DNS/redirect 防线仍生效。 - 回退:删除环境变量或恢复 `80,443` 并重启服务;不需要数据库迁移。 ## 验收标准 - [x] 未设置时默认只允许 80/443。 - [x] 合法自定义端口能传入 Portal 与管理端 SafeHTTP。 - [x] 非法端口配置导致服务启动失败并给出可定位错误。 - [x] 现有私网、DNS、redirect、跨 origin 和结果 URL SSRF 测试保持通过。 - [x] 本机 Supervisor 环境配置允许所需非标准端口,服务可正常启动。 - [x] Wiki 配置、架构和排错说明更新并同步核心镜像。 ## 验证 - `go test ./internal/config/... ./internal/platform/http/... ./portal/... ./admin/...` - `python dev_scripts/harness.py check --strict` - `python dev_scripts/harness.py sync --check` - 重启 Supervisor 后检查三个实例;真实调用由 #54 单独受控执行。 ## 文档影响 更新 Wiki 的 Architecture-and-Code-Map、Local-Development-and-Verification、Deployment-and-Operations、Troubleshooting,随后同步核心 `docs/` 镜像。
Author
Owner

实施与验证结果

  • 实现提交:b0ecbab,已推送 main。
  • 新增 CHORUS_PROVIDER_ALLOWED_PORTS:默认 80,443;严格解析 1..65535,去重,非法值失败关闭。
  • Portal worker 与启用后的管理端连通性探针均把相同端口列表传入 SafeHTTP。
  • SSRF 测试确认默认 8080 在拨号前拒绝;显式加入后仍解析并校验公共 IP,再拨号到目标端口。私网、DNS rebinding、redirect、跨 origin Authorization、结果 URL 和 proxy 防线未放宽。
  • 本机仓库外运行环境已设为 80,443,8080;三项 Supervisor 服务已显式重启,Portal 登录页和 Admin UI 可访问,Admin API 端口正常监听。

测试

  • go test ./...:通过。
  • cd admin && go test ./...:通过。
  • python -m unittest discover -s tests -v:43 项通过。
  • python dev_scripts/harness.py check --strict:通过。
  • python dev_scripts/harness.py sync --check:通过。

文档

线上 Wiki 的 Architecture-and-Code-Map、Local-Development-and-Verification、Troubleshooting、Deployment-and-Operations 已更新并在线回读;核心镜像已同步。真实 Provider 生成复验仍由依赖本工单的 #54 执行。

## 实施与验证结果 - 实现提交:`b0ecbab`,已推送 `main`。 - 新增 `CHORUS_PROVIDER_ALLOWED_PORTS`:默认 `80,443`;严格解析 1..65535,去重,非法值失败关闭。 - Portal worker 与启用后的管理端连通性探针均把相同端口列表传入 SafeHTTP。 - SSRF 测试确认默认 8080 在拨号前拒绝;显式加入后仍解析并校验公共 IP,再拨号到目标端口。私网、DNS rebinding、redirect、跨 origin Authorization、结果 URL 和 proxy 防线未放宽。 - 本机仓库外运行环境已设为 `80,443,8080`;三项 Supervisor 服务已显式重启,Portal 登录页和 Admin UI 可访问,Admin API 端口正常监听。 ### 测试 - `go test ./...`:通过。 - `cd admin && go test ./...`:通过。 - `python -m unittest discover -s tests -v`:43 项通过。 - `python dev_scripts/harness.py check --strict`:通过。 - `python dev_scripts/harness.py sync --check`:通过。 ### 文档 线上 Wiki 的 Architecture-and-Code-Map、Local-Development-and-Verification、Troubleshooting、Deployment-and-Operations 已更新并在线回读;核心镜像已同步。真实 Provider 生成复验仍由依赖本工单的 #54 执行。
Author
Owner

归档已在线回读:Task-55-Provider-出站端口白名单配置,revision b3f31b723a5323d49b07a0ebca0eca15f400a04b。核心 Wiki 镜像一致性复查通过;任务归档按规则未导出到 docs/task/。

归档已在线回读:`Task-55-Provider-出站端口白名单配置`,revision `b3f31b723a5323d49b07a0ebca0eca15f400a04b`。核心 Wiki 镜像一致性复查通过;任务归档按规则未导出到 `docs/task/`。
Author
Owner

用户端最新图片任务的 provider attempt 已达到上游(约 591ms),与修改前约 1ms 的端口前置拒绝不同,可作为本机自定义端口白名单生效的补充证据。上游随后因模型/能力不匹配返回非重试失败,该问题继续由 #54 跟踪。

用户端最新图片任务的 provider attempt 已达到上游(约 591ms),与修改前约 1ms 的端口前置拒绝不同,可作为本机自定义端口白名单生效的补充证据。上游随后因模型/能力不匹配返回非重试失败,该问题继续由 #54 跟踪。
Author
Owner

用户验收通过

  • 验收时间:2026-08-27 14:57:05 +08:00
  • 验收人:用户
  • 结论:用户明确确认本工单通过验收,接受当前实现、部署与已记录的验证结果。
  • 文档:沿用工单中已经完成的 Wiki/镜像处理;没有新的长期事实变化。
  • 状态:已完成,关闭工单。
## 用户验收通过 - 验收时间:2026-08-27 14:57:05 +08:00 - 验收人:用户 - 结论:用户明确确认本工单通过验收,接受当前实现、部署与已记录的验证结果。 - 文档:沿用工单中已经完成的 Wiki/镜像处理;没有新的长期事实变化。 - 状态:已完成,关闭工单。
ila closed this issue 2026-08-27 14:57:21 +08:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/chorus#55