Η WebRTC εφαρμογή σας δουλεύει στο δικό σας Wi-Fi και αποτυγχάνει για τον έναν πελάτη που καλεί από ξενοδοχείο. Τα μέσα peer-to-peer χρειάζονται μια διαδρομή ανάμεσα στις δύο πλευρές· όταν και οι δύο είναι πίσω από αυστηρό NAT, ή ένα τείχος προστασίας απορρίπτει το UDP, διαδρομή δεν υπάρχει και η κλήση απλώς δεν συνδέεται. Κανείς δεν βλέπει σφάλμα — μόνο ένα ατελείωτο «σύνδεση…».
Ένας TURN server είναι η εφεδρική λύση για αυτές ακριβώς τις κλήσεις: και οι δύο πλευρές στέλνουν τα μέσα τους σε αυτόν, και αυτός τα αναμεταδίδει. Αν βάζετε βίντεο ή φωνή σε μια εφαρμογή, τρέχετε Matrix ή Jitsi για μια ομάδα ή φτιάχνετε φωνητική συνομιλία για ένα παιχνίδι, θέλετε έναν. Το coturn είναι η τυπική υλοποίηση ανοιχτού κώδικα, και είναι ελαφρύ.
Ποιο πακέτο
Το TURN θέλει ελάχιστη CPU και μνήμη. Αυτό που καταναλώνει είναι εύρος ζώνης: κάθε αναμεταδιδόμενη ροή περνά από τον server δύο φορές, μέσα και έξω. Η κίνηση στα πακέτα μας είναι απεριόριστη στο 1 Gbit/s, οπότε το ερώτημα είναι πόσες αναμεταδιδόμενες κλήσεις τρέχουν ταυτόχρονα, όχι πόσο θα χρεωθείτε.
| Ταυτόχρονες αναμεταδιδόμενες κλήσεις | Πακέτο |
|---|---|
| Λίγες — μια ομάδα, μια μικρή εφαρμογή | Nano-IP: 2 vCPU, 1 GB, 15 GB ($8/μήνα) |
| Δεκάδες | Micro-IP: 2 vCPU, 2 GB, 25 GB ($10/μήνα) |
| Περισσότερες, ή TURN δίπλα στον server της εφαρμογής | Small-IP: 4 vCPU, 4 GB, 35 GB ($16/μήνα) |
Πρέπει να είναι πακέτο με δική του IPv4 — το TURN είναι εξ ολοκλήρου εισερχόμενες συνδέσεις σε πολλές θύρες, και τα πακέτα NAT δέχονται απ' έξω μόνο SSH. Στα πακέτα μας με αποκλειστική IP η δημόσια διεύθυνση βρίσκεται κατευθείαν στο interface του server, οπότε το coturn τη βρίσκει χωρίς γραμμή external-ip. Βάλτε τον server κοντά στους χρήστες σας: Γερμανία ή Φινλανδία, η διαθεσιμότητα φαίνεται κατά την παραγγελία. Πληρωμή με κρυπτονομίσματα, χωρίς KYC, αν αυτό σας ενδιαφέρει.
Θύρες που ανοίγετε: 3478 UDP και TCP, 49152–65535 UDP για τα αναμεταδιδόμενα μέσα και 5349 TCP αν προσθέσετε TLS.
Εγκατάσταση και ρύθμιση
Ως root σε Ubuntu 24.04 ή Debian 12:
apt install -y coturn
ip -4 addr # η δημόσια IP σας πρέπει να φαίνεται στη διεπαφή
Γράψτε τη ρύθμιση με ένα φρέσκο κοινό μυστικό:
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 σας
systemctl restart coturn
ufw allow 22/tcp && ufw allow 3478 && ufw allow 49152:65535/udp && ufw enable
Μην παραλείψετε τις γραμμές denied-peer-ip. Χωρίς αυτές, οποιοσδήποτε με έγκυρα διαπιστευτήρια μπορεί να χρησιμοποιήσει το relay σας για να φτάσει σε ιδιωτικές διευθύνσεις — ακόμη και σε υπηρεσίες στην εσωτερική πλευρά του ίδιου του server. Το ελέγξαμε: με αυτές τις γραμμές ένα relay προς ιδιωτική διεύθυνση απορρίπτεται με «403 Forbidden IP».
Διαπιστευτήρια που λήγουν
Με το use-auth-secret το coturn δέχεται όνομα χρήστη που περιέχει χρόνο λήξης και κωδικό που είναι το HMAC του. Τα παράγει το backend σας· το μυστικό δεν φεύγει ποτέ από την πλευρά του server. Σε Node.js:
const crypto = require("crypto");
// Προσωρινό όνομα χρήστη/κωδικός TURN (το σχήμα TURN REST API που καταλαβαίνει το coturn μέσω 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")));
Στον browser, ζητήστε από το backend ένα νέο ζεύγος και δώστε το στο 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,
},
],
});
Δοκιμή
Από τον server, με το ίδιο σχήμα μέσω openssl (παράγει ακριβώς τον ίδιο κωδικό με τον κώδικα Node.js — συγκρίναμε):
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
Στο τέλος θέλετε να δείτε «Total lost packets 0». Με λάθος κωδικό ο client σταματά στο «Cannot complete Allocation» — αυτός είναι ο server που κάνει τη δουλειά του.
Ελέγξαμε επίσης από πραγματικό Chromium: με iceTransportPolicy: "relay" και φρέσκα διαπιστευτήρια ο browser πήρε relay candidates από τον server· με λάθος κωδικό, κανέναν. Αν θέλετε να δοκιμάσετε τη δική σας διάταξη με τον ίδιο τρόπο, ενεργοποιήστε για λίγο αυτή την επιλογή — αναγκάζει κάθε κλήση να περάσει από το TURN.
TLS, αν το χρειάζεστε
Κάποια δίκτυα μπλοκάρουν το UDP και είναι ιδιότροπα με το απλό TCP· το TURN μέσω TLS περνά από περισσότερα από αυτά. Πάρτε πιστοποιητικό για το turn.example.com (το certbot κάνει). Τα αρχεία του τα διαβάζει μόνο ο root, ενώ το coturn τρέχει ως χρήστης turnserver, οπότε δώστε στο coturn δικό του αντίγραφο:
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
Προσθέστε το turns:turn.example.com:5349?transport=tcp στη λίστα urls. Τα πιστοποιητικά είναι βραχύβια, οπότε βάλτε την αντιγραφή σε ένα deploy hook του certbot — αλλιώς το TLS θα χαλάσει αθόρυβα στην πρώτη ανανέωση.
Καλό να ξέρετε
- Το TURN δεν κάνει μια κακή σύνδεση καλή. Προσθέτει ένα hop, οπότε βάλτε τον server κοντά σε όσους τον χρειάζονται.
- Αν τρέχετε SFU — για παράδειγμα το videobridge του Jitsi — αυτό είναι ξεχωριστό κομμάτι. Το TURN βοηθά τους clients που δεν μπορούν να φτάσουν σε αυτό απευθείας.
- Όλο το μοντέλο ασφαλείας είναι το μυστικό. Κρατήστε το έξω από το frontend και αλλάξτε το αν ποτέ διαρρεύσει.
Σχετικά
- VPS για Jitsi Meet: βιντεοκλήσεις στον δικό σας server
- Matrix Synapse στον δικό σας server: και οι κλήσεις στο Matrix χρειάζονται TURN server
- VPS για ιστότοπο με δική του IP: η εφαρμογή που μοιράζει τα διαπιστευτήρια
- Πώς να ρυθμίσετε τείχος προστασίας ufw
Σχόλια
Δεν υπάρχουν ακόμη σχόλια. Γίνετε ο πρώτος.