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 simultan | Plan |
|---|---|
| Câteva — o echipă, o aplicație mică | Nano-IP — 2 vCPU, 1 GB, 15 GB ($8/lună) |
| Zeci | Micro-IP — 2 vCPU, 2 GB, 25 GB ($10/lună) |
| Mai multe, sau TURN lângă serverul aplicației | Small-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
- VPS pentru Jitsi Meet — apeluri video pe serverul tău
- Matrix Synapse pe serverul tău — și apelurile din Matrix au nevoie de un server TURN
- VPS pentru un site cu IP propriu — aplicația care oferă credențialele
- Cum configurezi un firewall ufw
Comentarii
Încă nu există comentarii. Fii primul.