From 082c458897dee3c328bc21648e8a9369772c63fc Mon Sep 17 00:00:00 2001 From: gdz66601 Date: Sat, 19 Sep 2026 08:48:20 +0800 Subject: [PATCH] docs: prefer Cloudflare dashboard configuration --- .env.example | 2 +- DEPLOYMENT.md | 87 +++++++++++++++++++++++++++++++++++++--------- README.md | 42 +++++++++------------- docs/ZERO_TRUST.md | 28 +++++++-------- 4 files changed, 101 insertions(+), 58 deletions(-) diff --git a/.env.example b/.env.example index 870eee4..ebce43e 100644 --- a/.env.example +++ b/.env.example @@ -3,4 +3,4 @@ CONNECT_TIMEOUT_MS=10000 # Zero Trust 团队域名(不带 https://)及此应用的 audience,不能使用测试绕过开关。 ACCESS_TEAM_DOMAIN=your-team.cloudflareaccess.com ACCESS_AUD=your-access-application-audience -# ENCRYPTION_KEY 必须为 32 字节安全随机数的 Base64;本地写入 .dev.vars,生产使用 wrangler secret put。 +# ENCRYPTION_KEY 必须为 32 字节安全随机数的 Base64;本文件只用于本地开发,生产值在 Cloudflare Worker 控制台中保存为 Secret。 diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index 068ff0b..b86e7b3 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -13,23 +13,78 @@ ## 必需配置 -| 名称 | 配置方式 | 含义 | +| 名称 | 配置位置 | 含义 | | --- | --- | --- | -| `DB` | D1 binding | `edgessh-accounts` 数据库,优先复用已有资源 | -| `ACCESS_TEAM_DOMAIN` | **Worker Secret** | 团队域名,例如 `my-team.cloudflareaccess.com`,不含协议或路径 | -| `ACCESS_AUD` | **Worker Secret** | 此 Access 应用的 Application Audience (AUD) Tag | -| `ENCRYPTION_KEY` | **Worker Secret** | 32 字节安全随机数的标准 Base64 | -| `SSH_SESSIONS` | Durable Object binding | 保留上游 DO 类及迁移历史 | +| `DB` | `wrangler.toml` 的 D1 binding | 主机资料数据库,优先复用已有资源 | +| `SSH_SESSIONS` | `wrangler.toml` 的 Durable Object binding | SSH 会话隔离,保留现有类名及迁移历史 | +| `ASSETS` | `wrangler.toml` 的静态资源 binding | 前端构建产物,不需要手动创建 | +| `ACCESS_TEAM_DOMAIN` | Cloudflare Worker Secret | 团队域名,例如 `my-team.cloudflareaccess.com`,不含协议或路径 | +| `ACCESS_AUD` | Cloudflare Worker Secret | 此 Access 应用的 Application Audience (AUD) Tag | +| `ENCRYPTION_KEY` | Cloudflare Worker Secret | 32 字节安全随机数的标准 Base64 | +| `CONNECT_TIMEOUT_MS` | 可选普通变量 | 建连超时;仓库默认 `10000`,通常不要额外配置 | -### 部署顺序 +`DB`、`SSH_SESSIONS` 与 `ASSETS` 是绑定,不是环境变量。生产环境实际需要手动填写的运行时值只有三个 Worker Secret。 -1. 检查 Cloudflare 已有 Worker、D1;确认目标应用为本项目,避免覆盖其他项目。不自动读取或配置 Zero Trust。 -2. 复用或创建 `edgessh-accounts`,将目标环境的真实 `database_id` 写入 `wrangler.toml`;仓库当前配置的是线上数据库。 -3. Zero Trust 应用、域名及单管理员 Allow 策略由用户自行配置,本项目部署过程不代为创建或修改。 -4. 用户配置 Access 后,分别通过 `wrangler secret put ACCESS_TEAM_DOMAIN` 与 `wrangler secret put ACCESS_AUD` 注入。所有账号、主机与连接 API 均需 Access 保护;`workers.dev` 只允许固定测试 IP 的无敏感信息诊断。缺少这两个 Secret 时可先部署,但受保护 API 会返回 503,不能操作主机或连接 SSH。 -5. **只在首次部署时生成密钥**,通过标准输入执行 `wrangler secret put ENCRYPTION_KEY` 注入。不要在命令参数、源码、日志或明文配置里输出密钥。已有 Secret 必须复用,不可随意覆盖。 -6. 执行 `npx wrangler d1 migrations apply DB --remote`,仅添加 schema,不清空或重置数据。 -7. 执行 `npm run check`,然后 `npm run deploy`,通过实际 Access 入口验收。 +## Cloudflare 控制台配置 + +### 1. 创建 D1 数据库 + +1. 打开 Cloudflare Dashboard 的 D1 页面;新版界面通常位于 `Storage & databases > D1`,菜单名称可能随控制台更新而变化。 +2. 复用本项目已有数据库,或创建一个新的数据库;不要为每次部署重复创建。 +3. 将数据库名称和 ID 写入 `wrangler.toml` 的 `[[d1_databases]]`,binding 保持为 `DB`。 +4. 数据表不需要在控制台手动建立。GitHub Actions 会执行远程 migration,只添加项目所需 schema,不清空已有数据。 + +### 2. 配置 Zero Trust Access + +1. 进入 `Zero Trust > Access > Applications`,添加一个 `Self-hosted` 应用。 +2. 应用域名填写最终访问 EdgeSSH 的自定义域名,并保证该域名与 `wrangler.toml` 的 route 一致。 +3. 添加 Allow 策略,只包含管理员的明确邮箱或身份。不要使用 `Everyone`、`Bypass` 或允许整个邮箱域的宽泛规则。 +4. 在 Zero Trust 的团队设置中找到 Team Domain,保存不带 `https://` 和路径的域名,例如 `my-team.cloudflareaccess.com`。 +5. 在 Access 应用详情中复制 Application Audience (AUD) Tag。不要把应用 ID、Client ID 或策略 ID 当作 AUD。 + +### 3. 创建部署用 API Token + +1. 在 Cloudflare 个人资料的 `API Tokens` 页面创建 Token,选择官方 `Edit Cloudflare Workers` 模板作为起点。 +2. 在模板权限之外补充 Account 的 `D1: Edit`,供 workflow 执行远程 migration。 +3. 保留模板中的 Worker 与目标 Zone 权限,用于部署脚本及 `custom_domain = true` 的自定义域名;不需要添加 KV、R2 等本项目未使用资源的额外权限。 +4. Account Resources 和 Zone Resources 都只选择实际部署所用的账户与域名,不要使用全账户、全站点范围。 +5. Token 创建后只会完整显示一次,将它直接保存为 GitHub Actions Secret,不要写进仓库或 Cloudflare Worker 变量。 + +Cloudflare 账户 ID 可在 Dashboard 的账户概览或 Worker 概览中复制。它不是 Secret,可保存为 GitHub Actions Variable。 + +### 4. 配置 GitHub Actions + +在 GitHub 仓库进入 `Settings > Secrets and variables > Actions`: + +| 名称 | GitHub 类型 | 值 | +| --- | --- | --- | +| `CLOUDFLARE_ACCOUNT_ID` | Variable | Cloudflare 账户 ID | +| `CLOUDFLARE_API_TOKEN` | Secret | 上一步创建的最小权限 API Token | + +进入 `Actions > Deploy > Run workflow` 完成首次部署。workflow 会安装依赖、检查项目、迁移 D1 并创建或更新 Worker。首次运行时尚未配置运行时 Secret,受保护 API 暂时返回 503 属于预期现象。 + +### 5. 在 Worker 界面添加运行时 Secret + +首次部署完成后,进入 `Workers & Pages > edgessh > Settings > Variables and Secrets`,依次添加以下三项,并将类型选择为 **Secret**: + +| 名称 | 填写内容 | +| --- | --- | +| `ACCESS_TEAM_DOMAIN` | Zero Trust Team Domain,不带协议和路径 | +| `ACCESS_AUD` | Access 应用详情中的 Application Audience (AUD) Tag | +| `ENCRYPTION_KEY` | 32 字节安全随机数的标准 Base64,只在首次部署时生成 | + +保存后按控制台提示部署新版本。不要在 GitHub Actions 中重复保存这三项,也不要为 `DB`、`SSH_SESSIONS` 或 `ASSETS` 创建同名变量。`CONNECT_TIMEOUT_MS` 已由 `wrangler.toml` 设置为 `10000`,只有确实需要调整 2,000 至 30,000 毫秒的建连超时时才在配置中修改。 + +`ENCRYPTION_KEY` 应由可信的密码管理器或本机安全随机数工具生成,解码后必须正好为 32 字节。不要使用普通密码、UUID、示例值或在线随机字符串网页。密钥丢失将无法解密现有资料;当前版本不支持直接轮换,后续部署必须复用原值。 + +## 部署顺序 + +1. 检查 Cloudflare 已有 Worker、D1 与 Access 应用,确认资源属于本项目,避免覆盖其他项目。 +2. 配置 D1、Access 与最小权限 API Token,再将两个部署值保存到 GitHub Actions。 +3. 手动运行一次 `Deploy` workflow,让 GitHub Actions 自动迁移 D1 并创建或更新 Worker。 +4. 在 Worker 的 `Variables and Secrets` 界面添加三个运行时 Secret,保存并部署。 +5. 以后只需推送到 `main`;workflow 会复用原有资源和 Secret 自动发布,不需要在本地执行 Wrangler 部署命令。 +6. 通过实际 Access 入口验收。所有账号、主机与连接 API 均需 Access 保护;缺少 Access Secret 时会返回 503,不能操作主机或连接 SSH。 密钥丢失将无法解密现有资料。更换密钥必须设计旧密钥解密、新密钥重加密的迁移,不可直接覆盖 Secret。当前版本不提供自动轮换。更换 Access 团队或身份导致 `sub` 改变时,也需要显式的数据迁移。 @@ -44,7 +99,7 @@ | `CLOUDFLARE_ACCOUNT_ID` | Actions Variable | 目标 Cloudflare 账户 ID | | `CLOUDFLARE_API_TOKEN` | Actions Secret | 限定到目标账户,并具备 Workers 部署与 D1 迁移权限 | -三个运行时 Worker Secret 不进入 GitHub Actions。首次部署或主动轮换时仍使用 `wrangler secret put` 单独管理;日常自动部署只复用 Cloudflare 中已有值。 +三个运行时 Worker Secret 不进入 GitHub Actions,统一在 Cloudflare Worker 的 `Variables and Secrets` 界面管理;日常自动部署只复用 Cloudflare 中已有值。不要把本地 `.dev.vars` 或 `wrangler secret put` 作为普通用户的生产配置流程。 ## 验收清单(5.6 SOL 执行) @@ -83,4 +138,4 @@ - 正式入口:`https://ssh.dltwcnm.ccwu.cc` - `workers.dev` 作为诊断入口保留;Worker 仍在应用层强制校验所有生产账号与连接 API,不允许绕过自定义域名上的 Access 策略。 -- Access 应用与策略由用户在 Cloudflare 控制台维护;部署流程只注入 Team Domain 与应用 AUD。 +- Access 应用、策略与三个运行时 Secret 均由用户在 Cloudflare 控制台维护;GitHub Actions 只负责迁移与部署代码。 diff --git a/README.md b/README.md index b0fe508..877f74a 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ SSH 握手、密钥交换、认证与通道逻辑在 Worker 内完成。浏览 EdgeSSH 没有独立的本地登录系统,正式入口必须先经过 Cloudflare Zero Trust Access。首次部署时请先完成: 1. 在 **Zero Trust > Access controls(访问控制)> Applications(应用程序)** 创建 **Self-hosted and private(自托管和私有)** 应用,并绑定 EdgeSSH 的自定义域名。 -2. 添加一条 **Allow(允许)** 策略,使用 **Include> Emails** 明确填写管理员邮箱;不要使用 `Everyone(所有人)` 或 `Bypass(绕过)`。 +2. 添加一条 **Allow(允许)** 策略,使用 **Include > Emails** 明确填写管理员邮箱;不要使用 `Everyone(所有人)` 或 `Bypass(绕过)`。 3. 选择 **Identity Provider(标识提供程序)**。个人部署可使用 **One-time PIN(一次性 PIN)**;新建 Zero Trust 组织若没有该选项,需要先到 **Integrations(集成)> Identity providers(标识提供程序)** 手动添加。 4. 从 Access 应用中取得 **Application Audience (AUD) Tag(应用程序受众 (AUD) 标签)**,并从 Zero Trust **Settings(设置)** 取得 **Team Domain(团队域)**。 5. 将它们分别写入 `ACCESS_AUD` 与 `ACCESS_TEAM_DOMAIN` Worker Secret。 @@ -129,32 +129,24 @@ npm ci > [!IMPORTANT] > 本项目面向**单管理员**使用。Access 策略应仅允许管理员的明确身份,不要配置 Everyone 或 Bypass。缺少 Access 配置时,受保护 API 会拒绝访问,不会降级为匿名网关。 -1. 调整 `wrangler.toml` 中的 Worker 名称、自定义域名与 D1 绑定,**不要直接使用仓库中原部署环境的资源 ID**。 -2. 复用已有 D1 或创建自己的数据库,将其绑定为 `DB`,保留 Durable Object 类与迁移配置。 -3. 创建并配置 Access 应用,通过 Wrangler 注入下列 Secret。 -4. 应用数据库迁移,完成检查后部署。 +1. 在 Cloudflare 控制台复用或创建 D1 数据库,并调整 `wrangler.toml` 中的 Worker 名称、自定义域名与 D1 `database_id`,**不要直接使用仓库中原部署环境的资源 ID**。 +2. 在 Zero Trust 控制台创建 Self-hosted Access 应用,只允许管理员的明确邮箱或身份,并记下 Team Domain 与 Application Audience (AUD) Tag。 +3. 在 GitHub 配置一个 Actions Variable 和一个 Actions Secret,首次运行 `Deploy` workflow;它会自动检查项目、迁移 D1 并创建或更新 Worker。 +4. Worker 首次出现后,在 Cloudflare 控制台的 `Workers & Pages > 你的 Worker(默认 edgessh)> Settings > Variables and Secrets` 中添加三个运行时 Secret。保存并部署这些设置后即可通过 Access 入口验收。 -| 配置 | 用途 | -| --- | --- | -| `DB` | 保存加密主机资料的 D1 绑定 | -| `SSH_SESSIONS` | 隔离 SSH 会话的 Durable Object 绑定 | -| `ASSETS` | 提供前端静态资源 | -| `ACCESS_TEAM_DOMAIN` | Access 团队域名,通过 Secret 注入 | -| `ACCESS_AUD` | Access 应用 Audience,通过 Secret 注入 | -| `ENCRYPTION_KEY` | 32 字节安全随机密钥的标准 Base64,通过 Secret 注入 | -| `CONNECT_TIMEOUT_MS` | TCP 建连超时,默认 `10000` 毫秒 | +| 配置 | 类型与位置 | 用途 | +| --- | --- | --- | +| `DB` | `wrangler.toml` 中的 D1 binding | 保存加密主机资料 | +| `SSH_SESSIONS` | `wrangler.toml` 中的 Durable Object binding | 隔离 SSH 会话 | +| `ASSETS` | `wrangler.toml` 中的静态资源 binding | 提供前端资源 | +| `ACCESS_TEAM_DOMAIN` | Cloudflare Worker Secret | Access 团队域名,如 `my-team.cloudflareaccess.com`,不含协议和路径 | +| `ACCESS_AUD` | Cloudflare Worker Secret | Access 应用的 Application Audience (AUD) Tag | +| `ENCRYPTION_KEY` | Cloudflare Worker Secret | 32 字节安全随机密钥的标准 Base64 | +| `CONNECT_TIMEOUT_MS` | 可选普通变量 | TCP 建连超时;仓库已设为 `10000`,通常无需填写 | -```bash -npx wrangler login -npx wrangler secret put ACCESS_TEAM_DOMAIN -npx wrangler secret put ACCESS_AUD -npx wrangler secret put ENCRYPTION_KEY -npx wrangler d1 migrations apply DB --remote -npm run check -npm run deploy -``` +生产运行时只需在 Cloudflare 控制台填写 `ACCESS_TEAM_DOMAIN`、`ACCESS_AUD` 与 `ENCRYPTION_KEY` 三个 Worker Secret。`DB`、`SSH_SESSIONS` 与 `ASSETS` 是部署时创建的绑定,不是环境变量;`CONNECT_TIMEOUT_MS` 已有默认配置,也无需重复添加。 -**首次部署才生成加密密钥,后续部署复用已有 Secret。** 丢失或直接替换密钥会导致已有资料无法解密。密钥不要写入源码、配置文件或提交记录。 +**首次部署才生成 `ENCRYPTION_KEY`,后续部署始终复用原值。** 丢失或直接替换密钥会导致已有资料无法解密。密钥只粘贴到 Cloudflare 的 Secret 输入框,不要写入源码、`wrangler.toml`、GitHub Actions 或提交记录。 完整配置顺序、安全边界与验收清单见 [部署指南](DEPLOYMENT.md)。 @@ -167,7 +159,7 @@ npm run deploy | `CLOUDFLARE_ACCOUNT_ID` | Variable | Cloudflare 账户 ID | | `CLOUDFLARE_API_TOKEN` | Secret | 具备 Workers 部署和 D1 迁移权限的 API Token | -Action 只需要这两项部署凭据。`ACCESS_TEAM_DOMAIN`、`ACCESS_AUD` 与 `ENCRYPTION_KEY` 继续作为 Worker Secret 保存在 Cloudflare,普通部署不会读取或覆盖它们。API Token 属于敏感信息,必须使用 GitHub Secret,不能保存为普通 Variable。 +Action 只需要这两项部署凭据。创建 API Token 时,可使用 Cloudflare 的 `Edit Cloudflare Workers` 模板并补充 `D1: Edit`,再将 Account 与 Zone Resources 限制到实际使用的账户和域名;该模板会覆盖 Worker 与自定义域名部署所需权限。`ACCESS_TEAM_DOMAIN`、`ACCESS_AUD` 与 `ENCRYPTION_KEY` 只保存在 Cloudflare Worker Secrets 中,普通部署不会读取或覆盖它们。API Token 属于敏感信息,必须使用 GitHub Secret,不能保存为普通 Variable。 ## 本地开发 diff --git a/docs/ZERO_TRUST.md b/docs/ZERO_TRUST.md index 414486f..ed5d723 100644 --- a/docs/ZERO_TRUST.md +++ b/docs/ZERO_TRUST.md @@ -113,24 +113,20 @@ my-team.cloudflareaccess.com Cloudflare 官方获取 AUD 的说明: https://developers.cloudflare.com/cloudflare-one/access-controls/applications/http-apps/authorization-cookie/validating-json/ -## 写入 Worker Secret +## 在 Cloudflare 控制台保存 Worker Secret -在 EdgeSSH 项目目录运行: +先按 [部署指南](../DEPLOYMENT.md) 配置 GitHub Actions,并手动运行一次 `Deploy` workflow。首次部署完成、Worker 出现在 Cloudflare 后: -```bash -npx wrangler secret put ACCESS_TEAM_DOMAIN -npx wrangler secret put ACCESS_AUD -``` +1. 打开 Cloudflare Dashboard,进入 `Workers & Pages`。 +2. 选择你的 EdgeSSH Worker(默认名称为 `edgessh`)。 +3. 进入 `Settings(设置)> Variables and Secrets(变量与机密)`。 +4. 添加 `ACCESS_TEAM_DOMAIN`,类型选择 **Secret**,粘贴前面取得的 Team Domain。 +5. 添加 `ACCESS_AUD`,类型选择 **Secret**,粘贴前面取得的 Application Audience (AUD) Tag。 +6. 按控制台提示保存并部署新版本。 -分别粘贴刚才取得的值。 +不要把这两个值保存为 GitHub Actions Secret。GitHub Actions 只需要 `CLOUDFLARE_ACCOUNT_ID` 和 `CLOUDFLARE_API_TOKEN` 两项部署凭据;Access 参数属于 Worker 运行时 Secret,应始终留在 Cloudflare 中。 -然后继续完成项目部署: - -```bash -npx wrangler d1 migrations apply DB --remote -npm run check -npm run deploy -``` +EdgeSSH 还需要一个 `ENCRYPTION_KEY` Worker Secret。它与上述两项在同一个控制台页面配置,生成要求和密钥保管注意事项见 [部署指南](../DEPLOYMENT.md#5-在-worker-界面添加运行时-secret)。生产部署不需要在本地执行 Wrangler Secret 或 Worker 部署命令。 ## 验证配置 @@ -148,9 +144,9 @@ npm run deploy 检查: -- `ACCESS_TEAM_DOMAIN` 是否已经通过 Wrangler Secret 写入。 +- `ACCESS_TEAM_DOMAIN` 是否已经在 Worker 的 `Variables and Secrets` 页面保存为 Secret,并部署到当前版本。 - Team Domain 是否为 `xxx.cloudflareaccess.com`,且没有 `https://`。 -- `ACCESS_AUD` 是否已经写入。 +- `ACCESS_AUD` 是否已在同一页面保存为 Secret,且值来自当前 Access 应用。 ### 登录后提示“Access 登录已失效”