From dc612be8ee33f358a605d26e4f40f0dc9ef93dcf Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Wed, 11 Mar 2026 18:31:57 +0000 Subject: [PATCH] Add TURN server support for mobile video chat Prosody and web client now receive TURN configuration (host, port, credentials) enabling relay-based NAT traversal for mobile clients on symmetric NAT (4G/5G). Coturn is shared from jami-infrastructure as jeffsi-coturn. Added coturn config for reference. Also updated custom-config.js with TURN ICE servers for P2P. Co-Authored-By: Claude Opus 4.6 --- coturn/turnserver.conf | 29 +++++++++++++++++++++++++++++ docker-compose.jeffsi.yml | 15 +++++++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 coturn/turnserver.conf diff --git a/coturn/turnserver.conf b/coturn/turnserver.conf new file mode 100644 index 0000000..41991bd --- /dev/null +++ b/coturn/turnserver.conf @@ -0,0 +1,29 @@ +# Coturn configuration for Jeffsi Meet +listening-port=3478 +tls-listening-port=5349 +external-ip=159.195.32.209 +fingerprint +lt-cred-mech +user=turnuser:jeffsi-turn-secret-2025 +realm=meet.jeffemmett.com +total-quota=0 +bps-capacity=0 +min-port=49152 +max-port=49252 +log-file=stdout +verbose +no-multicast-peers +denied-peer-ip=0.0.0.0-0.255.255.255 +denied-peer-ip=10.0.0.0-10.255.255.255 +denied-peer-ip=100.64.0.0-100.127.255.255 +denied-peer-ip=127.0.0.0-127.255.255.255 +denied-peer-ip=169.254.0.0-169.254.255.255 +denied-peer-ip=172.16.0.0-172.31.255.255 +denied-peer-ip=192.0.0.0-192.0.0.255 +denied-peer-ip=192.88.99.0-192.88.99.255 +denied-peer-ip=192.168.0.0-192.168.255.255 +denied-peer-ip=198.18.0.0-198.19.255.255 +denied-peer-ip=224.0.0.0-255.255.255.255 +allowed-peer-ip=10.0.10.0-10.0.10.255 +stale-nonce=600 +no-cli diff --git a/docker-compose.jeffsi.yml b/docker-compose.jeffsi.yml index 90a08bf..3d25ae4 100644 --- a/docker-compose.jeffsi.yml +++ b/docker-compose.jeffsi.yml @@ -1,6 +1,7 @@ # Jeffsi Meet - Docker Compose for Traefik # Primary domain: jeffsi.localvibe.live (direct HTTPS via Let's Encrypt) # Legacy domain: meet.jeffemmett.com (via Cloudflare tunnel) +# TURN server: shared jeffsi-coturn from jami-infrastructure services: web: image: jeffsi-meet-web:latest @@ -20,23 +21,19 @@ services: labels: - "traefik.enable=true" - "traefik.http.services.jeffsi-meet.loadbalancer.server.port=80" - # Shared middlewares - "traefik.http.middlewares.jeffsi-headers.headers.customrequestheaders.X-Forwarded-Proto=https" - "traefik.http.middlewares.jeffsi-nocache.headers.customresponseheaders.Cache-Control=no-store, must-revalidate" - "traefik.http.middlewares.jeffsi-frame.headers.customFrameOptionsValue=ALLOWALL" - "traefik.http.middlewares.jeffsi-permissions.headers.customresponseheaders.Permissions-Policy=camera=*, microphone=*, display-capture=*, fullscreen=*, autoplay=*" - "traefik.http.middlewares.jeffsi-csp.headers.customresponseheaders.Content-Security-Policy=frame-ancestors *" - "traefik.http.middlewares.jeffsi-redirect-https.redirectscheme.scheme=https" - # PRIMARY: jeffsi.localvibe.live - HTTPS via Let's Encrypt - "traefik.http.routers.jeffsi-meet-secure.rule=Host(`jeffsi.localvibe.live`)" - "traefik.http.routers.jeffsi-meet-secure.entrypoints=websecure" - "traefik.http.routers.jeffsi-meet-secure.tls.certresolver=letsencrypt" - "traefik.http.routers.jeffsi-meet-secure.middlewares=jeffsi-headers,jeffsi-nocache,jeffsi-frame,jeffsi-permissions,jeffsi-csp" - # PRIMARY HTTP->HTTPS redirect - "traefik.http.routers.jeffsi-meet-http.rule=Host(`jeffsi.localvibe.live`)" - "traefik.http.routers.jeffsi-meet-http.entrypoints=web" - "traefik.http.routers.jeffsi-meet-http.middlewares=jeffsi-redirect-https" - # LEGACY: meet.jeffemmett.com - via Cloudflare tunnel (port 80) - "traefik.http.routers.jeffsi-meet.rule=Host(`meet.jeffemmett.com`)" - "traefik.http.routers.jeffsi-meet.entrypoints=web" - "traefik.http.routers.jeffsi-meet.middlewares=jeffsi-headers,jeffsi-nocache,jeffsi-frame,jeffsi-permissions,jeffsi-csp" @@ -63,6 +60,10 @@ services: - XMPP_MUC_DOMAIN=muc.meet.jitsi - XMPP_RECORDER_DOMAIN=recorder.meet.jitsi - ENABLE_RECORDING + - TURN_HOST=${TURN_HOST} + - TURN_PORT=${TURN_PORT} + - TURNS_PORT=${TURNS_PORT} + - TURN_TRANSPORT=${TURN_TRANSPORT} networks: - meet.jitsi - traefik-public @@ -108,6 +109,12 @@ services: - XMPP_MUC_DOMAIN=muc.meet.jitsi - XMPP_INTERNAL_MUC_DOMAIN=internal-muc.meet.jitsi - XMPP_RECORDER_DOMAIN=recorder.meet.jitsi + - TURN_HOST=${TURN_HOST} + - TURN_PORT=${TURN_PORT} + - TURNS_HOST=${TURN_HOST} + - TURNS_PORT=${TURNS_PORT} + - TURN_TRANSPORT=${TURN_TRANSPORT:-udp} + - TURN_CREDENTIALS=${TURN_CREDENTIALS} networks: meet.jitsi: aliases: