−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 עוזר ללקוחות שלא מצליחים להגיע אליו ישירות.
  • כל מודל האבטחה הוא הסוד. החזיקו אותו מחוץ לצד הלקוח, והחליפו אותו אם הוא ידלוף אי פעם.

קשור

מוכנים להקים? שלמו בקריפטו, ללא KYC — חי בערך תוך דקה.

הקימו עכשיו →

שאלות נפוצות

למה שיחות 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.

תגובות

אין עדיין תגובות. היו הראשונים.

השאירו תגובה

התגובות עוברות מודרציה לפני שהן מופיעות.