feat(web): relay --cert/--key for real TLS on one port - #3952
feat(web): relay --cert/--key for real TLS on one port#3952paul-nechifor wants to merge 1 commit into
Conversation
Greptile SummaryAdds operator-provided TLS certificates to the web relay and updates clients to verify those certificates. The TLS discovery response can advertise a localhost WebTransport address that does not reach the default IPv4-only QUIC listener. Confidence Score: 4/5Not safe to merge until TLS relay discovery consistently advertises an address that reaches the configured QUIC listener. A reproduced relay discovery failure prevents the cockpit from connecting when localhost is selected but resolves to IPv6 before the relay's IPv4-only listener. The earlier listener-cleanup thread was manually resolved by paul-nechifor without explanation. Files Needing Attention: web/relay/server.ts
What T-Rex did
Important Files Changed
|
Codecov Report❌ Patch coverage is
@@ Coverage Diff @@
## paul/feat/t12b-robot-picker #3952 +/- ##
===============================================================
+ Coverage 78.01% 78.04% +0.02%
===============================================================
Files 1413 1413
Lines 133568 133681 +113
Branches 11572 11573 +1
===============================================================
+ Hits 104207 104334 +127
+ Misses 26079 26068 -11
+ Partials 3282 3279 -3
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 1 file with indirect coverage changes 🚀 New features to boost your workflow:
|
With --cert/--key the relay terminates TLS itself: HTTPS on --port, QUIC on the same port, /api/info advertises the origin the client dialed and no certHash (the ready line omits it too). Without them nothing changes. The SDK pins a hash only when one is advertised. The bridge verifies normally: RelayClient.connect defaults the port to 443, GlobalConfig.relay_ca (--relay-ca) is a PEM CA bundle used for both the /api/info fetch and aioquic, and a TLS alert during the handshake is logged because aioquic surfaces it as a bare ConnectionError. RelayProcess takes cert/key paths, which also widen the child's --allow-read. Verified with the deno relay tests (h2 discovery and a hash-pinned hello on the shared port), vitest, pytest including a self-signed e2e, the browser e2e, and a manual private-CA relay: the bridge and Firefox (with network.http.http3.disable_when_third_party_roots_found=false) verify it; Chrome's QUIC stack rejects user-added roots (QUIC_CERT_ROOT_NOT_KNOWN), so Chrome needs a publicly trusted certificate.
f0d7460 to
aeffeb6
Compare
| const info = tls | ||
| ? { wtUrl: url.origin, v: PROTOCOL_VERSION } | ||
| : { wtUrl, certHash: cert.certHashB64, v: PROTOCOL_VERSION }; |
There was a problem hiding this comment.
TLS discovery selects localhost
If localhost resolves to both IPv4 and IPv6, requesting the TLS relay at https://localhost:<port>/api/info returns that localhost origin as wtUrl, even though the default HTTP and QUIC listeners bind only to 127.0.0.1. The browser can then try ::1, where no QUIC listener exists, so the cockpit's advertised WebTransport connection times out. Advertise the configured reachable host or bind both listeners on IPv6 before returning a localhost URL.
Knowledge Base Used: Web cockpit and relay transport
--certand--keyoptions to run the relay with a supplied TLS certificate. This enables HTTPS access to the cockpit from other machines.--relay-caso robots can trust certificates issued by a private certificate authority.