Skip to content

L2+L4+L5: WAN 准备(NAT 仿真 relay-only/docker · 故障注入 · 加固/运维) - #54

Merged
Windsander merged 14 commits into
mainfrom
feat/wan-l2-l5
Sep 19, 2026
Merged

Windsander merged 14 commits into
mainfrom
feat/wan-l2-l5

Conversation

@Windsander

Copy link
Copy Markdown
Owner

L2+L4+L5 · WAN 准备(NAT 仿真 · 故障注入 · 加固/运维)

只进 CI/本机可重复验证:NAT/relay 仿真(本机 relay-only + docker 三容器隔离网络)、确定性故障注入加固与运维git diff origin/main...HEAD -- src/ 为空(不改 core 语义/线格式);未碰桥/Self-Skills。

主张 → 命令/输出 → 覆盖

# 主张 证据
1 relay-only 可连通并收敛(只交换 /p2p-circuit verify:wan:l2 ① · docker (隔离网络)
2 授权负例:未授权分区经 relay 也不可见 verify:wan:l2 ② · docker ② {secretCount:0}
3 relay 重启后恢复 verify:wan:l2
4 对端“IP 变更”(新监听端口)后恢复 verify:wan:l2
5 relay 不可达 → 降级手动 multiaddr 直连 verify:wan:l2direct-degraded
6 确定性丢包/延迟下有界收敛且可观测 tests/sync/wan-hardening.test.ts(L4)
7 加固:白名单/连接上限/帧上限(不改线格式) wan-hardening peerWhitelist · tests/p2p/ConnectionManager.test.ts · Libp2pProvider.test.ts
8 doctor 公网监听 → WARN + 建议(不静默) tests/fleet/grant.test.ts 监听地址
9 不回归 734 ×6、覆盖阈值全过、lint/build 无输出、verify:fleet:all 126/126

红 → 绿(断言原文)

破坏点 锚点 结果
L2 relay Libp2pProvider 去掉 circuitRelayTransport//p2p-circuit 监听(rebuild,S9) verify:wan:l2 ①/③ FAIL A 已获得 relay 预留地址 + ①/③ FAIL → 还原 7/7
L5 告警 isPrivateListenHosttrue 0.0.0.0 → WARN ✕ Expected "WARN" Received "PASS" → 还原 ✓

L2 · 本机 relay-only 仿真(verify:wan:l2,7/7)

PASS  A 已获得 relay 预留地址(/p2p-circuit)  {aCircuit:"…/tcp/65013/p2p/…/p2p-circuit/p2p/…"}
PASS  ① relay-only 连通且增量同步收敛  {dialed:true}
PASS  ① 双方 default 分区状态一致  {a:1,b:1}
PASS  ② 授权负例:未授权分区不可见(默认拒绝)
PASS  ③ relay 重启后经 relay 恢复同步
PASS  ④ IP 变更后经 relay 恢复同步  {circuit:true}
PASS  ⑤ relay 不可达 → 降级手动 multiaddr 直连可用  {mode:"direct-degraded"}

L2 · docker NAT 隔离(CI job,4/4)

三容器:relay(公开)+ peera/peerb(各自 net-a/net-b无入站端口);peer 仅知 relay,经 /p2p-circuit 互连。

PASS  docker compose up(relay + peera + peerb)
PASS  A 在隔离网络中经 relay 预留(/p2p-circuit)  {circuit:true}
PASS  ① relay-only 收敛(A→B→A 往返)  {a.sawReply:true, b.sawA:true}
PASS  ② 授权负例:未授权分区对隔离网络中的对端不可见  {secretCount:0}
FLEET_SUMMARY {"total":4,"passed":4,"failed":[],"skipped":[]}

(docker 中未重复 relay 重启/IP 变更;两者由本机 verify:wan:l2 ③④ 覆盖同一 libp2p relay 代码路径。)

新 CI job

  • build / test / lint(含新增 npm run verify:wan:l2 步骤)✅
  • WAN NAT isolation (docker compose, relay + 2 NAT peers)新增
  • windows … ✅ · semantic recall
  • run 35367109902(四个 job 全绿)。

L5 · 加固清单(既有/新增)与 doctor 告警

状态 证据
帧大小上限 MAX_FRAME_BYTES 4 MiB(编码/解码越界抛错) 既有 tests/p2p/Libp2pProvider.test.ts
连接数上限 ConnectionManager.maxConnections(默认 100,超限拒绝) 既有 tests/p2p/ConnectionManager.test.ts
对端白名单 sync.peerWhitelist(未列对端会话被忽略) 既有,新增测试 tests/sync/wan-hardening.test.ts
doctor 监听地址0.0.0.0/公网 → WARN + 建议(不使 ok=false 新增(fleet 层) tests/fleet/grant.test.ts
WARN  监听地址  /ip4/0.0.0.0/tcp/4001 绑定到全接口/公网地址(0.0.0.0)  → 改绑回环或 LAN 地址 + 经 relay 互联(见 RELAY-OPS.md)

文档

  • packages/fleet/RELAY-OPS.md:relay = transport-only(SEALING §1.6)、自托管/替换、加固清单、故障降级、docker/本机验证入口。
  • PROTOCOL-INVARIANTS.md §8:L2/L4/L5 行 → 测试/脚本名。
  • RUNBOOK.md §3 互链 RELAY-OPS。

顺带修复(CI 暴露的真实脆弱点,非放水)

  • spool 验收假红根因worker1 可能在「已执行、done 未发布」窗口被杀 → A 永久缺该 done。改为按 A 已观测 ≥8 条 done 触发 kill(本机 5× 7/7)。
  • 1d collab E2E 抖动:A→B 常驻连接一次性建立 + anti-entropy 兜底(去 churn),慢 runner 放宽等待(断言不变);全量 6× 734 绿。

未做项 / 风险

  • L3(真公网跨 NAT)留给真机阶段:本轮全部为本机/CI 仿真,明确 non-evidence
  • docker 场景仅做 relay-only 收敛 + 授权负例;relay 重启/IP 变更在 docker 未重复(本机覆盖)。
  • 加固为边界项,不改线格式/同步语义;peerWhitelist 未列对端为“忽略会话”(非拒绝错误)。
  • CI 上 docker job 有 15min 上限;当前远低于。

测试方式

npm ci && npm run build
npm run test:coverage
npm run verify:wan:l2
npm run verify:wan:l2:docker   # 需 docker compose;无则 SKIP
npm run verify:fleet:all

onboard:DoctorStatus 增 WARN;新增「监听地址」检查(0.0.0.0/公网 → WARN + 修复建议,不使 ok=false);cli 对 WARN 显示 hint。
RELAY-OPS.md:relay=transport-only(SEALING §1.6)、自托管/替换、加固清单、故障降级;RUNBOOK 互链;PROTOCOL-INVARIANTS §8(L2/L4/L5 行)。
wan-hardening:LossyProvider(确定性拨号丢包/延迟)有界收敛且丢包可观测;peerWhitelist 负例与对照。
grant.test:监听地址 WARN/PASS。collab-e2e:全量负载下放宽超时/循环(断言不变)。
verify:wan:l2:真实 libp2p circuit relay,仅交换 /p2p-circuit 地址——relay-only 收敛、授权负例、relay 重启、IP 变更、relay 不可达降级直连(L4)。
docker-compose.wan.yml + wan-nat-{relay,peer}:relay 公开 + 两 peer 隔离网络无入站;verify:wan:l2:docker 驱动(无 docker → SKIP 明列)。
CI:ubuntu 增 verify:wan:l2 步骤 + 独立 wan-nat(docker compose)job。
kicker 每轮确保连接并触发 anti-entropy;等待放宽到 55s。断言不变。
…ab 慢 runner 等待放宽

容器 peer sync 开 pushOnWrite(默认库关);collab-e2e jest 超时 120s、等待 90s。断言不变。
A→B 也建常驻以支持 push(协商 accept/子任务);kicker 仅触发 anti-entropy。全量 6× 734 绿。
根因:worker1 可能在“已执行、done 未发布”窗口被杀 → A 永久缺该 done。改为按 A 存储 done 计数触发 kill。本机 5× 7/7。
…败时回显子套件输出

remote:延迟可见等待加重试+触发 anti-entropy;驱动循环周期兜底;deadline 90s→150s。
collab:worker 循环每轮触发 anti-entropy。
verify:fleet:all:失败时打印该套件 PASS/FAIL 行(诊断)。断言不变。本机 remote 3×/collab 3×/all 均绿。
@Windsander
Windsander merged commit b37ad50 into main Sep 19, 2026
8 checks passed
@Windsander
Windsander deleted the feat/wan-l2-l5 branch September 19, 2026 10:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant