From f7c5eb1cc9d6e2511812d36aa65566f98436b70a Mon Sep 17 00:00:00 2001 From: ryan Date: Tue, 10 Mar 2026 09:49:49 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=AE=BE=E8=AE=A1=E6=96=87?= =?UTF-8?q?=E6=A1=A3=EF=BC=8C=E5=A2=9E=E5=8A=A0=20HTTPS/TLS=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E3=80=81=E8=AF=81=E4=B9=A6=E6=89=98=E7=AE=A1=E4=B8=8E?= =?UTF-8?q?=E5=9F=9F=E5=90=8D=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=9B=B8=E5=85=B3=E4=BA=A4=E4=BB=98=E6=A0=87?= =?UTF-8?q?=E5=87=86=E4=B8=8E=E6=A3=80=E6=9F=A5=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/design.md | 137 ++++++++++++++++++++------------- docs/development-guidelines.md | 41 ++++++---- docs/development-plan.md | 74 +++++++++--------- 3 files changed, 147 insertions(+), 105 deletions(-) diff --git a/docs/design.md b/docs/design.md index a8b1962c..db2df9e4 100644 --- a/docs/design.md +++ b/docs/design.md @@ -46,17 +46,16 @@ **2.5.1 HTTPS/TLS 支持** -* `proxy_routes` 增加 HTTPS 相关字段:`enable_https`、`ssl_cert_path`、`ssl_key_path` +* `proxy_routes` 增加 HTTPS 相关字段:`enable_https`、`cert_id`、`redirect_http` * 渲染器根据字段生成 HTTPS `server` 块(443 端口),并可选生成 HTTP → HTTPS 重定向块 -* 证书文件仍由节点本地预先准备,控制面只记录路径,不托管证书 +* 控制面托管证书并下发到节点本地,支持手动导入与文件导入 -**2.5.2 节点分组与差异化下发** +**2.5.2 域名管理与证书托管** -* 新增 `node_groups` 表:管理分组(如 staging、production) -* `nodes` 增加 `group_id` 字段,节点可归属某个分组 -* 发布时可选择目标分组,生成面向该分组的版本 -* 不指定分组时,默认行为与第一版相同(全量下发) -* Agent 在心跳时携带自身分组信息,Server 按分组返回对应激活版本 +* 新增 `managed_domains` 表:管理业务域名,支持精确域名与通配符域名(如 `*.example.com`) +* 新增 `tls_certificates` 表:保存证书与私钥,支持手动粘贴导入和证书文件上传导入 +* 控制面新增证书管理与域名管理页面 +* 在反代规则编辑时,输入域名后自动匹配可用证书(包含通配符匹配) **2.5.3 Agent Token 管理** @@ -80,8 +79,9 @@ * 多租户 * WAF、限流、Bot、防刷 +* 节点分组与差异化下发 * 对象存储、消息队列、Redis、Prometheus -* 证书托管与自动签发 +* 证书自动签发(ACME) * Purge、中台审计、审批流 * mid-tier / 分层缓存 * 复杂缓存策略配置 @@ -193,8 +193,7 @@ Agent 使用 Go 单体程序: 第二版新增字段: * `enable_https` — 是否启用 HTTPS(bool,默认 false) -* `ssl_cert_path` — 节点本地证书文件路径(string) -* `ssl_key_path` — 节点本地私钥文件路径(string) +* `cert_id` — 关联托管证书 ID(nullable,未启用 HTTPS 时可为空) * `redirect_http` — 是否将 HTTP 重定向到 HTTPS(bool,默认 false) * `custom_headers` — 自定义 `proxy_set_header` 指令(JSON 格式,存字符串) @@ -219,9 +218,7 @@ Agent 使用 Go 单体程序: * `rendered_config` 保存渲染后的 Nginx 路由配置 * 第一版直接存 SQLite,不单独上对象存储 -第二版新增字段: - -* `group_id` — 关联目标分组(nullable,null 表示全量发布) +第二版沿用第一版字段,不新增分组字段。 ### 5.3 nodes(第一版) @@ -242,9 +239,7 @@ Agent 使用 Go 单体程序: * `created_at` * `updated_at` -第二版新增字段: - -* `group_id` — 所属节点分组(nullable,无分组时为 null) +第二版沿用第一版字段,不新增分组字段。 ### 5.4 apply_logs(第一版) @@ -259,19 +254,37 @@ Agent 使用 Go 单体程序: * `message` * `created_at` -### 5.5 node_groups(第二版新增) +### 5.5 tls_certificates(第二版新增) -节点分组表,用于差异化下发。 +证书托管表,用于保存证书与私钥内容。 建议字段: * `id` -* `name` — 分组名称,唯一(如 `staging`、`production`) -* `remark` — 备注 +* `name` — 证书名称(唯一) +* `cert_pem` — 证书 PEM 内容 +* `key_pem` — 私钥 PEM 内容 +* `not_before` — 证书生效时间 +* `not_after` — 证书过期时间 +* `remark` * `created_at` * `updated_at` -### 5.6 agent_tokens(第二版新增) +### 5.6 managed_domains(第二版新增) + +域名管理表,用于维护可选域名及其默认证书关系。 + +建议字段: + +* `id` +* `domain` — 域名(支持精确域名和 `*.example.com`) +* `cert_id` — 关联 `tls_certificates.id`(nullable) +* `enabled` +* `remark` +* `created_at` +* `updated_at` + +### 5.7 agent_tokens(第二版新增) Agent Token 管理表,替代全局单一 Token。 @@ -363,13 +376,13 @@ server { ### HTTPS 处理 -第一版不在控制中心管理证书。 +第一版不在控制中心管理证书,第二版开始支持证书托管。 约定如下: -* Nginx 的监听端口、证书、TLS 相关配置由节点本地预先准备 -* 控制中心只负责反代映射 -* 如果节点已经具备 HTTPS 接入能力,后续可以扩展生成 HTTPS `server` 块 +* 第一版:Nginx 的监听端口、证书、TLS 相关配置由节点本地预先准备 +* 第二版:控制中心托管证书并在配置下发时生成对应证书文件与 HTTPS 配置引用 +* 第二版:反代规则可通过 `cert_id` 绑定证书,并支持 HTTP → HTTPS 重定向 ### 缓存处理 @@ -512,10 +525,16 @@ Agent 每次上报: ### 11.3 第二版新增管理端 API -* `GET /api/node-groups/` — 分组列表 -* `POST /api/node-groups/` — 创建分组 -* `PUT /api/node-groups/:id` — 更新分组 -* `DELETE /api/node-groups/:id` — 删除分组 +* `GET /api/tls-certificates/` — 证书列表 +* `POST /api/tls-certificates/` — 手动导入证书(粘贴 PEM) +* `POST /api/tls-certificates/import-file` — 证书文件导入 +* `PUT /api/tls-certificates/:id` — 更新证书备注/状态 +* `DELETE /api/tls-certificates/:id` — 删除证书 +* `GET /api/managed-domains/` — 域名列表 +* `POST /api/managed-domains/` — 创建域名并可绑定默认证书 +* `PUT /api/managed-domains/:id` — 更新域名配置 +* `DELETE /api/managed-domains/:id` — 删除域名 +* `GET /api/tls-certificates/match?domain=` — 按输入域名返回匹配证书(支持 `*.example.com`) * `GET /api/agent-tokens/` — Token 列表 * `POST /api/agent-tokens/` — 创建 Token * `DELETE /api/agent-tokens/:id` — 撤销 Token @@ -558,8 +577,7 @@ Agent(第二版): 第二版新增字段: * 是否启用 HTTPS -* SSL 证书路径 -* SSL 私钥路径 +* 证书选择(自动匹配候选证书,支持通配符) * 是否 HTTP → HTTPS 重定向 * 自定义请求头(JSON 编辑器) @@ -579,7 +597,6 @@ Agent(第二版): 第二版新增: -* 发布目标分组选择(可选,不选则全量) * 发布前展示配置预览与变更摘要 ### 12.4 节点页(第一版,已实现) @@ -593,10 +610,6 @@ Agent(第二版): * 最后心跳时间 * 最近错误 -第二版新增: - -* 所属分组 - ### 12.5 应用记录页(第一版,已实现) 展示: @@ -621,19 +634,35 @@ Agent(第二版): * 创建 Token * 撤销 Token -### 12.7 节点分组页(第二版新增) +### 12.7 证书管理页(第二版新增) 展示: -* 分组名称 +* 证书名称 +* 有效期(起止时间) +* 绑定域名数量 * 备注 -* 该分组下节点数 动作: -* 创建分组 -* 编辑分组 -* 删除分组 +* 手动导入证书(粘贴 PEM) +* 文件导入证书 +* 删除证书 + +### 12.8 域名管理页(第二版新增) + +展示: + +* 域名(支持 `*.example.com`) +* 绑定证书 +* 是否启用 +* 备注 + +动作: + +* 创建域名 +* 绑定/更换证书 +* 删除域名 --- @@ -666,13 +695,16 @@ atsf_server/ ```text atsf_server/ controller/ - node_group.go # 节点分组 CRUD + tls_certificate.go # 证书管理 + managed_domain.go # 域名管理 agent_token.go # Token 管理 model/ - node_group.go # NodeGroup 模型 + tls_certificate.go # TLSCertificate 模型 + managed_domain.go # ManagedDomain 模型 agent_token.go # AgentToken 模型 service/ - node_group.go # 分组逻辑 + tls_certificate.go # 证书导入与匹配逻辑 + managed_domain.go # 域名管理逻辑 agent_token.go # Token 创建与验证 renderer.go # 抽离渲染逻辑(HTTPS 支持扩展) middleware/ @@ -697,9 +729,8 @@ atsf_agent/ 第二版 Agent 无需新增模块,只需在现有模块内扩展: -* `config`: 新增 `group_id` 配置项 -* `heartbeat`: 心跳请求中携带 `group_id` -* `sync`: 按分组获取对应激活版本(Server 端路由区分) +* `sync`: 拉取包含 HTTPS 与证书引用的渲染配置并应用 +* `nginx`: 写入控制面托管证书生成的本地文件并参与 `nginx -t` / reload --- @@ -720,7 +751,7 @@ atsf_agent/ 1. HTTPS/TLS 支持(ProxyRoute 扩展字段 + 渲染器 + 前端表单) 2. Agent Token 管理(agent_tokens 表 + 中间件改造 + 前端 Token 管理页) -3. 节点分组与差异化下发(node_groups 表 + 发布分组逻辑 + Agent 携带 group_id) +3. 域名管理与证书托管(managed_domains/tls_certificates + 证书导入 + 自动匹配) 4. 路由增强(custom_headers 字段 + 渲染器注入 + 前端表单) 5. 配置预览与变更摘要(preview 接口 + diff 接口 + 前端发布确认弹窗) @@ -746,8 +777,8 @@ atsf_agent/ ### 第二版取舍 -* HTTPS 支持不托管证书,只记录本地路径,避免引入证书存储和签发复杂度 -* 节点分组不做跨分组继承,每个分组独立一套激活版本,降低理解负担 +* HTTPS 支持由控制面托管证书,但只支持导入,不做自动签发与自动续期 +* 第二版不做节点分组,所有节点继续消费同一份激活版本 * Token 管理不做细粒度权限(如只读 Token),第二版所有 Token 权限一致 * 路由自定义头不做模板变量,只支持静态 key-value,避免过早引入 DSL * 配置预览只展示渲染结果,不实际验证 Nginx 语法,真实校验仍由 Agent 完成 @@ -755,5 +786,5 @@ atsf_agent/ 第二版成功标准: ```text -HTTPS 路由可生效 + 节点可按分组差异化下发 + Token 可在界面管理 + 发布前可预览变更 +HTTPS 路由可生效 + 控制面可托管证书并按域名自动匹配(含通配符)+ Token 可在界面管理 + 发布前可预览变更 ``` diff --git a/docs/development-guidelines.md b/docs/development-guidelines.md index 9eaa34d9..71548d5c 100644 --- a/docs/development-guidelines.md +++ b/docs/development-guidelines.md @@ -13,8 +13,9 @@ 第二版在此基础上新增以下能力: * HTTPS/TLS 路由支持 +* 证书托管(手动导入与文件导入) +* 域名管理与证书自动匹配(支持 `*.example.com`) * Agent Token 管理 -* 节点分组与差异化下发 * 路由自定义请求头 * 配置预览与变更摘要 @@ -23,8 +24,9 @@ * 多租户 * WAF、限流、Bot、防刷 * 百分比灰度发布 +* 节点分组与差异化下发 * Redis、MQ、对象存储、Prometheus -* 复杂缓存策略、证书托管、Purge、审批流 +* 复杂缓存策略、证书自动签发、Purge、审批流 * mid-tier、分层缓存、复杂策略编排 超出以上范围的需求,必须先更新设计文档,再开始编码。 @@ -63,16 +65,19 @@ Agent 放在 `atsf_agent`,使用 Go 单体程序开发。 ### 2.3 Nginx 配置边界 -第一版控制面只管理独立生成的 Nginx 路由配置文件,例如 `/etc/nginx/conf.d/atsflare_routes.conf`。 +第一版控制面只管理独立生成的 Nginx 路由配置文件,例如 `/etc/nginx/conf.d/atsflare_routes.conf`。第二版在此基础上增加证书托管能力。 -以下内容先不纳入控制面: +第一版以下内容不纳入控制面: * `nginx.conf` -* TLS 证书 * 缓存策略 * upstream 高级配置 -这些内容先保持节点本地静态配置。 +第二版约束: + +* 允许在控制面托管 TLS 证书并下发给节点 +* 仅支持证书导入(手动粘贴与文件导入),不做自动签发/续期 +* `nginx.conf`、缓存策略、upstream 高级配置仍保持节点本地静态配置 ## 3. 仓库职责划分 @@ -119,7 +124,7 @@ Agent 放在 `atsf_agent`,使用 Go 单体程序开发。 * Server 只管状态和配置,不直接 SSH 改节点。 * Agent 是唯一落地入口。 * 所有发布都是"新版本激活",不是在线覆盖编辑。 -* 第一版:所有节点默认拉同一份全量配置;第二版:可按节点分组差异化下发。 +* 第一版与第二版:所有节点默认拉同一份全量配置,不做节点分组差异化下发。 * 能用 SQLite 解决的问题,不引入额外中间件。 * 新功能优先复用现有 gin-template 结构,不平行造第二套框架。 @@ -134,7 +139,8 @@ Agent 放在 `atsf_agent`,使用 Go 单体程序开发。 第二版新增实体: -* `node_groups` — 节点分组 +* `tls_certificates` — 证书托管 +* `managed_domains` — 域名管理与证书绑定 * `agent_tokens` — Agent Token 管理 约束(全版本): @@ -142,9 +148,10 @@ Agent 放在 `atsf_agent`,使用 Go 单体程序开发。 * 不新增 `zone`、`origin_pool`、`policy`、`deployment` 这类平台化对象 * `proxy_routes` 一条域名只对应一个 `origin_url` * `config_versions` 必须保存完整快照和渲染后的 Nginx 路由配置 -* 同一分组内激活版本只能有一个;全量版本(group_id = null)全局只能有一个 +* 激活版本全局只能有一个,不引入分组维度 * 回滚通过"激活旧版本"实现,不直接修改历史记录 * `agent_tokens` 中的 Token 值不可更新,只能创建或撤销 +* 域名到证书匹配必须支持精确匹配和通配符匹配(如 `*.example.com`) 如需新增表,必须先证明它服务于当前迭代版本的主链路。 @@ -383,11 +390,12 @@ Server 新增覆盖: * HTTPS server 块渲染正确性(`enable_https=true` 时生成 443 块,`redirect_http=true` 时生成重定向块) * HTTP-only 路由渲染结果不受 HTTPS 字段影响 +* 证书导入逻辑(手动导入、文件导入)和 PEM 校验逻辑 +* 域名证书匹配逻辑(精确匹配与 `*.example.com` 通配符匹配) * `custom_headers` 注入到渲染结果的正确性 * `agent_tokens` 创建与查表验证逻辑 * Token 撤销后验证失败 * bootstrap Token 降级行为(数据库有 Token 时环境变量 Token 失效) -* 分组发布逻辑(group_id 筛选激活版本) * 预览接口不写库 * diff 接口变更摘要计算正确性 @@ -403,12 +411,13 @@ Server 新增覆盖: ### 10.4 联调验收标准(第二版) 1. 创建含 HTTPS 字段的路由并发布,Nginx 能以 HTTPS 正确转发 -2. 通过管理界面创建 Token,Agent 使用新 Token 成功访问 -3. 撤销 Token 后 Agent 请求返回 401 -4. 创建分组并按分组发布,不同分组节点拉到不同版本 -5. 路由配置自定义头后,渲染结果包含对应指令 -6. 发布页预览展示正确渲染结果 -7. 变更摘要正确列出域名变化 +2. 控制面可手动导入和文件导入证书,导入后可被路由选择 +3. 反代规则输入域名后可自动匹配证书,且支持 `*.example.com` +4. 通过管理界面创建 Token,Agent 使用新 Token 成功访问 +5. 撤销 Token 后 Agent 请求返回 401 +6. 路由配置自定义头后,渲染结果包含对应指令 +7. 发布页预览展示正确渲染结果 +8. 变更摘要正确列出域名变化 ## 11. 文档维护规范 diff --git a/docs/development-plan.md b/docs/development-plan.md index 850af0ae..9c21dfce 100644 --- a/docs/development-plan.md +++ b/docs/development-plan.md @@ -71,21 +71,47 @@ MVP 已于第一版完成。当前进入第二版迭代。 * 支持通过控制面配置 HTTPS 路由 * 渲染出包含 443 端口的 `server` 块 * 支持 HTTP → HTTPS 重定向块 +* 控制面支持托管证书 交付: -* `proxy_routes` 新增字段:`enable_https`、`ssl_cert_path`、`ssl_key_path`、`redirect_http` +* `proxy_routes` 新增字段:`enable_https`、`cert_id`、`redirect_http` * 渲染器支持 HTTPS server 块生成 * 前端反代规则页增加 HTTPS 配置表单 +* `tls_certificates` 表与模型 +* 证书导入能力:手动导入(粘贴 PEM)与文件导入 * AutoMigrate 覆盖新字段 完成标准: * 创建含 HTTPS 字段的路由并发布,Agent 拉取后 Nginx 能以 HTTPS 正确转发 * HTTP 重定向配置生效 +* 证书可通过控制面导入并被 HTTPS 路由引用 * 未开启 HTTPS 的路由渲染行为与第一版保持一致 -### V2 Phase 2: Agent Token 管理 +### V2 Phase 2: 域名管理与证书自动匹配 + +目标: + +* 控制面可管理域名并绑定证书 +* 反代规则编辑时按输入域名自动匹配证书 +* 支持 `*.example.com` 通配符证书匹配 + +交付: + +* `managed_domains` 表与模型 +* 域名管理 CRUD API +* 证书匹配 API(精确匹配 + 通配符匹配) +* 前端域名管理页 +* 前端反代规则页接入证书自动匹配 + +完成标准: + +* 创建域名并绑定证书后,反代规则输入域名可自动匹配证书 +* 通配符证书可匹配子域名(如 `api.example.com` 匹配 `*.example.com`) +* 无匹配证书时前端给出明确提示 + +### V2 Phase 3: Agent Token 管理 目标: @@ -107,30 +133,6 @@ MVP 已于第一版完成。当前进入第二版迭代。 * 撤销 Token 后 Agent 请求立即返回 401 * 全局环境变量 Token 仅在数据库无有效记录时生效 -### V2 Phase 3: 节点分组与差异化下发 - -目标: - -* 节点可按分组管理 -* 发布时可选择目标分组,生成分组专属版本 -* Agent 按分组拉取对应激活版本 - -交付: - -* `node_groups` 表与模型 -* `nodes` 新增 `group_id` 字段 -* `config_versions` 新增 `group_id` 字段(nullable,null 表示全量) -* 发布 API 接受可选 `group_id` 参数 -* Agent API 按节点分组返回对应激活版本 -* Agent `agent.json` 新增 `group_id` 配置项 -* 前端节点分组管理页与节点页分组字段 - -完成标准: - -* 同一系统内 staging 和 production 分组各有独立激活版本 -* staging 节点拉取 staging 版本,production 节点拉取 production 版本 -* 不属于任何分组的节点拉取全量(group_id = null)版本 - ### V2 Phase 4: 路由自定义头 目标: @@ -172,14 +174,14 @@ MVP 已于第一版完成。当前进入第二版迭代。 建议严格按以下顺序开发: 1. HTTPS/TLS 支持(对现有渲染链路影响最小,独立可测) -2. Agent Token 管理(安全性改善,早做早稳) -3. 节点分组(数据模型扩展,影响面最广,需要 Agent 配合) +2. 域名管理与证书自动匹配(与 HTTPS 强相关,尽早完成闭环) +3. Agent Token 管理(安全性改善,早做早稳) 4. 路由自定义头(纯增量,对现有结构影响小) 5. 配置预览与变更摘要(纯只读接口,最后补充) 不要先做以下内容: -* 证书托管 +* 节点分组与差异化下发 * 灰度百分比发布 * WAF、限流 * Redis、Prometheus @@ -191,23 +193,23 @@ MVP 已于第一版完成。当前进入第二版迭代。 * `enable_https=true` 的路由发布后生成 443 端口 server 块 * `redirect_http=true` 的路由生成 80 → 443 重定向块 +* 支持手动导入证书与文件导入证书 * 未开启 HTTPS 的路由渲染结果不受影响 * Agent 拉取后 Nginx reload 成功 ### V2 Phase 2 检查项 +* 可通过管理界面维护域名并绑定证书 +* 反代规则输入域名后可自动匹配证书 +* 通配符证书可匹配子域名(`*.example.com`) + +### V2 Phase 3 检查项 + * 可通过管理界面创建 Token * 新 Token 可被 Agent 使用 * 撤销 Token 后访问立即失败 * 全局 Token 环境变量在数据库有记录时失效 -### V2 Phase 3 检查项 - -* 可创建分组并将节点归入分组 -* 可发布面向指定分组的版本 -* 分组节点只拉取该分组的激活版本 -* 无分组节点拉取全量激活版本 - ### V2 Phase 4 检查项 * 路由可添加自定义头