Aplikasi WebRTC Anda jalan di Wi-Fi Anda dan gagal bagi satu pelanggan yang menelepon dari hotel. Media peer-to-peer butuh jalur di antara kedua sisi; kalau keduanya di balik NAT ketat, atau firewall membuang UDP, tidak ada jalur dan panggilan begitu saja tidak tersambung. Tidak ada yang melihat error — hanya «menyambungkan…» tanpa akhir.
Server TURN adalah cadangan untuk panggilan seperti itu: kedua sisi mengirim media ke sana, dan server meneruskannya. Kalau Anda menanam video atau suara ke aplikasi, menjalankan Matrix atau Jitsi untuk tim, atau membuat obrolan suara untuk game, Anda butuh satu. coturn adalah implementasi open source standar, dan ringan.
Paket yang mana
TURN hemat CPU dan memori. Yang dipakainya adalah bandwidth: setiap stream yang diteruskan melewati server dua kali, masuk dan keluar. Trafik di paket kami tanpa batas di 1 Gbit/s, jadi pertanyaannya berapa panggilan yang diteruskan sekaligus, bukan berapa tagihan Anda.
| Panggilan yang diteruskan bersamaan | Paket |
|---|---|
| Beberapa — sebuah tim, aplikasi kecil | Nano-IP: 2 vCPU, 1 GB, 15 GB ($8/bln) |
| Puluhan | Micro-IP: 2 vCPU, 2 GB, 25 GB ($10/bln) |
| Lebih banyak, atau TURN di samping server aplikasi | Small-IP: 4 vCPU, 4 GB, 35 GB ($16/bln) |
Harus paket dengan IPv4 sendiri — TURN sepenuhnya soal koneksi masuk di banyak port, dan paket NAT dari luar hanya menerima SSH. Di paket kami dengan IP sendiri, alamat publik langsung terpasang di antarmuka server, jadi coturn menemukannya tanpa baris external-ip. Letakkan server dekat pengguna Anda: Jerman atau Finlandia, ketersediaannya terlihat saat memesan. Pembayaran dengan kripto, tanpa KYC, kalau itu penting bagi Anda.
Port yang perlu dibuka: 3478 UDP dan TCP, 49152–65535 UDP untuk media yang diteruskan, dan 5349 TCP jika Anda menambahkan TLS.
Instalasi dan konfigurasi
Sebagai root di Ubuntu 24.04 atau Debian 12:
apt install -y coturn
ip -4 addr # IP publik Anda harus tercantum di interface
Tulis konfigurasi dengan rahasia bersama yang baru:
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 Anda butuh nilai ini
systemctl restart coturn
ufw allow 22/tcp && ufw allow 3478 && ufw allow 49152:65535/udp && ufw enable
Jangan lewatkan baris denied-peer-ip. Tanpanya, siapa pun dengan kredensial sah bisa memakai relay Anda untuk menjangkau alamat privat — termasuk layanan di sisi internal server itu sendiri. Kami sudah memeriksa: dengan baris-baris ini, relay ke alamat privat ditolak dengan «403 Forbidden IP».
Kredensial yang kedaluwarsa
Dengan use-auth-secret, coturn menerima username yang berisi waktu kedaluwarsa dan password yang merupakan HMAC dari username itu. Backend Anda yang membuatnya; rahasianya tidak pernah meninggalkan sisi server. Di Node.js:
const crypto = require("crypto");
// Username/password TURN sementara (skema TURN REST API yang dipahami coturn lewat 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")));
Di browser, minta pasangan baru ke backend dan berikan ke 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,
},
],
});
Uji
Dari server, dengan skema yang sama memakai openssl (hasilnya password yang persis sama dengan kode Node.js — kami sudah membandingkan):
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
Di akhir Anda ingin melihat «Total lost packets 0». Dengan password salah, klien berhenti di «Cannot complete Allocation» — itu server yang sedang menjalankan tugasnya.
Kami juga menguji dari Chromium sungguhan: dengan iceTransportPolicy: "relay" dan kredensial baru, browser mendapat kandidat relay dari server; dengan password salah, tidak ada sama sekali. Kalau Anda ingin menguji pengaturan sendiri dengan cara yang sama, aktifkan opsi itu sebentar — opsi ini memaksa setiap panggilan lewat TURN.
TLS, jika perlu
Beberapa jaringan memblokir UDP dan rewel terhadap TCP biasa; TURN lewat TLS bisa menembus lebih banyak di antaranya. Dapatkan sertifikat untuk turn.example.com (certbot cukup). Filenya hanya bisa dibaca root, sedangkan coturn berjalan sebagai pengguna turnserver, jadi beri coturn salinannya sendiri:
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
Tambahkan turns:turn.example.com:5349?transport=tcp ke daftar urls. Sertifikat berumur pendek, jadi masukkan penyalinan ke deploy hook certbot — kalau tidak, TLS diam-diam rusak saat perpanjangan pertama.
Perlu diketahui
- TURN tidak membuat koneksi buruk menjadi bagus. Ia menambah satu lompatan, jadi letakkan server dekat orang yang membutuhkannya.
- Kalau Anda menjalankan SFU — misalnya videobridge milik Jitsi — itu bagian terpisah. TURN membantu klien yang tidak bisa menjangkaunya secara langsung.
- Seluruh model keamanan bertumpu pada rahasia itu. Jauhkan dari frontend, dan ganti jika suatu saat bocor.
Terkait
- VPS untuk Jitsi Meet: panggilan video di server sendiri
- Matrix Synapse di server sendiri: panggilan Matrix juga butuh server TURN
- VPS untuk situs web dengan IP sendiri: aplikasi yang membagikan kredensial
- Cara mengonfigurasi firewall ufw
Komentar
Belum ada komentar. Jadilah yang pertama.