−25%

روی پرداخت سالانه Windows، تا ۳۱ اکتبر. مشاهده پلن‌ها

EQVPS
شروع کنید

سرور VPS برای سرور TURN (‏coturn) برای WebRTC

تماس‌هایی که پشت NAT سخت‌گیر شکست می‌خورند به رلهٔ TURN نیاز دارند. ‏coturn روی سروری با IPv4 اختصاصی: پورت‌ها، اعتبارنامهٔ موقت، پیکربندی آزموده و پلن.

اپ WebRTC شما روی وای‌فای خودتان کار می‌کند و درست برای همان مشتری‌ای که از هتل تماس می‌گیرد شکست می‌خورد. رسانهٔ همتا به همتا به مسیری میان دو طرف نیاز دارد؛ وقتی هر دو پشت NAT سخت‌گیر باشند، یا فایروالی UDP را دور بریزد، مسیری نیست و تماس اصلاً وصل نمی‌شود. هیچ‌کس خطایی نمی‌بیند — فقط یک «در حال اتصال…» بی‌پایان.

سرور TURN راه جایگزین همین تماس‌هاست: هر دو طرف رسانه‌شان را به آن می‌فرستند و آن رله می‌کند. اگر ویدیو یا صدا را در اپی می‌گنجانید، برای تیمی Matrix یا Jitsi اجرا می‌کنید یا برای بازی‌ای گفت‌وگوی صوتی می‌سازید، به یکی نیاز دارید. ‏coturn پیاده‌سازی متن‌باز استاندارد است و سبک است.

کدام پلن

‏TURN پردازنده و حافظهٔ کمی می‌خواهد. چیزی که مصرف می‌کند پهنای باند است: هر جریان رله‌شده دو بار، ورود و خروج، از سرور می‌گذرد. ترافیک در پلن‌های ما با سرعت 1 Gbit/s نامحدود است، پس پرسش این است که هم‌زمان چند تماس رله‌شده در جریان است، نه اینکه چقدر صورت‌حساب می‌آید.

تماس‌های رله‌شدهٔ هم‌زمانپلن
چند تماس — یک تیم، یک اپ کوچکNano-IP: ۲ vCPU، ۱ گیگابایت، ۱۵ گیگابایت (۸ دلار در ماه)
ده‌ها تماسMicro-IP: ۲ vCPU، ۲ گیگابایت، ۲۵ گیگابایت (۱۰ دلار در ماه)
بیشتر، یا TURN کنار سرور اپSmall-IP: ۴ vCPU، ۴ گیگابایت، ۳۵ گیگابایت (۱۶ دلار در ماه)

باید پلنی با 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 به کلاینت‌هایی کمک می‌کند که نمی‌توانند مستقیم به آن برسند.
  • کل مدل امنیتی همان راز است. آن را از فرانت‌اند دور نگه دارید و اگر روزی لو رفت عوضش کنید.

مرتبط

آماده استقرار؟ با رمزارز بپرداز، بدون KYC — در حدود یک دقیقه فعال می‌شود.

← همین حالا مستقر کن

سؤالات متداول

چرا تماس‌های WebRTC اصلاً به سرور TURN نیاز دارند؟

‏WebRTC تلاش می‌کند طرفین را مستقیم به هم وصل کند و معمولاً موفق می‌شود. وقتی هر دو طرف پشت NAT متقارن یا فایروالی باشند که UDP را دور می‌ریزد — وای‌فای هتل، شبکه‌های اداری، برخی اپراتورهای موبایل — مسیر مستقیمی وجود ندارد و تماس بی‌صدا شکست می‌خورد. سرور TURN دقیقاً برای همین تماس‌ها رسانه را رله می‌کند؛ سهمی که معمولاً گفته می‌شود حدود یک تماس از هر ده تماس است.

آیا TURN روی پلن NAT اجرا می‌شود؟

نه. کلاینت‌ها به UDP و TCP 3478 و به بازهٔ پورت‌های رله وصل می‌شوند و پلن NAT از بیرون فقط پورت SSH شما را می‌پذیرد. به پلنی با IPv4 اختصاصی نیاز دارید.

چقدر پهنای باند مصرف می‌کند؟

هر جریان رله‌شده دو بار از سرور می‌گذرد — از یک طرف وارد و به طرف دیگر خارج می‌شود. یک تماس تصویری دونفره با ۱ تا ۲ Mbit/s در هر جهت روی سرور چند Mbit/s می‌شود. پردازنده و RAM تقریباً متوجه نمی‌شوند؛ سقف واقعی پورت 1 Gbit/s است.

چرا یک نام کاربری و گذرواژهٔ ثابت در اپ نگذارم؟

چون هرچه در JavaScript مرورگر باشد عمومی است و سرور TURN با گذرواژهٔ لو رفته، رلهٔ رایگانی برای کل اینترنت است. با use-auth-secret بک‌اند شما اعتبارنامه‌هایی صادر می‌کند که منقضی می‌شوند و با رازی امضا شده‌اند که مرورگر هرگز نمی‌بیند.

آیا روی پورت 5349 به TLS نیاز دارم؟

در شبکه‌هایی که UDP را مسدود می‌کنند و با TCP ساده سخت‌گیرند کمک می‌کند. وقتی TURN ساده کار کرد اضافه‌اش کنید: به coturn یک گواهی برای نام میزبان TURN بدهید و 5349/tcp را باز کنید. رله از طریق TLS را هم آزمایش کردیم.

نظرات

هنوز نظری نیست. اولین نفر باشید.

یک نظر بگذارید

نظرات پیش از نمایش بررسی می‌شوند.