feat: 证书探测改走国内机真 Node —— Workers 拿不到证书正文的兜底方案

根因:Workers 上 cloudflare:sockets 没有 getPeerCertificate,
node:tls 的同名方法是桩函数(调用即抛 not implemented)。

- editor-api 新增 /ssl-probe 本地端点(真 Node,读对端证书正文):
  不外发、不落盘;ssl 白名单放行,admin/ssl 可用,editor/匿名拒绝
- certprobe 改两级:首选国内机(带 X-Editor-Token),失败自动降级本地握手
- certProbe/certCheck 接线 EDITOR_API_BASE + EDITOR_TOKEN,撤掉 ?debug 诊断
- wrangler.toml 显式开 nodejs_compat(compat date 早于默认启用阈值)
- 手写 node:tls 最小类型声明(保持零依赖)
- seed-ssl-config.mjs 净化:真实凭据移到 secrets-backup/certkeeper-seeds.json,
  TOKEN_SECRET 改从 .dev.vars 读;脚本本体不含任何凭据
- role-perm 新增第 9 节 12 项(59/59),UI 探测 37 项全过
This commit is contained in:
zqlit committed 2026-10-06 15:55:22 +08:00
1 parent a40a92f526
commit 432cf5e398
9 files changed
+688 -63

No files matched your search

+4 -2
View File
@@ -404,7 +404,9 @@ export async function certProbe(ctx: Ctx): Promise<Response> {
}
if (!host) return fail(400, '缺少 host 参数(或指定的域名没有可探测的 SAN)');
const info = await probeTls(host);
// ★ 探测走国内机 editor-api:Workers 拿不到对端证书正文(node:tls 是桩函数),
// 本机是真 Node 才行。传 base + 共享令牌,失败时 probeTls 内部自动降级。
const info = await probeTls(host, 8000, ctx.env.EDITOR_API_BASE, ctx.env.EDITOR_TOKEN);
if (!info.ok) {
await log(ctx, a.ident, 'probe', `探测 ${host} 失败:${info.error || '未知原因'}`, 'warn', domain || host);
}
@@ -480,7 +482,7 @@ export async function certCheck(ctx: Ctx): Promise<Response> {
const rec = await getCert(ctx.env, d.name);
const storedLeft = daysLeft(rec?.expireAt);
const host = d.san.find((s) => !s.startsWith('*.')) || d.name;
const live = await probeTls(host);
const live = await probeTls(host, 8000, ctx.env.EDITOR_API_BASE, ctx.env.EDITOR_TOKEN);
let verdict = 'unknown';
if (!live.ok) verdict = 'unreachable';