fix(relay-run): agent-TLS ca must be full chain (intermediate+root), not intermediate-only
Node/OpenSSL rejects an agent client leaf whose only trust anchor is a non-self-signed intermediate (no PARTIAL_CHAIN flag) → every agent was reset at the TLS layer before attach(), surfacing as a silent 1006. Pass the full agent-ca bundle and stop swallowing tlsClientError.
This commit is contained in:
@@ -205,7 +205,11 @@ async function main(): Promise<void> {
|
||||
resolver,
|
||||
mtls: mtlsBridge.sync,
|
||||
now,
|
||||
caBundle: [readFileSync(agentCaCertPath)],
|
||||
// Agent-TLS trust store for validating the agent's CLIENT leaf (requestCert+rejectUnauthorized).
|
||||
// MUST be the FULL chain (intermediate + self-signed root): Node/OpenSSL rejects a leaf whose only
|
||||
// anchor is a non-self-signed intermediate (no PARTIAL_CHAIN flag). Intermediate-only ⇒ every agent
|
||||
// is reset at the TLS layer before attach() runs.
|
||||
caBundle: [readFileSync(agentCaChainPath)],
|
||||
onError: (e) => console.error('[data-plane]', errText(e)),
|
||||
tlsServerFactory: mtlsBridge.wrap(agentTlsFactory),
|
||||
})
|
||||
|
||||
@@ -37,6 +37,11 @@ export function makeAgentTlsServerFactory(opts: AgentTlsOptions): TlsServerFacto
|
||||
const der = peer && peer.raw ? new Uint8Array(peer.raw) : new Uint8Array()
|
||||
onPeer(wsToWebSocketLike(ws), der)
|
||||
})
|
||||
wss.on('error', (e) => opts.onError?.(e))
|
||||
// Surface TLS-layer client failures (e.g. a client leaf that doesn't chain to `ca`). Node
|
||||
// otherwise SWALLOWS 'tlsClientError' — the peer just sees an abrupt reset with no server signal,
|
||||
// which is exactly what masked the intermediate-only-CA bug.
|
||||
server.on('tlsClientError', (e) => opts.onError?.(e))
|
||||
server.on('error', (e) => opts.onError?.(e))
|
||||
server.listen(opts.bindPort, opts.bindHost, () => opts.onListening?.())
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user