−25%

sur Windows en paiement annuel, jusqu'au 31/10. Voir les offres

EQVPS
Commencer

VPS pour un serveur TURN (coturn) pour WebRTC

Les appels bloqués par un NAT strict ont besoin d'un relais TURN. coturn sur un serveur avec sa propre IPv4 : ports, identifiants temporaires, config testée.

Votre application WebRTC fonctionne sur votre Wi-Fi et échoue chez le seul client qui appelle depuis un hôtel. Les médias pair-à-pair ont besoin d'un chemin entre les deux côtés ; quand les deux sont derrière un NAT strict, ou qu'un pare-feu bloque l'UDP, il n'y a pas de chemin et l'appel ne se connecte tout simplement pas. Personne ne voit d'erreur — juste un « connexion… » interminable.

Un serveur TURN est la solution de repli pour ces appels : les deux côtés lui envoient leurs médias, et il relaie. Si vous intégrez la vidéo ou la voix dans une app, faites tourner Matrix ou Jitsi pour une équipe, ou proposez un chat vocal pour un jeu, il vous en faut un. coturn est l'implémentation open source de référence, et elle est légère.

Quelle offre

TURN consomme peu de CPU et de mémoire. Ce qu'il utilise, c'est la bande passante : chaque flux relayé traverse le serveur deux fois, à l'aller et au retour. Le trafic est illimité à 1 Gbit/s sur nos offres, donc la question est de savoir combien d'appels relayés tournent en même temps, pas combien vous serez facturé.

Appels relayés en simultanéOffre
Quelques-uns — une équipe, une petite appNano-IP — 2 vCPU, 1 Go, 15 Go (8 $/mois)
Quelques dizainesMicro-IP — 2 vCPU, 2 Go, 25 Go (10 $/mois)
Davantage, ou TURN à côté de votre serveur d'appSmall-IP — 4 vCPU, 4 Go, 35 Go (16 $/mois)

Il faut une offre avec sa propre IPv4 — TURN, ce sont des connexions entrantes sur de nombreux ports, et les offres NAT n'acceptent que le SSH de l'extérieur. Sur nos offres à IP dédiée, l'adresse publique est directement sur l'interface du serveur, donc coturn la trouve sans ligne external-ip. Placez le serveur près de vos utilisateurs : Allemagne ou Finlande, la disponibilité s'affiche à la commande. Paiement en crypto, sans KYC, si cela compte pour vous.

Ports à ouvrir : 3478 en UDP et TCP, 49152–65535 en UDP pour les médias relayés, et 5349 en TCP si vous ajoutez TLS.

Installation et configuration

En root sur Ubuntu 24.04 ou Debian 12 :

apt install -y coturn
ip -4 addr    # votre IP publique doit apparaître sur l'interface

Écrivez la configuration avec un secret partagé tout neuf :

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"    # votre backend a besoin de cette valeur
systemctl restart coturn
ufw allow 22/tcp && ufw allow 3478 && ufw allow 49152:65535/udp && ufw enable

Ne sautez pas les lignes denied-peer-ip. Sans elles, n'importe qui disposant d'identifiants valides peut utiliser votre relais pour atteindre des adresses privées — y compris des services du côté interne du serveur lui-même. Nous avons vérifié : avec ces lignes, un relais vers une adresse privée est refusé avec « 403 Forbidden IP ».

Des identifiants qui expirent

Avec use-auth-secret, coturn accepte un nom d'utilisateur qui contient une date d'expiration et un mot de passe qui en est le HMAC. C'est votre backend qui les génère ; le secret ne quitte jamais le côté serveur. En Node.js :

const crypto = require("crypto");

// Identifiant/mot de passe TURN temporaires (le schéma TURN REST API que coturn comprend 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")));

Dans le navigateur, demandez une nouvelle paire à votre backend et passez-la à 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,
    },
  ],
});

Le tester

Depuis le serveur, avec le même schéma via openssl (il produit exactement le même mot de passe que le code Node.js — nous avons comparé) :

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 fin, vous voulez voir « Total lost packets 0 ». Avec un mauvais mot de passe, le client s'arrête sur « Cannot complete Allocation » — c'est le serveur qui fait son travail.

Nous avons aussi testé depuis un vrai Chromium : avec iceTransportPolicy: "relay" et des identifiants frais, le navigateur a obtenu des candidats relay du serveur ; avec un mauvais mot de passe, aucun. Pour tester votre propre installation de la même façon, activez cette option un instant — elle force chaque appel à passer par TURN.

TLS, si besoin

Certains réseaux bloquent l'UDP et se montrent pointilleux avec le TCP en clair ; TURN sur TLS en traverse davantage. Obtenez un certificat pour turn.example.com (certbot convient). Ses fichiers ne sont lisibles que par root, alors que coturn tourne sous l'utilisateur turnserver : donnez donc à coturn sa propre copie :

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

Ajoutez turns:turn.example.com:5349?transport=tcp à la liste urls. Les certificats ont une durée de vie courte : placez la copie dans un deploy hook de certbot, sinon TLS cassera discrètement au premier renouvellement.

Bon à savoir

  • TURN ne rend pas bonne une mauvaise connexion. Il ajoute un saut, donc placez le serveur près des personnes qui en ont besoin.
  • Si vous faites tourner un SFU — le videobridge de Jitsi, par exemple —, c'est une brique séparée. TURN aide les clients qui ne peuvent pas l'atteindre directement.
  • Le secret est tout le modèle de sécurité. Gardez-le hors du frontend, et changez-le s'il fuit un jour.

Sur le même sujet

Prêt à déployer ? Payez en crypto, sans KYC — en ligne en une minute environ.

Déployer →

FAQ

Pourquoi les appels WebRTC ont-ils besoin d'un serveur TURN ?

WebRTC essaie de connecter les participants directement, et y parvient le plus souvent. Quand les deux côtés sont derrière un NAT symétrique ou un pare-feu qui bloque l'UDP — Wi-Fi d'hôtel, réseaux d'entreprise, certains opérateurs mobiles —, il n'y a pas de chemin direct et l'appel échoue sans bruit. Un serveur TURN relaie les médias précisément pour ces appels ; on cite souvent une proportion d'environ un appel sur dix.

TURN peut-il tourner sur une offre NAT ?

Non. Les clients se connectent en UDP et TCP 3478 et sur la plage de ports de relais, et une offre NAT n'accepte de l'extérieur que votre port SSH. Il vous faut une offre avec sa propre IPv4.

Quelle bande passante consomme-t-il ?

Chaque flux relayé traverse le serveur deux fois — en entrée depuis un côté, en sortie vers l'autre. Un appel vidéo à deux à 1–2 Mbit/s par sens, c'est quelques Mbit/s sur le serveur. Le CPU et la RAM le remarquent à peine ; la vraie limite, c'est le port à 1 Gbit/s.

Pourquoi ne pas mettre simplement un identifiant et un mot de passe fixes dans l'app ?

Parce que tout ce qui se trouve dans le JavaScript du navigateur est public, et un serveur TURN au mot de passe connu devient un relais gratuit pour tout Internet. Avec use-auth-secret, votre backend distribue des identifiants qui expirent, signés avec un secret que le navigateur ne voit jamais.

Ai-je besoin de TLS sur le port 5349 ?

Cela aide sur les réseaux qui bloquent l'UDP et sont stricts avec le TCP en clair. Ajoutez-le une fois que le TURN simple fonctionne : donnez à coturn un certificat pour le nom d'hôte TURN et ouvrez 5349/tcp. Nous avons aussi testé le relais via TLS.

Commentaires

Pas encore de commentaires. Soyez le premier.

Laisser un commentaire

Les commentaires sont modérés avant leur publication.