Skip to content

Corporate network requirements

This page is for the person who runs the firewall or proxy at a client site. The ports the server box itself must open are in Going live. Below, HOST is your server name and TURN is its TURN name (the same name unless you changed TURN_DOMAIN).

  • 443 outbound TCP to HOST, and to TURN
  • Off TURN over TLS until you switch it on
  • Splice do not TLS-inspect TURN
Server architecture: the desktop app reaches the gateway over HTTPS; call media goes straight to the LiveKit media server over UDP.
Clients reach the server over HTTPS on 443; the optional UDP path goes straight to the media server.
  • Outbound TCP 443 to HOST: web, sign-in and WebSocket signalling. Also to TURN when it is a different name; it carries call audio, video and screen share over TLS. If TURN equals HOST, that is one allowlist entry.
  • WebSocket upgrade on HOST. A proxy that strips the Upgrade header breaks signalling. Squid strips it on inspected traffic by default; http_upgrade_request_protocols OTHER allow all fixed it in the lab.
  • Do not TLS-inspect TURN (and not HOST when it is the same name). Exempt it from decryption (Squid: ssl_bump splice; other products call it bypass, no decrypt or ignore hosts). The relay traffic is TURN framing, not HTTP, so a proxy that decrypts it and expects HTTP drops it.
  • An explicit HTTP proxy only has to allow CONNECT to port 443.
  • Optional, faster path: UDP 3478 and the server’s UDP relay range. Not needed when 443 works.

Media is SRTP-encrypted between each participant and the server’s media server (SFU) on every path. It is not end-to-end encrypted past the SFU: the server decrypts and re-encrypts to forward it, so the server operator can in principle access it. The relay on 443 carries the same encrypted media, so a proxy gains nothing by decrypting the TLS wrapper.

It is off by default, and with it off a call from an outbound-443-only network connects and carries nothing (see Going live).

  1. In .env, set TURN_TLS_ENABLED=true. TURN_DOMAIN defaults to turn.<PUBLIC_HOST>.
  2. Add a DNS record for TURN_DOMAIN to the box, or set TURN_DOMAIN equal to PUBLIC_HOST.
  3. Re-run ./firstboot.sh. It adds docker-compose.turn-tls.yml to COMPOSE_FILE.
  4. Open the relay UDP range (default 30000-30199, TURN_RELAY_START / TURN_RELAY_END). Do not open 5349 externally.

An HAProxy mux then owns host ports 80 and 443. It terminates the TURN name with the certificate Caddy issued and passes everything else to Caddy, so the server still sees real client IPs. Turn it back off with TURN_TLS_ENABLED=false and ./firstboot.sh.

Before enabling, node preflight-turn-tls.mjs (run by firstboot.sh, and by verify-stack.sh as step 15) reports as FAIL or WARN: a private or unset NODE_IP, missing or wrong DNS for TURN_DOMAIN, ports 80/443 held by a non-Docker process, a bad relay range, or no certificate yet. NODE_IP must be public (not RFC1918 or CGNAT); in the lab a private one gave relay candidates but no working pairs.

Measured in a lab with real Chromium. Products differ.

The client’s network Result
Proxy allows CONNECT to 443, no inspection Calls work.
Inspects everything, but TURN is exempt Calls work.
SNI allowlist is missing the TURN name The page loads and the call joins, then no audio or video (“could not establish pc connection”).
Decrypts everything and drops non-HTTP traffic (strict inspection) Call joins, no media. No server setting works around this.
Decrypts everything but forwards non-HTTP bytes as plain TCP Worked in the lab, only because that box was lenient. Splice is the safe ask.
Proxy strips WebSocket Upgrade Sign-in works, calls fail before media starts.

Not tested: named commercial inspection products, proxy authentication (NTLM, Kerberos), HTTP/3. A fallback that carries media over the signalling WebSocket is designed but not built.

  • In the app: Preferences, Calls, Diagnostics, Test network. It probes three steps: signalling (secure WebSocket), media relay over UDP, and media relay over TLS 443, reports each as reachable, blocked or not tested, and gives a sentence to send to IT. A live call’s Diagnostics tab shows Transport:; relay-tls means it is going over 443.
  • From a machine on that network: with Node and verify-turn.mjs from the bundle, see Troubleshooting.
Terminal window
node verify-turn.mjs --tls --servername TURN HOST 443