Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Proxy Builder 在 GCP 上运行基于 sing-box 的 VLESS Reality 与 Hysteria2

## 当前状态

仓库正在 `refactor/opentofu-platform` 分支进行破坏性重构。OpenTofu、共享 Go 契约、订阅服务、代理 VM release runtime 与 GitHub Actions 交付链已完成离线实现和验证,但尚未配置 GitHub、apply 或部署;当前在线环境仍由旧 Bash 资源和同一台 GCE VM 上的 sing-box/订阅容器提供服务。
新架构已在 `development` 完成真实激活:OpenTofu 管理 GCP 资源与 WIF,GitHub Actions 通过分离的 plan/apply/deploy 身份发布,sing-box 运行在 GCE VM,订阅服务运行在公开入口的 Cloud Run,并由应用 token 认证用户。完整事务部署和 VLESS Reality/Hysteria2 出站 E2E 已通过;`production` 尚未激活。

当前系统组成见 [Architecture](docs/architecture/overview.md)。重构为什么发生见 [ADR 索引](docs/adr/README.md),将要实现的具体契约见 [Design 索引](docs/design/README.md)。
当前系统组成见 [Architecture](docs/architecture/overview.md)。关键决策见 [ADR 索引](docs/adr/README.md),具体契约见 [Design 索引](docs/design/README.md)。

## 当前开发检查

Expand Down
56 changes: 26 additions & 30 deletions docs/architecture/overview.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 当前架构

本文描述重构开始前仍在运行的系统。新系统已在仓库实现但尚未激活,其契约位于 [ADR](../adr/README.md) 和 [Design](../design/README.md)。
本文描述已经在 `development` 激活并验证的系统。`production` 使用同一结构但尚未激活;具体接口位于 [Design](../design/README.md)。

## 目的与边界

Expand All @@ -10,62 +10,58 @@ Proxy Builder 在 GCP Compute Engine 上运行 sing-box,为每个用户提供

## 环境

系统有 `development` 与 `production` 两个环境。每个环境使用独立的 GCP Project、WIF Provider、部署 Service Account、VM、代理密钥和用户集合;两者使用相同的区域和资源结构。
系统定义 `development` 与 `production` 两个环境。每个环境使用独立的 GCP Project、OpenTofu state、WIF Provider、Service Accounts、运行资源、代理密钥和用户集合。当前只有 `development` 在线。

GitHub 同名 Environment 保存 GCP 接入参数与应用配置。仓库根目录的 `.env.development`、`.env.production` 和 `users.<environment>.json` 是本地维护副本,脚本可将其上传为 GitHub Environment Secrets。
GitHub Repository Variables 保存 pull-request plan 身份;同名 GitHub Environment 保存 apply/deploy 身份与五项应用 Secrets。本地 `.secrets/<environment>/` 是权限受限的灾难恢复副本,不进入 Git。

## 组件与数据流

```text
维护者
│ workflow_dispatch
▼
GitHub Actions ──OIDC/WIF──> GCP deploy Service Account
│ │
├── build/push ─────────────> Artifact Registry
└── gcloud scp/ssh ─────────> Compute Engine VM
│
└── Docker Compose
├── sing-box : TCP/UDP 443
└── subscription : TCP 8080
GitHub Actions ──OIDC/WIF──> plan / apply / deploy Service Accounts
│ │
├── OpenTofu ─────────────────> GCP identity + platform resources
├── build/push ───────────────> Artifact Registry
├── IAP scp/ssh ──────────────> Compute Engine VM
│ └── sing-box : TCP/UDP 443
└── immutable revision ───────> Cloud Run subscription HTTPS
```

### GitHub Actions

线上系统由重构前的 GitHub Actions 交付:构建订阅镜像、推送 Artifact Registry,并把应用与秘密一并上传到 VM。环境由 Git 分支隐式选择。
所有可写 workflow 显式接收环境。pull request 使用只读 plan 身份;platform apply 与应用 deploy 使用独立的 GitHub Environment WIF 身份。production 还受 main-only 和人工审批保护。

### GCP 身份与资源

每个环境的 GitHub OIDC 身份通过 WIF 模拟一个部署 Service Account。该账号同时承担 VM、OS Login、Artifact Registry、Storage 和 Service Account 使用相关操作。

线上基础设施没有声明式 state,历史上由 Bash 调用 `gcloud` 创建或更新 WIF、VM、Artifact Registry 和防火墙资源;当前重构分支不再保留这些命令入口。
OpenTofu 使用独立 `bootstrap` 与 `platform` state。bootstrap 管理 API、WIF 和 GitHub plan/apply/deploy 身份;platform 管理网络、静态 IP、防火墙、VM、Artifact Registry、Secret Manager 容器、Cloud Run 服务及最小 IAM。

### 代理 VM

VM 通过命令式脚本安装 Docker、启用 BBR 并配置主机。部署过程生成 sing-box 配置和自签证书,然后启动 Docker Compose。
VM startup metadata 只负责幂等主机供给。应用部署生成不可变 release,原子切换 `current`,并保留 `previous` 供显式回滚。Docker Compose 中的 sing-box 监听公网 TCP/UDP 443。

`sing-box` 容器监听公网 TCP/UDP 443。它从宿主机挂载生成的配置和证书。
订阅服务与 VM 分离,运行在 Cloud Run。默认 HTTPS URL 公开且关闭 Invoker IAM check;`/v1/health` 无需认证,`/v1/subscription` 由逐用户高熵 token 认证。Secret Manager version 以引用方式注入,不把秘密写入 OpenTofu state。

`subscription` 容器监听公网 TCP 8080。它读取同一台 VM 上的用户文件和证书,根据请求 token 生成订阅内容,并根据 User-Agent 选择输出格式。
部署先激活 VM,再创建零流量 Cloud Run revision;切流后验证公网健康、两种订阅格式及 VLESS Reality/Hysteria2 真实出站。失败时先恢复旧 Cloud Run traffic,再回滚 VM。

## 状态所有权

| 状态 | 当前所有者 |
| --- | --- |
| GCP 资源实际状态 | 各环境 GCP Project;Bash 通过查询后修改 |
| GCP 接入与应用配置 | GitHub Environment Secrets,本地 `.env.<environment>` 有副本 |
| 用户数据 | GitHub `USERS_JSON` Secret,本地 `users.<environment>.json` 有副本 |
| sing-box 运行配置与证书 | VM 文件系统 |
| 订阅镜像 | 各环境 Artifact Registry |
| 部署版本 | Git commit、GitHub run 与 VM 当前文件共同体现 |
| GCP 身份与平台资源 | OpenTofu bootstrap/platform state |
| 非秘密 GitHub 接入标识 | Repository / Environment Variables |
| 应用秘密 | GitHub Environment Secrets;本地 `.secrets/<environment>/` 备份 |
| Cloud Run runtime secrets | Secret Manager versions |
| sing-box 配置、证书与 release | VM `/opt/proxy-builder` |
| 应用镜像 | Artifact Registry digest |
| 已部署版本 | Git SHA + GitHub run/attempt + VM release + Cloud Run revision |

## 当前约束

- 环境选择与 Git 分支隐式绑定。
- GitHub Environment 未配置审批或部署分支保护。
- 非敏感 GCP 配置和应用秘密都存为 GitHub Secrets。
- 单一部署身份同时拥有基础设施和应用发布权限。
- 订阅服务、用户文件和证书与代理 VM 共享生命周期。
- GCP 资源缺少可审查的声明式 state,配置来源存在重复。
- `development` 已真实部署并通过 destroy/rebuild、正式发布、回滚和双协议 E2E。
- `development` 的 bootstrap/platform plan 当前为零变更,GitHub 配置审计通过。
- `production` 资源与秘密尚未激活,任何写操作仍需显式审批。
- Cloud Run request log 按精确服务名排除,避免 query token 被平台日志持久化;应用仅记录脱敏事件。

改变这些边界的原因见 [ADR-0001](../adr/0001-manage-gcp-with-opentofu.md)、[ADR-0002](../adr/0002-separate-proxy-and-subscription-runtimes.md) 和 [ADR-0003](../adr/0003-own-and-deliver-application-secrets.md)。
10 changes: 5 additions & 5 deletions docs/design/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

| 文档 | 唯一拥有的主题 | 实现状态 |
| --- | --- | --- |
| [基础设施与身份](infrastructure-and-identity.md) | OpenTofu 目录、stack/state、模块边界、资源与 IAM/WIF 接口 | 代码已实现,尚未 apply |
| [环境与交付](environments-and-delivery.md) | 环境清单、GitHub 配置、工作流和发布协议 | 代码已实现,尚未配置或执行 |
| [代理与订阅共享契约](proxy-and-subscription-contracts.md) | 用户 schema、Reality 派生与 HY2 证书校验 | 代码已实现,尚未部署 |
| [代理 VM 运行时](proxy-vm-runtime.md) | 主机就绪、release bundle、Compose、原子切换与回滚 | 代码已实现,尚未部署 |
| [订阅服务](subscription-service.md) | 进程配置、HTTP API、订阅格式与日志 | 代码已实现,尚未部署 |
| [基础设施与身份](infrastructure-and-identity.md) | OpenTofu 目录、stack/state、模块边界、资源与 IAM/WIF 接口 | development 已 apply;production 未激活 |
| [环境与交付](environments-and-delivery.md) | 环境清单、GitHub 配置、工作流和发布协议 | development 已配置并通过完整流程 |
| [代理与订阅共享契约](proxy-and-subscription-contracts.md) | 用户 schema、Reality 派生与 HY2 证书校验 | development 已部署并通过 E2E |
| [代理 VM 运行时](proxy-vm-runtime.md) | 主机就绪、release bundle、Compose、原子切换与回滚 | development 已部署并验证回滚 |
| [订阅服务](subscription-service.md) | 进程配置、HTTP API、订阅格式与日志 | development Cloud Run 已部署 |
2 changes: 1 addition & 1 deletion docs/design/environments-and-delivery.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

本文唯一拥有环境配置归属、GitHub Variables/Secrets 名称、工作流接口以及 VM 与 Cloud Run 的发布协议。

**实现状态:** 环境清单、发布工具与 GitHub 工作流已实现并离线验证;GitHub/GCP 尚未配置或执行。
**实现状态:** development GitHub/GCP 已配置,并通过正式部署、协调回滚与双协议 E2E;production 尚未激活。

## 环境模型

Expand Down
2 changes: 1 addition & 1 deletion docs/design/infrastructure-and-identity.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

本文唯一拥有 OpenTofu 目录、stack/state 划分、模块接口、GCP 资源拓扑以及 IAM/WIF 边界。

**实现状态:** 代码已实现并通过离线契约测试,尚未 apply 到 GCP
**实现状态:** development 已 apply、重建并通过零变更 plan;production 尚未激活

## 目录接口

Expand Down
2 changes: 1 addition & 1 deletion docs/design/proxy-and-subscription-contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

本文唯一拥有 proxy VM 与 subscription 服务共享的用户 schema、Reality 派生和 HY2 证书校验规则。VM 文件与切换规则见[代理 VM 运行时](proxy-vm-runtime.md),HTTP 接口见[订阅服务](subscription-service.md)。

**实现状态:** Go 共享契约与 `proxyctl` 已实现并离线验证,尚未部署。
**实现状态:** Go 共享契约与 `proxyctl` 已在 development 部署,并通过双协议真实出站验证。

## 用户 Schema

Expand Down
2 changes: 1 addition & 1 deletion docs/design/proxy-vm-runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

本文唯一拥有 VM 主机就绪标记、release bundle、staging 输入、sing-box Compose、原子切换、健康判断和回滚规则。

**实现状态:** startup、bundle、Compose、发布与回滚代码已实现并离线验证,尚未在 GCE 部署。
**实现状态:** development 已在 GCE 部署,健康 release、previous 与事后回滚均已验证;production 尚未激活。

## 主机供给接口

Expand Down
2 changes: 1 addition & 1 deletion docs/design/subscription-service.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

本文唯一拥有 subscription 进程配置、启动行为、HTTP API、订阅格式和日志规则。

**实现状态:** Go 服务、容器定义与 OpenTofu startup probe 已实现并离线验证,尚未在 Cloud Run 部署。
**实现状态:** development Cloud Run 已部署,公开健康、token 隔离、订阅正文和双协议 E2E 已验证;production 尚未激活。

## 进程配置

Expand Down