diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml index f86d82e..b57c4ae 100644 --- a/k8s/deployment.yaml +++ b/k8s/deployment.yaml @@ -54,6 +54,14 @@ spec: name: coturn-auth key: password optional: true + - name: TURN_LAN_HOST + value: "10.10.3.46" + - name: TURN_LAN_SECRET + valueFrom: + secretKeyRef: + name: coturn-lan-secret + key: static-auth-secret + optional: true - name: OTEL_INGEST_KEY valueFrom: secretKeyRef: diff --git a/server.js b/server.js index 0dc407f..22a824a 100644 --- a/server.js +++ b/server.js @@ -24,8 +24,22 @@ const STATIC_DIR = fs.existsSync(path.join(__dirname, 'dist')) // STUN_URLS comma-separated stun: urls // TURN_URLS comma-separated turn:/turns: urls // TURN_USERNAME / TURN_CREDENTIAL static creds for all TURN urls +// TURN_LAN_HOST / TURN_LAN_SECRET optional second, LAN-only TURN relay +// (own coturn instance + secret, reachable only from +// the local network via its own LoadBalancer IP with +// no NAT/hairpin involved). Harmless to hand out to +// every client: anyone not on that network simply +// can't reach the address and ICE ignores it. // ICE_SERVERS_JSON complete {"iceServers":[...]} override // --------------------------------------------------------------------------- +function hmacTurnCredential(secret, label, ttl) { + const expiry = Math.floor(Date.now() / 1000) + ttl; + const username = `${expiry}:${label}`; + const hmac = crypto.createHmac('sha1', secret); + hmac.update(username); + return { username, credential: hmac.digest('base64') }; +} + function iceConfig() { if (process.env.ICE_SERVERS_JSON) { try { @@ -47,13 +61,9 @@ function iceConfig() { // If a TURN secret is provided (coturn use-auth-secret / static-auth-secret), generate ephemeral HMAC credentials const turnSecret = process.env.TURN_SECRET || process.env.TURN_STATIC_AUTH_SECRET || ''; + const ttl = Number(process.env.TURN_TTL || 86400); if (turnSecret) { - const ttl = Number(process.env.TURN_TTL || 86400); - const expiry = Math.floor(Date.now() / 1000) + ttl; - username = `${expiry}:gibbz`; - const hmac = crypto.createHmac('sha1', turnSecret); - hmac.update(username); - credential = hmac.digest('base64'); + ({ username, credential } = hmacTurnCredential(turnSecret, 'gibbz', ttl)); } iceServers.push({ @@ -61,6 +71,19 @@ function iceConfig() { username, credential, }); + + if (process.env.TURN_LAN_HOST && process.env.TURN_LAN_SECRET) { + const { username: lanUsername, credential: lanCredential } = + hmacTurnCredential(process.env.TURN_LAN_SECRET, 'gibbz-lan', ttl); + iceServers.push({ + urls: [ + `turn:${process.env.TURN_LAN_HOST}:3478?transport=udp`, + `turn:${process.env.TURN_LAN_HOST}:3478?transport=tcp`, + ], + username: lanUsername, + credential: lanCredential, + }); + } } return { iceServers }; }