Din WebRTC-app virker på dit wifi og fejler hos netop den ene kunde, der ringer fra et hotel. Peer-to-peer-medier skal have en vej mellem de to sider; når begge sidder bag streng NAT, eller en firewall smider UDP væk, er der ingen vej, og opkaldet bliver simpelthen ikke forbundet. Ingen ser en fejl — bare et uendeligt „forbinder…”.
En TURN-server er reserveløsningen til netop de opkald: begge sider sender deres medier til den, og den videresender. Bygger du video eller tale ind i en app, kører du Matrix eller Jitsi for et team eller laver du stemmechat til et spil, så vil du have en. coturn er standardimplementeringen med åben kildekode, og den er let.
Hvilken plan
TURN bruger meget lidt CPU og hukommelse. Det, den bruger, er båndbredde: hver videresendt strøm går to gange gennem serveren, ind og ud. Trafik er ubegrænset ved 1 Gbit/s på vores planer, så spørgsmålet er, hvor mange videresendte opkald der kører samtidig, ikke hvor meget du bliver faktureret.
| Videresendte opkald samtidig | Plan |
|---|---|
| En håndfuld — et team, en lille app | Nano-IP: 2 vCPU, 1 GB, 15 GB ($8/md.) |
| Dusinvis | Micro-IP: 2 vCPU, 2 GB, 25 GB ($10/md.) |
| Flere, eller TURN ved siden af din appserver | Small-IP: 4 vCPU, 4 GB, 35 GB ($16/md.) |
Det skal være en plan med egen IPv4 — TURN handler udelukkende om indgående forbindelser på mange porte, og NAT-planer modtager kun SSH udefra. På vores planer med egen IP ligger den offentlige adresse direkte på serverens interface, så coturn finder den uden en external-ip-linje. Placér serveren tæt på dine brugere: Tyskland eller Finland, tilgængeligheden ses ved bestilling. Betaling med krypto, uden KYC, hvis det betyder noget for dig.
Porte, der skal åbnes: 3478 UDP og TCP, 49152–65535 UDP til de videresendte medier og 5349 TCP, hvis du tilføjer TLS.
Installation og konfiguration
Som root på Ubuntu 24.04 eller Debian 12:
apt install -y coturn
ip -4 addr # din offentlige IP skal stå på interfacet
Skriv konfigurationen med en frisk delt hemmelighed:
SECRET=$(openssl rand -hex 32)
cat > /etc/turnserver.conf <<EOF
listening-port=3478
fingerprint
use-auth-secret
static-auth-secret=$SECRET
realm=turn.example.com
min-port=49152
max-port=65535
no-cli
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.168.0.0-192.168.255.255
EOF
echo "$SECRET" # din backend skal bruge denne værdi
systemctl restart coturn
ufw allow 22/tcp && ufw allow 3478 && ufw allow 49152:65535/udp && ufw enable
Spring ikke linjerne denied-peer-ip over. Uden dem kan enhver med gyldige loginoplysninger bruge dit relæ til at nå private adresser — også tjenester på serverens egen interne side. Vi tjekkede: med disse linjer afvises et relæ til en privat adresse med „403 Forbidden IP”.
Loginoplysninger, der udløber
Med use-auth-secret accepterer coturn et brugernavn, der indeholder et udløbstidspunkt, og en adgangskode, der er en HMAC af det. Din backend genererer dem; hemmeligheden forlader aldrig serversiden. I Node.js:
const crypto = require("crypto");
// Midlertidigt TURN-brugernavn og adgangskode (TURN REST API-skemaet, som coturn forstår via use-auth-secret).
function turnCredentials(secret, user, ttlSeconds = 3600) {
const username = `${Math.floor(Date.now() / 1000) + ttlSeconds}:${user}`;
const credential = crypto.createHmac("sha1", secret).update(username).digest("base64");
return { username, credential };
}
console.log(JSON.stringify(turnCredentials(process.env.TURN_SECRET, "alice")));
I browseren beder du din backend om et nyt par og giver det til RTCPeerConnection:
const { username, credential } = await fetch("/api/turn-credentials").then((r) => r.json());
const pc = new RTCPeerConnection({
iceServers: [
{ urls: "stun:turn.example.com:3478" },
{
urls: ["turn:turn.example.com:3478?transport=udp", "turn:turn.example.com:3478?transport=tcp"],
username,
credential,
},
],
});
Test det
Fra serveren, efter samme skema med openssl (det giver præcis samme adgangskode som Node.js-koden — vi sammenlignede):
U="$(( $(date +%s) + 3600 )):test"
P=$(echo -n "$U" | openssl dgst -binary -sha1 -hmac "$SECRET" | base64)
turnutils_uclient -y -n 10 -u "$U" -w "$P" YOUR_SERVER_IP
Til sidst vil du se „Total lost packets 0”. Med en forkert adgangskode stopper klienten ved „Cannot complete Allocation” — det er serveren, der gør sit arbejde.
Vi testede også fra en rigtig Chromium: med iceTransportPolicy: "relay" og friske loginoplysninger fik browseren relay-kandidater fra serveren; med en forkert adgangskode ingen. Vil du teste din egen opsætning på samme måde, så slå den indstilling til et øjeblik — den tvinger hvert opkald gennem TURN.
TLS, hvis du har brug for det
Nogle netværk blokerer UDP og er kræsne med almindelig TCP; TURN over TLS kommer igennem flere af dem. Skaf et certifikat til turn.example.com (certbot er fint). Filerne kan kun læses af root, mens coturn kører som brugeren turnserver, så giv coturn sin egen kopi:
mkdir -p /etc/coturn
cp /etc/letsencrypt/live/turn.example.com/fullchain.pem /etc/letsencrypt/live/turn.example.com/privkey.pem /etc/coturn/
chown turnserver: /etc/coturn/*.pem && chmod 640 /etc/coturn/privkey.pem
cat >> /etc/turnserver.conf <<'EOF'
tls-listening-port=5349
cert=/etc/coturn/fullchain.pem
pkey=/etc/coturn/privkey.pem
EOF
systemctl restart coturn && ufw allow 5349/tcp
Tilføj turns:turn.example.com:5349?transport=tcp til listen urls. Certifikater er kortlivede, så læg kopieringen i et deploy hook til certbot — ellers går TLS stille i stykker ved første fornyelse.
Værd at vide
- TURN gør ikke en dårlig forbindelse god. Den tilføjer ét hop, så placér serveren tæt på dem, der har brug for den.
- Kører du en SFU — fx Jitsis videobridge — er det en separat del. TURN hjælper de klienter, der ikke kan nå den direkte.
- Hemmeligheden er hele sikkerhedsmodellen. Hold den ude af frontenden, og udskift den, hvis den nogensinde lækker.
Relateret
- VPS til Jitsi Meet: videoopkald på din egen server
- Kør Matrix Synapse selv: opkald i Matrix har også brug for en TURN-server
- VPS til et website på egen IP: appen, der udleverer loginoplysningerne
- Sådan sætter du en ufw-firewall op
Kommentarer
Ingen kommentarer endnu. Vær den første.