TURN Server Configuration & Auth

TURN Architecture & ICE Fallback Mechanics

TURN servers act as mandatory media relays when symmetric NATs or strict enterprise firewalls block direct peer-to-peer connectivity. Within the broader WebRTC Protocol Stack & Signaling Servers infrastructure, relay allocation serves as the final fallback in the ICE candidate gathering process.

Implementation Flow:

  1. Candidate Prioritization: ICE strictly enforces host > srflx > relay hierarchy. Browsers attempt direct paths first before issuing relay allocation requests.
  2. Allocation Request (RFC 5766): The client sends an Allocate request. The TURN server validates credentials, reserves a public IP/port pair, and returns a 200 OK containing the relayed transport address.
  3. Browser Constraints: Modern browsers cap ICE gathering at ~10–15 seconds and limit concurrent candidate pairs. If relay allocation exceeds this threshold, iceConnectionState transitions to failed.

Network Fallback Considerations:

Authentication Models & Credential Generation

Static long-term credentials are unsuitable for production due to credential stuffing and replay attack vulnerabilities. Implement time-bound ephemeral credentials signed via HMAC-SHA1. These tokens are embedded directly into the SDP Offer/Answer Lifecycle to guarantee secure, expiring relay access.

Step-by-Step Credential Generation (Node.js):

const crypto = require('crypto');
const TTL = 86400; // 24 hours
const timestamp = Math.floor(Date.now() / 1000) + TTL;
const username = `${timestamp}:client_id`;
const credential = crypto.createHmac('sha1', process.env.TURN_SECRET)
 .update(username)
 .digest('base64');
return { username, credential, ttl: TTL };

Configuration & Rotation Strategy:

Signaling Integration & Credential Exchange

Credentials must be delivered securely to the client before RTCPeerConnection initialization. This exchange typically occurs over an encrypted signaling channel, as detailed in WebSocket Signaling Implementation.

Client-Side Integration:

  1. Fetch ephemeral credentials asynchronously from your backend.
  2. Construct the RTCIceServer array with explicit username and credential fields.
  3. Enforce wss:// for signaling and turns:// for media transport to prevent MITM interception.
const iceServers = [
 { urls: 'stun:stun.example.com:3478' },
 { urls: 'turn:turn.example.com:3478', username: creds.username, credential: creds.credential },
 { urls: 'turns:turn.example.com:5349?transport=tcp', username: creds.username, credential: creds.credential }
];
const pc = new RTCPeerConnection({ iceServers });

Browser & Network Fallback Handling:

Production Hardening & Debugging Workflows

Deploying a TURN relay requires strict network mapping, resource limits, and active monitoring. For advanced cluster scaling and kernel tuning, refer to Configuring Coturn for production TURN relay.

Hardened turnserver.conf Baseline:

listening-port=3478
tls-listening-port=5349
external-ip=PUBLIC_IP/PRIVATE_IP
realm=turn.example.com
server-name=turn.example.com
log-file=/var/log/turnserver/turn.log
verbose
max-bps=1000000
user-quota=10
stale-nonce
listening-ip=0.0.0.0

Troubleshooting & Verification:

Common Implementation Pitfalls

Frequently Asked Questions

When should I use long-term auth versus ephemeral credentials? Reserve long-term auth for isolated, internal testing environments. Production deployments must use ephemeral credentials with HMAC-SHA1 signing and strict TTLs to prevent credential leakage and replay attacks.

How do I verify if my TURN server is actually being used? Monitor RTCPeerConnection.getStats() for localCandidateType: relay. Track bytesSent and bytesReceived on relay candidates. Server-side, grep allocation and refresh logs for active sessions.

Why does my TURN server fail on corporate networks despite correct configuration? Enterprise firewalls often block all UDP traffic and restrict outbound ports to 80/443. Ensure your TURN server binds TCP/TLS to port 443 (turns://...?transport=tcp) and validate connectivity using turnutils_uclient over TLS.