docs: log native mTLS reverse-tunnel — four tracks landed + two HIGH fixups

This commit is contained in:
Yaojia Wang
2026-07-07 09:43:35 +02:00
parent d0c249c739
commit cb04516d52

View File

@@ -47,6 +47,17 @@
- **验证(实测)**: `npx tsc --noEmit` 全项目干净;`npx vitest run` **15 files / 101 tests pass** - **验证(实测)**: `npx tsc --noEmit` 全项目干净;`npx vitest run` **15 files / 101 tests pass**
- **偏差**: 手建 `control-plane/node_modules/relay-auth` 符号链接以配合新 file: 依赖(`npm install` 会重建)。**阻塞**: 无。 - **偏差**: 手建 `control-plane/node_modules/relay-auth` 符号链接以配合新 file: 依赖(`npm install` 会重建)。**阻塞**: 无。
### ✅ NATIVE-TUNNEL — 原生 mTLS 反向隧道:四轨代码全部落地(2026-07-07,分支 `feat/relay-phase1`,commits 5337281/e38e6d1/bb09495/d0c249c)
- **背景**: 原生 iOS/Android/桌面客户端讲 base-app 协议(非 E2E relay),需经用户 VPS 反向隧道(frp)回到本机 `127.0.0.1:3000`。**base app 无鉴权 → mTLS 客户端证书是唯一闸门**。总计划见 [PLAN_NATIVE_TUNNEL.md](./PLAN_NATIVE_TUNNEL.md)(Model A 单主人机队;LE 泛证书;frps 控制通道 mTLS+token;CRL 第一天上;`BIND_HOST=127.0.0.1` 强制)。
- **执行**: 两个后台 Workflow —— (1) build→review 四轨并行(8 agents,0 error,860k tok);(2) 修复两个 HIGH(2 agents,0 error,308k tok)。四轨文件互不相交(`ios/`·`desktop/`·`agent/`·`deploy/`),**零 `src/` 改动**(计划承诺兑现)。
- **各轨(全部已验证)**:
- **C-iOS `[x]`**: 新 `ios/Packages/ClientTLS`(SecIdentity 包装、PKCS12 导入含类型化错误、keychain 存储 `AfterFirstUnlockThisDeviceOnly`、纯 `MutualTLSChallengeResponder` 真值表、跨平台 X.509 DER 摘要)。两个 transport + SessionThumbnail 改**惰性 `@Sendable ()->ClientIdentity?` provider**(WS 每连接、HTTP 每证书挑战解析 → 装证书后免重启生效)。`ClientCertScreen``hostMenu` 的「设备证书」入口可达;PairingViewModel 对 `*.terminal.yaojia.wang` 无证书时挡探测、mTLS 拒绝重映射为 clientCertRejected。**验证**: ClientTLS 14/14、SessionCore 93/93、xcodegen+xcodebuild BUILD SUCCEEDED。
- **C-Desktop `[x]`**(D-1/D-2): `remote-hosts.ts` + DesktopPrefs(不可变、向后兼容)+ 托盘选择器;`will-navigate` 动态锁定选中远端 origin、null 失败关闭(无开放重定向);`select-client-certificate` handler `event.preventDefault()` 优先、按 issuer CN 选证、缺证弹框不静默。**验证**: `npm run typecheck` 干净。
- **S2 host-packaging `[x]`**: launchd 写 `<EnvironmentVariables>`、systemd 写 `EnvironmentFile`、originConfig zone 参数化(默认 `term` 保留);`InstallOptions` 从 CLI install → createCliDeps → installService seam → writers 全程贯通,生成单元携带 `BIND_HOST`(隧道机默认 `127.0.0.1`)/`ALLOWED_ORIGINS`/`PORT`/`SHELL_PATH`/`IDLE_TTL`/`USE_TMUX`;systemd 拒绝控制字符。**验证**: agent typecheck+build 干净、vitest **166/166**(154+12 新)。
- **V2/V7 VPS 脚本(可提交件)`[x]`**: `gen-device-ca.sh`(EC P-256,`--kind frp-client`)、`issue-device-cert.sh`(P-256 leaf,EKU=clientAuth only,.p12 `-legacy`+.pem,防 CSR 注入 serverAuth/CA:TRUE)、`revoke-device.sh`(CRL 强制)、`frp/{frps,frpc}` 模板(`disableCustomTLSFirstByte=true`)、`nginx/frp-mtls.conf`(:8470 TLS 终止 + `ssl_verify_client on` + `ssl_crl`,WS 升级代理 →:7080)、`nginx/stream-sni-additions.md`(两条加性 SNI map,合并式共存)。**验证**: tmp 目录跑通 gen→issue→`openssl verify`→revoke→CRL(OpenSSL 3.0.18);无密钥/证书误入库。
- **对抗式评审结论**: Desktop/VPS 直接 PASS;iOS/S2 各命中 1 个 HIGH(ClientCertScreen 无入口 / 环境注入未接到 install CLI)—— 均属跨 lane 收尾接线,已由第二个 Workflow 补齐并复验。
- **未做(下一步,串行 ops)**: **实机 VPS 部署**(装 frps + `acme.sh` LE 泛证书 + 生产 nginx `:8470`/SNI 两行)—— 触碰用户生产 nginx/xray/relay,不交给 agent,需操作者 ssh-agent 就绪后由主会话逐步执行(见 PLAN §6 MVP 快路径 V0→V6 / M1)。base app **零改动**;隧道启用前 **S-GATE 必须绿**(无证书 curl 必须被 TLS 拒)。
### ✅ 修复:底部快捷键栏遮挡终端内容(iOS 安全区,2026-07-06,main) ### ✅ 修复:底部快捷键栏遮挡终端内容(iOS 安全区,2026-07-06,main)
- **现象(用户截图,iPhone)**: 底部快捷键栏(Esc/Esc²/⇧Tab…)压住终端最后一行(Claude Code "bypass permissions" 提示行只露上半)。 - **现象(用户截图,iPhone)**: 底部快捷键栏(Esc/Esc²/⇧Tab…)压住终端最后一行(Claude Code "bypass permissions" 提示行只露上半)。
- **根因(`public/`)**: `index.html` 设了 `viewport-fit=cover`(布局铺满物理屏、延伸进刘海/Home 指示条),但 `style.css` **全程没有任何 `env(safe-area-inset-*)` 补偿**。于是 `#keybar`(`fixed; bottom:0; height:--keybar-h`)整条压进 Home 指示条区,而 `#term` 只预留了裸 `--keybar-h`,末行与键栏相撞。教科书级 cover-无-safe-area 缺陷。 - **根因(`public/`)**: `index.html` 设了 `viewport-fit=cover`(布局铺满物理屏、延伸进刘海/Home 指示条),但 `style.css` **全程没有任何 `env(safe-area-inset-*)` 补偿**。于是 `#keybar`(`fixed; bottom:0; height:--keybar-h`)整条压进 Home 指示条区,而 `#term` 只预留了裸 `--keybar-h`,末行与键栏相撞。教科书级 cover-无-safe-area 缺陷。