feat(backend): nodectl bootstrap-token 子命令 + 补全 REALITY snapshot 监听/handshake 字段
档 3 真机准备的后端代码部分: - nodectl 新增 bootstrap-token -node=<uuid> 子命令:复用 mtls.NewBootstrapTokenManager(rdb).IssueToken 签发 agent enroll 用的一次性 token,只读 Redis(REDIS_ADDR/REDIS_PASSWORD),stdout 仅打印 token 便于 部署脚本直接捕获。 - 修复 Register 下发的 ConfigSnapshot.Reality 缺字段:此前只填 PrivateKey/ ShortID/ServerName,而 agent 的 render.go 还要读 ListenPort/HandshakeServer/ HandshakePort——缺这三个会渲染出 listen_port:0 + 空 handshake 的无效 sing-box server 配置,隧道起不来。现从节点 endpoint 解析监听端口、以 reality_sni 作 handshake 目标:443 填齐,与 httpapi.BuildClientConfig 的客户端口径一致。 - 强化 TestRegister_OK 断言新字段(ListenPort/ServerName/HandshakeServer/ HandshakePort/PrivateKey),防止该缺口回归。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -466,9 +466,27 @@ func TestRegister_OK(t *testing.T) {
|
||||
if snap.ConfigVersion != 7 {
|
||||
t.Errorf("ConfigVersion=%d, want 7", snap.ConfigVersion)
|
||||
}
|
||||
// The mock store returns a node with RealityPBK set.
|
||||
// The mock store returns a node with RealityPBK set (endpoint 1.2.3.4:443,
|
||||
// SNI www.example.com). The snapshot must carry a renderable inbound: a
|
||||
// non-zero listen port (parsed from endpoint) and a handshake target, or the
|
||||
// agent's sing-box config is invalid.
|
||||
if snap.Reality == nil {
|
||||
t.Error("Reality is nil, want non-nil")
|
||||
t.Fatal("Reality is nil, want non-nil")
|
||||
}
|
||||
if snap.Reality.ListenPort != 443 {
|
||||
t.Errorf("Reality.ListenPort=%d, want 443 (from endpoint)", snap.Reality.ListenPort)
|
||||
}
|
||||
if snap.Reality.ServerName != "www.example.com" {
|
||||
t.Errorf("Reality.ServerName=%q, want www.example.com", snap.Reality.ServerName)
|
||||
}
|
||||
if snap.Reality.HandshakeServer != "www.example.com" {
|
||||
t.Errorf("Reality.HandshakeServer=%q, want www.example.com", snap.Reality.HandshakeServer)
|
||||
}
|
||||
if snap.Reality.HandshakePort != 443 {
|
||||
t.Errorf("Reality.HandshakePort=%d, want 443", snap.Reality.HandshakePort)
|
||||
}
|
||||
if snap.Reality.PrivateKey == "" {
|
||||
t.Error("Reality.PrivateKey is empty, want the node's REALITY key")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user