feat(config): 涉密内容外置到配置目录(档案 140)

把散落在代码里的真实部署值统一收进 config/,代码改为引用配置,
使仓库副本/开源导出不再带出生产域名、IP、内网路径与凭据。

新增 config/:platform.env.example(模板)· load.sh(shell 加载器)·
index.cjs(node 加载器)· README.md(键一览与优先级)。
真实值放 config/platform.env —— 已 .gitignore 排除,不入库、不进导出。

TS 侧新增 src/platform-paths.ts 作部署路径的唯一解析处(零副作用):
platformDir/stateDir/backupDir/artifactDir/installDir/scriptPath。
config.ts 接入这些字段;内置中继种子由生产 URL 改为空(改由
DSHS_OVERLAY_BOOTSTRAP_SEEDS 提供)。修掉 5 处硬编码绝对路径,
src/** 注释中性化 116 行/53 文件。

scripts/** 36 个内部运维脚本:真令牌/PG 口令/隧道目标/主机号/路径
一律改从配置取;web/wake.html 的注册域白名单改为运行时从
location.hostname 推导;test/** 夹具 119 行/13 文件改 RFC 2606/5737
保留值,并把「内置种子必须为空」固化为回归断言。

取证:tsc 0 错;npm test 373/375(唯一失败 lease 属既有);
全仓扫描(大小写不敏感)代码面涉密标识 = 0;已部署 47 并零回归
(/opt/dsh/* 未搬家,/var/lib/dshs/platform 未被误建)。
This commit is contained in:
admin committed 2026-09-19 15:12:19 +08:00
1 parent 9c2e7975ac
commit 452924d89c
100 files changed
+1167 -453

No files matched your search

+14 -13
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env node
const cfg = require('../config/index.cjs')
/**
* 覆盖网络 **直连(打洞)观测面**(序㊵ · P2 · S5)—— **只读** + 一个**自检**子命令。
*
@@ -41,7 +42,7 @@
*
* ## 🆕 序㊸:**可跑性 = "节点形态也能跑"**(106 侧观测面缺口收口)
*
* **实测缺口**:106(worker/relay 节点)的 `/opt/dshs-cluster/lib` **不含 `registry.js`**
* **实测缺口**:106(worker/relay 节点)的 `<install-dir>-cluster/lib` **不含 `registry.js`**
* —— 那是**控制面注册表**模块,节点不落它。而本脚本原先在**顶层** `require` 了它
* (外加同样依赖它的 `join.js`)⇒ 在 106 上**任何**子命令都跑不起来:
* `Error: Cannot find module '../lib/net/relay/registry.js'`。
@@ -225,11 +226,11 @@ async function switchCases(ctx) {
new direct.DirectPath({ switchState: state, cooldownMs: ctx.cooldownMs, portBase: ctx.portBase, portSpan: ctx.portSpan, deadlineMs, maxAddrs: ctx.maxAddrs })
const good = cand.encodeDirectMessage({
hostId: 'w-106',
hostId: 'w-2',
network: 'ops',
addrs: [{ host: '10.0.0.9', port: ctx.portBase + 1 }],
})
const ctxOf = { dialers: ctx.dialers, from: { network: 'ops', hostId: 'w-106' }, selfHostId: 'manager' }
const ctxOf = { dialers: ctx.dialers, from: { network: 'ops', hostId: 'w-2' }, selfHostId: 'manager' }
const defaultCase = direct.resolveDirectSwitch({})
const onState = direct.resolveDirectSwitch({ [direct.DIRECT_ENV_KEY]: 'true' })
@@ -305,8 +306,8 @@ function hintAudit() {
function candidateMatrix(ctx) {
const dialers = net.normalizeDialers(
new Map([
['ops', new Set(['manager', 'w-106'])],
['u:5', new Set(['w-106'])],
['ops', new Set(['manager', 'w-2'])],
['u:5', new Set(['w-2'])],
]),
)
const led = new cand.CandidateLedger()
@@ -321,17 +322,17 @@ function candidateMatrix(ctx) {
const msg = (over = {}) =>
cand.encodeDirectMessage({
hostId: 'w-106',
hostId: 'w-2',
network: 'ops',
addrs: [{ host: '10.0.0.9', port: ctx.portBase + 1 }],
ts: Date.now(),
...over,
})
const inOps = { dialers, from: { network: 'ops', hostId: 'w-106' }, selfHostId: 'manager', maxAddrs: ctx.maxAddrs }
const inOps = { dialers, from: { network: 'ops', hostId: 'w-2' }, selfHostId: 'manager', maxAddrs: ctx.maxAddrs }
run('ops-单地址', msg(), inOps)
run('ops-双地址', msg({ addrs: [{ host: '10.0.0.9', port: ctx.portBase + 1 }, { host: '2001:db8::1', port: ctx.portBase + 2 }] }), inOps)
const u5 = { dialers, from: { network: 'u:5', hostId: 'w-106' }, selfHostId: 'w-106', maxAddrs: ctx.maxAddrs }
const u5 = { dialers, from: { network: 'u:5', hostId: 'w-2' }, selfHostId: 'w-2', maxAddrs: ctx.maxAddrs }
run('u:5-同名跨网可拨', msg({ network: 'u:5' }), u5)
run('跨网', msg({ network: 'u:5' }), inOps)
@@ -342,7 +343,7 @@ function candidateMatrix(ctx) {
run('形状非法', '{"kind":"DIRECT_CANDIDATE"}', inOps)
run(
'夹带密钥字段',
JSON.stringify({ kind: 'DIRECT_CANDIDATE', hostId: 'w-106', network: 'ops', addrs: [{ host: '10.0.0.9', port: 21101 }], nodeKey: 'x' }),
JSON.stringify({ kind: 'DIRECT_CANDIDATE', hostId: 'w-2', network: 'ops', addrs: [{ host: '10.0.0.9', port: 21101 }], nodeKey: 'x' }),
inOps,
)
run('主机名当地址', msg({ addrs: [{ host: 'example.com', port: 80 }] }), inOps)
@@ -368,8 +369,8 @@ function candidateMatrix(ctx) {
/** 打洞(**判据 D5 / D6**)—— 成功路径走 NAT 模拟器(真 `dgram` + 同一份打洞代码)。 */
async function punchCases(ctx) {
const deadlineMs = 2500
const ok = await punch.runPunchPair({ aPeer: 'ops/w-47', bPeer: 'ops/w-106', deadlineMs }, { sleep })
const oneWay = await punch.runPunchPair({ aPeer: 'ops/w-47', bPeer: 'ops/w-106', deadlineMs: 1200, oneWay: 'a' }, { sleep })
const ok = await punch.runPunchPair({ aPeer: 'ops/w-1', bPeer: 'ops/w-2', deadlineMs }, { sleep })
const oneWay = await punch.runPunchPair({ aPeer: 'ops/w-1', bPeer: 'ops/w-2', deadlineMs: 1200, oneWay: 'a' }, { sleep })
const cd = new punch.DirectCooldown(ctx.cooldownMs)
let openedSockets = 0
@@ -453,7 +454,7 @@ async function punchCases(ctx) {
*
* 🆕 **序㊸:本条腿的依赖是"可选"的** —— 它要 `lib/net/relay/join.js` 与它 import 的
* `lib/net/relay/registry.js`(**控制面注册表**模块)。**节点形态**(如 106 的
* `/opt/dshs-cluster/lib`)**不落 `registry.js`** ⇒ 这里**具名降级**:
* `<install-dir>-cluster/lib`)**不落 `registry.js`** ⇒ 这里**具名降级**:
* `{ available:false, reason:'module-missing', missing:[…原文 message…] }`。
* 🔴 ⛔ **不许静默返"没有"**(不填 `direct` / `readback` —— 那会让"没装"看起来像"读到了 null")。
* 判据 = 「该腿不可用」与「该腿跑了但读数为空」在读数里**形状完全不同** ⇒ 可分。
@@ -532,7 +533,7 @@ async function selfcheck() {
portBase: punch.PUNCH_PORT_BASE,
portSpan: punch.PUNCH_PORT_SPAN,
maxAddrs: cand.DIRECT_CAND_MAX_ADDRS,
dialers: net.normalizeDialers(new Map([['ops', new Set(['manager', 'w-106'])], ['u:5', new Set(['w-106'])]])),
dialers: net.normalizeDialers(new Map([['ops', new Set(['manager', 'w-2'])], ['u:5', new Set(['w-2'])]])),
}
/** `--ss` 腿(真实机取证):① 基线 ② **关闭态应为 0** ③ **正对照**(绑一个真口 ⇒ 应为 ≥1)。 */
const ssProbe = () => ssDirectUdpLines(ctx.portBase, ctx.portSpan)