-
Notifications
You must be signed in to change notification settings - Fork 4
Web Client Requires HTTPS
The web client works over plain http://. Earlier releases refused to run
without HTTPS, and this page previously said that could not be changed. That was
wrong, and 1.0 fixes it.
HTTPS is still the better experience, and the difference is worth understanding before choosing.
HTTPS (or localhost) |
Plain HTTP | |
|---|---|---|
| Video | VP8, VP9, H.264, H.265, AV1 via WebCodecs | H.264 only, via Media Source Extensions |
| Hardware decoding | Yes | Depends on the browser's own H.264 pipeline |
| Per-frame statistics | Codec, FPS, bitrate, dropped frames | Not reported |
| Keyboard, mouse, file transfer, chat | Yes | Yes |
| Clipboard sync | Yes | Restricted by the browser |
The fallback is automatic. Nothing to configure and no separate URL — the client detects what the browser allows and picks the path.
Browsers restrict some APIs to a secure context — HTTPS, or localhost.
Two mattered here:
-
crypto.subtle(Web Crypto) — the login handshake hashes with SHA-256. -
VideoDecoder(WebCodecs) — the full-quality video pipeline.
Neither turned out to be a hard wall:
- The hash never needed Web Crypto. SHA-256 is small and well specified, and the client now carries its own implementation.
- Video does need a decoder, but WebCodecs is not the only one. Media Source
Extensions is not secure-context gated, and any browser that can play an MP4
can decode H.264 through it. The client muxes the incoming H.264 stream into
fragmented MP4 and hands it to a
<video>element.
The cost is real — one codec instead of five, and no per-frame numbers, because on that path nothing in the client ever sees an individual frame.
Yes, where you can. Better codec choice, hardware decoding, working clipboard sync, and the ordinary reasons an admin console should be encrypted: the session carries keystrokes and screen contents whichever path renders them.
The fallback is for where TLS genuinely is not available — an isolated LAN, a temporary deployment, a machine you cannot install a certificate on.
A self-signed certificate is not enough on its own: browsers only grant a secure context to a certificate they trust, so a self-signed cert has to be installed into the trust store of every machine that connects.
Options, roughly easiest first:
A real certificate for a name that resolves to a private address. This is
usually the least work and is widely misunderstood as impossible. Point a public
DNS name you own — console.example.com — at the LAN address (10.0.0.50), and
issue a certificate with a DNS-01 challenge,
which never requires the host to be reachable from the internet. You get a
browser-trusted certificate for a service that is only reachable internally, and
nothing has to be deployed to client machines.
A reverse proxy that handles certificates for you. Caddy does this in one line, and Traefik or nginx-proxy-manager are equivalent:
console.example.com {
reverse_proxy localhost:8080
}
Remember the web client also needs /ws/id and /ws/relay proxied with
WebSocket upgrade headers. Full configs for Caddy, Traefik and nginx are in
Reverse proxy and TLS.
An internal CA. If you already run one — AD Certificate Services, step-ca,
Smallstep — issue from it. The CA root is usually already trusted on managed
machines, which is what makes this painless where it applies and painful where
it does not.
Tailscale, or a similar overlay. Tailscale issues trusted certificates for its own hostnames and needs no public DNS or open ports, which suits a clinic or office network well.
- Clicking through a browser certificate warning loads the page but does not grant a secure context, so it lands you on the HTTP path rather than the HTTPS one.
- Chrome's
OverrideSecurityRestrictionsOnInsecureOriginpolicy still works if you want the full WebCodecs path over HTTP on a managed fleet. It deliberately weakens a browser security boundary for that origin, and it is no longer necessary just to make the client run. - The desktop RustDesk client has none of these restrictions. The console's
per-device Connect links open it with
rustdesk://.