−25%

la planurile Windows anuale, până pe 31 oct. Vezi planurile

EQVPS
Începe

VPS pentru un server TURN (coturn) pentru WebRTC

Apelurile care eșuează în spatele unui NAT strict au nevoie de un relay TURN. coturn pe un server cu IPv4 propriu: porturi, credențiale temporare, config.

Aplicația ta WebRTC merge pe Wi-Fi-ul tău și eșuează exact la clientul care sună dintr-un hotel. Media peer-to-peer are nevoie de un drum între cele două părți; când ambele sunt în spatele unui NAT strict sau un firewall blochează UDP, drumul nu există, iar apelul pur și simplu nu se conectează. Nimeni nu vede vreo eroare — doar un „se conectează…” fără sfârșit.

Un server TURN e varianta de rezervă exact pentru aceste apeluri: ambele părți îi trimit media, iar el o retransmite. Dacă integrezi video sau voce într-o aplicație, rulezi Matrix sau Jitsi pentru o echipă ori faci chat vocal pentru un joc, ai nevoie de unul. coturn e implementarea open source standard, și e ușoară.

Ce plan

TURN consumă puțin CPU și memorie. Ce folosește e lățimea de bandă: fiecare flux retransmis trece de două ori prin server, la intrare și la ieșire. Traficul pe planurile noastre e nelimitat la 1 Gbit/s, deci întrebarea e câte apeluri retransmise rulează simultan, nu cât vei plăti.

Apeluri retransmise simultanPlan
Câteva — o echipă, o aplicație micăNano-IP — 2 vCPU, 1 GB, 15 GB ($8/lună)
ZeciMicro-IP — 2 vCPU, 2 GB, 25 GB ($10/lună)
Mai multe, sau TURN lângă serverul aplicațieiSmall-IP — 4 vCPU, 4 GB, 35 GB ($16/lună)

Trebuie să fie un plan cu IPv4 propriu — TURN înseamnă numai conexiuni de intrare pe multe porturi, iar planurile NAT acceptă din exterior doar SSH. Pe planurile noastre cu IP dedicat, adresa publică stă direct pe interfața serverului, deci coturn o găsește fără linia external-ip. Pune serverul aproape de utilizatori: există două locații din UE (disponibilitatea se vede la comandă). Plată în cripto, fără KYC, dacă asta contează pentru tine.

Porturi de deschis: 3478 UDP și TCP, 49152–65535 UDP pentru media retransmisă și 5349 TCP dacă adaugi TLS.

Instalare și configurare

Ca root pe Ubuntu 24.04 sau Debian 12:

apt install -y coturn
ip -4 addr    # IP-ul public ar trebui să apară pe interfață

Scrie configurația cu un secret partajat nou:

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"    # backend-ul tău are nevoie de această valoare
systemctl restart coturn
ufw allow 22/tcp && ufw allow 3478 && ufw allow 49152:65535/udp && ufw enable

Nu sări peste liniile denied-peer-ip. Fără ele, oricine are credențiale valide îți poate folosi relay-ul ca să ajungă la adrese private — inclusiv la servicii de pe partea internă a serverului însuși. Am verificat: cu aceste linii, un relay către o adresă privată e refuzat cu „403 Forbidden IP”.

Credențiale care expiră

Cu use-auth-secret, coturn acceptă un nume de utilizator care conține un moment de expirare și o parolă care e HMAC-ul lui. Le generează backendul tău; secretul nu părăsește niciodată partea de server. În Node.js:

const crypto = require("crypto");

// Utilizator/parolă TURN temporare (schema TURN REST API pe care coturn o înțelege prin 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")));

În browser, cere-i backendului o pereche nouă și dă-o lui 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,
    },
  ],
});

Testează

De pe server, cu aceeași schemă folosind openssl (produce exact aceeași parolă ca și codul Node.js — am comparat):

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

La final vrei să vezi „Total lost packets 0”. Cu o parolă greșită, clientul se oprește la „Cannot complete Allocation” — e serverul care își face treaba.

Am verificat și dintr-un Chromium real: cu iceTransportPolicy: "relay" și credențiale proaspete, browserul a primit candidați relay de la server; cu o parolă greșită, niciunul. Dacă vrei să-ți testezi propria configurație la fel, activează opțiunea pentru un moment — forțează fiecare apel să treacă prin TURN.

TLS, dacă e nevoie

Unele rețele blochează UDP și sunt pretențioase cu TCP-ul simplu; TURN prin TLS trece prin mai multe dintre ele. Obține un certificat pentru turn.example.com (certbot e bun). Fișierele lui pot fi citite doar de root, iar coturn rulează ca utilizatorul turnserver, așa că dă-i lui coturn o copie proprie:

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

Adaugă turns:turn.example.com:5349?transport=tcp în lista urls. Certificatele au viață scurtă, așa că pune copierea într-un deploy hook pentru certbot — altfel TLS se strică pe tăcute la prima reînnoire.

Bine de știut

  • TURN nu face dintr-o conexiune proastă una bună. Adaugă un salt, deci pune serverul aproape de cei care au nevoie de el.
  • Dacă rulezi un SFU — videobridge-ul din Jitsi, de exemplu —, e o piesă separată. TURN îi ajută pe clienții care nu pot ajunge direct la el.
  • Secretul e întregul model de securitate. Ține-l departe de frontend și schimbă-l dacă se scurge vreodată.

Articole conexe

Gata de deploy? Plătește cu cripto, fără KYC — online în aproximativ un minut.

Pornește acum →

Întrebări frecvente

De ce au nevoie apelurile WebRTC de un server TURN?

WebRTC încearcă să conecteze participanții direct și de obicei reușește. Când ambele părți stau în spatele unui NAT simetric sau al unui firewall care blochează UDP — Wi-Fi de hotel, rețele de birou, unii operatori mobili —, nu există drum direct, iar apelul eșuează fără zgomot. Un server TURN retransmite media exact pentru aceste apeluri; proporția citată de obicei e în jur de un apel din zece.

Poate rula TURN pe un plan NAT?

Nu. Clienții se conectează pe UDP și TCP 3478 și pe intervalul de porturi de relay, iar un plan NAT acceptă din exterior doar portul tău SSH. Ai nevoie de un plan cu IPv4 propriu.

Câtă lățime de bandă folosește?

Fiecare flux retransmis trece de două ori prin server — intră de la o parte și iese spre cealaltă. Un apel video unu la unu la 1–2 Mbit/s pe direcție înseamnă câțiva Mbit/s pe server. CPU-ul și RAM-ul abia observă; plafonul real e portul de 1 Gbit/s.

De ce să nu pun pur și simplu un utilizator și o parolă fixe în aplicație?

Pentru că tot ce e în JavaScript-ul din browser e public, iar un server TURN cu parolă cunoscută e un relay gratuit pentru tot internetul. Cu use-auth-secret, backendul tău oferă credențiale care expiră, semnate cu un secret pe care browserul nu-l vede niciodată.

Am nevoie de TLS pe portul 5349?

Ajută în rețelele care blochează UDP și sunt stricte cu TCP-ul simplu. Adaugă-l după ce TURN-ul simplu funcționează: dă-i lui coturn un certificat pentru numele de host TURN și deschide 5349/tcp. Am testat și relay-ul prin TLS.

Comentarii

Încă nu există comentarii. Fii primul.

Lasă un comentariu

Comentariile sunt moderate înainte să apară.