# Self-hosted TURN (coturn) for BizGaze Connect Why: customers behind symmetric NAT / corporate firewalls / VPNs can't form a direct WebRTC path, so screen share blanks out and disconnects. A TURN relay fixes it. We host our own coturn on a VM we already own — flat cost, no per-GB billing. ## 1. VM prerequisites - A VM with a **public IP** (your data-center VM is fine). - A DNS A record, e.g. `turn.yourdomain.com` -> that public IP. - A TLS cert for that name (Let's Encrypt): `certbot certonly --standalone -d turn.yourdomain.com` ## 2. Open firewall ports (on the VM and any edge firewall) - `3478/udp` and `3478/tcp` (STUN/TURN) - `5349/tcp` (TURN over TLS) — and `443/tcp` if you enable alt-tls - `49152-65535/udp` (relay range) ## 3. Configure Edit `turnserver.conf`: - `external-ip=` your VM's public IP - `static-auth-secret=` a long random string (e.g. `openssl rand -hex 32`) - `realm=` your domain - `cert=` / `pkey=` paths to your Let's Encrypt cert ## 4. Run ``` docker compose up -d # uses docker-compose.yml here # or native: apt install coturn; copy this file to /etc/turnserver.conf; enable in /etc/default/coturn; systemctl enable --now coturn ``` ## 5. Point the app at it (production env) ``` TURN_URLS=turn:turn.yourdomain.com:3478,turn:turn.yourdomain.com:3478?transport=tcp,turns:turn.yourdomain.com:5349?transport=tcp TURN_SECRET= TURN_TTL=86400 ``` The app's `/api/ice` mints short-lived credentials from `TURN_SECRET` automatically — no permanent password is exposed, and outsiders can't reuse your relay. Restart the app. ## 6. Verify - `GET https:///api/ice` should return a `turn:`/`turns:` entry with a username + credential. - Test page: https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ Add your `turns:turn.yourdomain.com:5349?transport=tcp` with the username/credential from `/api/ice`; you should see a candidate of type **relay**. If you do, restrictive networks are covered.