Drop the iframe wrapper page and fix two real certificate bugs
Video and audio no longer share one iframe-based /screen/<name> page. Firefox refuses to load iframe content signed by a certificate whose warning hasn't been accepted at the top level, with no way to click through inside the iframe (Chrome is more lenient, which is why this briefly looked fine there). "Open Screen" is now a plain top-level link straight to noVNC's own URL (new tab, normal Accept-the-Risk applies), and the "Enable Sound" toggle moved to the main setup page - meant to be left open in its own tab while playing. Because that page now hosts a persistent AudioContext/WebSocket, its auto-refresh no longer fires just because a game is running (only during active installs), since a full-page refresh would have killed that connection every 3s. Two real certificate bugs found and fixed along the way: - CN=NY (a meaningless placeholder) -> CN=localhost + SAN (DNS:localhost, IP:127.0.0.1). Firefox validates the WebSocket-Secure connection's cert against the hostname independently of the page load and rejected the CN mismatch there even after the page-level warning was accepted. - Worse: adding -addext without also pinning basicConstraints=CA:FALSE left the cert defaulting to CA:TRUE - i.e. flagged as a Certificate Authority, not a server cert. Firefox hard-refuses that with no override option at all (not a normal clickable warning), which is why "the warning appears but won't let me proceed" even after the CN fix. Fixed by explicitly setting basicConstraints=critical,CA:FALSE plus keyUsage/extendedKeyUsage=serverAuth. Confirmed fixed: Firefox now shows the same clickable self-signed warning Chrome always did, and the noVNC connection completes successfully after accepting it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NiNnj78HGx1KWyCCo39HSz
This commit is contained in:
@@ -92,9 +92,35 @@
|
||||
`server.sh` now starts `pulseaudio --start --exit-idle-time=-1` and the bridge
|
||||
(`pcm_ws_bridge.py 7199 parec --device=@DEFAULT_MONITOR@ ...`) once, before `exec`-ing
|
||||
`setup_server.py` — both live for the container's whole lifetime, independent of any
|
||||
game's start/stop. `setup_server.py` gained `GET /screen/<name>` (an iframe onto the
|
||||
game's noVNC screen plus an "Enable Sound" button — browsers require a user gesture
|
||||
before audio can start) and `GET /pcm-worklet.js`; the "Open Screen" link is now a plain
|
||||
same-origin relative link (`/screen/<name>`) instead of the old client-side-JS-built
|
||||
cross-port link, since the wrapper page itself now handles connecting to the right ports
|
||||
(reading the actual host from the request's own `Host:` header server-side).
|
||||
game's start/stop.
|
||||
|
||||
**No iframe, no per-game screen page** — tried an `<iframe>`-based `/screen/<name>` wrapper
|
||||
first (embedding noVNC + an Enable Sound button on one page), but Firefox refuses to load
|
||||
iframe content signed by a certificate whose warning hasn't been accepted at the top level,
|
||||
with no way to click through *inside* the iframe (Chrome is more lenient, which is why it
|
||||
briefly looked like it worked). Settled on: "Open Screen" is a plain top-level link straight
|
||||
to noVNC's own URL (opens in a new tab — normal "Accept the Risk and Continue" applies
|
||||
there), and the one "Enable Sound" toggle lives on the main setup page instead, meant to be
|
||||
left open in its own tab for as long as you're playing. Also regenerated the self-signed
|
||||
cert with `CN=localhost` + SAN (`DNS:localhost`, `IP:127.0.0.1`) instead of the old
|
||||
meaningless `CN=NY` — Firefox validates the WebSocket-Secure connection's cert against the
|
||||
hostname independently of the page load and was rejecting the CN mismatch there even after
|
||||
the page-level warning was accepted. Only fixes access via `localhost`/`127.0.0.1`; a LAN IP
|
||||
or other hostname would hit the same mismatch again, since a static cert can't cover every
|
||||
possible address in advance.
|
||||
|
||||
**A second, worse cert bug turned up right after**: adding `-addext` without also pinning
|
||||
`basicConstraints=CA:FALSE` left `openssl req -x509` defaulting to `CA:TRUE` — i.e. the
|
||||
generated cert claimed to be a Certificate Authority, not a normal server certificate.
|
||||
Firefox hard-refuses a CA-flagged cert used as a TLS server cert (not an overridable
|
||||
"Advanced -> Accept the Risk" warning, just a dead end), which is exactly why "the warning
|
||||
appears but won't let me proceed" even after the CN fix above. Chrome is lenient about this
|
||||
too, which is why it kept looking fine there. Fixed by explicitly setting
|
||||
`basicConstraints=critical,CA:FALSE`, `keyUsage=critical,digitalSignature,keyEncipherment`,
|
||||
and `extendedKeyUsage=serverAuth` in the same `openssl req -x509 -addext ...` call.
|
||||
|
||||
Because the setup page now hosts a persistent `AudioContext`/`WebSocket`, its
|
||||
`<meta http-equiv="refresh">` auto-refresh was narrowed to only fire while an install is
|
||||
actively in progress — it used to also refresh continuously whenever any game was running
|
||||
(to catch a crashed game's slot being freed), which would have torn down the live audio
|
||||
connection every 3 seconds.
|
||||
|
||||
Reference in New Issue
Block a user