−25%

за Windows при годишно плащане, до 31.10. Към плановете

EQVPS
Започни

VPS за TURN сървър (coturn) за WebRTC

Обажданията, които не минават през строг NAT, спасява TURN ретранслатор. coturn на сървър със собствен IPv4: портове, временни данни за вход, проверен конфиг.

Вашето WebRTC приложение работи на вашия Wi-Fi и не работи при онзи единствен клиент, който звъни от хотел. Медията точка-точка има нужда от път между двете страни; когато и двете са зад строг NAT или защитна стена реже UDP, път няма и обаждането просто не се свързва. Никой не вижда грешка — само безкрайно „свързване…“.

TURN сървърът е резервният вариант точно за такива обаждания: двете страни пращат медията си към него, а той я ретранслира. Ако вграждате видео или глас в приложение, поддържате Matrix или Jitsi за екип или правите гласов чат за игра — трябва ви. coturn е стандартната отворена реализация, и е лека.

Кой план

TURN почти не натоварва CPU и памет. Той харчи трафик: всеки ретранслиран поток минава през сървъра два пъти, на вход и на изход. Трафикът на нашите планове е без лимит при 1 Gbit/s, така че въпросът е колко ретранслирани обаждания вървят едновременно, а не колко ще ви таксуват.

Едновременно ретранслирани обажданияПлан
Няколко — екип, малко приложениеNano-IP: 2 vCPU, 1 GB, 15 GB ($8/месец)
ДесеткиMicro-IP: 2 vCPU, 2 GB, 25 GB ($10/месец)
Повече, или TURN до сървъра на приложениетоSmall-IP: 4 vCPU, 4 GB, 35 GB ($16/месец)

Планът трябва да е със собствен IPv4 — TURN е изцяло входящи връзки на много портове, а плановете с NAT приемат отвън само SSH. На нашите планове със собствен IP публичният адрес стои направо на интерфейса на сървъра, така че coturn го намира без ред external-ip. Сложете сървъра близо до потребителите: Германия или Финландия, наличността се вижда при поръчка. Плащане с крипто, без 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"    # тази стойност трябва на вашия бекенд
systemctl restart coturn
ufw allow 22/tcp && ufw allow 3478 && ufw allow 49152:65535/udp && ufw enable

Не пропускайте редовете denied-peer-ip. Без тях всеки с валидни данни за вход може през вашия ретранслатор да стигне до частни адреси — включително до услуги от вътрешната страна на самия сървър. Проверихме: с тези редове ретранслация към частен адрес се отхвърля с „403 Forbidden IP“.

Данни за вход със срок на валидност

С use-auth-secret coturn приема потребителско име, което съдържа време на изтичане, и парола, която е негов HMAC. Генерира ги вашият бекенд; тайната никога не напуска сървърната страна. На 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")));

В браузъра поискайте от бекенда нова двойка и я подайте на 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,
    },
  ],
});

Проверка

На самия сървър, по същата схема чрез 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“. С грешна парола клиентът спира на „Cannot complete Allocation“ — това е сървърът, който си върши работата.

Проверихме и от истински Chromium: с iceTransportPolicy: "relay" и пресни данни за вход браузърът получи relay кандидати от сървъра; с лоша парола — нито един. Ако искате да проверите своята схема по същия начин, включете тази опция за минута — тя принуждава всяко обаждане да минава през 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 не прави лошата връзка добра. Добавя един скок, затова слагайте сървъра близо до хората, които имат нужда от него.
  • Ако имате SFU — например videobridge в Jitsi, — това е отделна част. TURN помага на клиентите, които не могат да стигнат до него директно.
  • Целият модел на сигурност се крепи на тайната. Дръжте я далеч от фронтенда и я сменете, ако някога изтече.

Свързано

Готов за deploy? Плати в crypto, без KYC — онлайн за около минута.

Deploy-ни сега →

Въпроси

Защо на WebRTC обажданията изобщо им трябва TURN сървър?

WebRTC се опитва да свърже участниците директно и обикновено успява. Когато двете страни са зад симетричен NAT или защитна стена, която реже UDP — хотелски Wi-Fi, офисни мрежи, някои мобилни оператори, — директен път няма и обаждането тихо не се осъществява. TURN сървърът ретранслира медията точно за такива обаждания; обикновено се цитира дял от около едно обаждане на десет.

Може ли TURN да работи на план с NAT?

Не. Клиентите се свързват на UDP и TCP 3478 и към диапазона портове за ретранслация, а план с NAT приема отвън само вашия SSH порт. Трябва ви план със собствен IPv4.

Колко трафик харчи?

Всеки ретранслиран поток минава през сървъра два пъти — навътре от едната страна и навън към другата. Видеоразговор едно към едно по 1–2 Mbit/s във всяка посока прави няколко Mbit/s на сървъра. CPU и RAM почти не го усещат; истинският таван е портът от 1 Gbit/s.

Защо просто да не сложа постоянно име и парола в приложението?

Защото всичко в JavaScript на браузъра е публично, а TURN сървър с известна парола е безплатен ретранслатор за целия интернет. С use-auth-secret вашият бекенд раздава данни за вход със срок на валидност, подписани с тайна, която браузърът никога не вижда.

Трябва ли ми TLS на порт 5349?

Помага в мрежи, които блокират UDP и са придирчиви към обикновения TCP. Добавете го, когато обикновеният TURN вече работи: дайте на coturn сертификат за името на TURN сървъра и отворете 5349/tcp. Ретранслацията през TLS също я проверихме.

Коментари

Още няма коментари. Бъди първият.

Остави коментар

Коментарите се модерират преди да се появят.