−25%

cho Windows trả theo năm, đến 31/10. Xem các gói

EQVPS
Bắt đầu

VPS cho máy chủ TURN (coturn) cho WebRTC

Cuộc gọi thất bại sau NAT khắt khe cần một relay TURN. coturn trên máy chủ có IPv4 riêng: cổng, thông tin đăng nhập có hạn, cấu hình đã kiểm thử và gói phù hợp.

Ứng dụng WebRTC của bạn chạy trên Wi-Fi của bạn và thất bại với đúng vị khách gọi từ khách sạn. Âm thanh và hình ảnh peer-to-peer cần một đường đi giữa hai phía; khi cả hai nằm sau NAT khắt khe, hoặc tường lửa chặn UDP, không có đường và cuộc gọi đơn giản là không kết nối. Không ai thấy lỗi — chỉ thấy “đang kết nối…” mãi không dứt.

Máy chủ TURN là phương án dự phòng cho đúng những cuộc gọi đó: cả hai phía gửi dữ liệu tới nó, và nó chuyển tiếp. Nếu bạn đang đưa video hay giọng nói vào ứng dụng, chạy Matrix hay Jitsi cho một nhóm, hoặc làm voice chat cho game, bạn cần một máy chủ như vậy. coturn là bản cài đặt mã nguồn mở tiêu chuẩn, và nó nhẹ.

Chọn gói nào

TURN tốn rất ít CPU và bộ nhớ. Thứ nó dùng là băng thông: mỗi luồng được chuyển tiếp đi qua máy chủ hai lần, vào và ra. Lưu lượng trên các gói của chúng tôi không giới hạn ở 1 Gbit/s, nên câu hỏi là có bao nhiêu cuộc gọi chuyển tiếp chạy cùng lúc, chứ không phải bạn bị tính bao nhiêu tiền.

Số cuộc gọi chuyển tiếp cùng lúcGói
Vài cuộc — một nhóm, một ứng dụng nhỏNano-IP: 2 vCPU, 1 GB, 15 GB ($8/tháng)
Vài chụcMicro-IP: 2 vCPU, 2 GB, 25 GB ($10/tháng)
Nhiều hơn, hoặc TURN cạnh máy chủ ứng dụngSmall-IP: 4 vCPU, 4 GB, 35 GB ($16/tháng)

Phải là gói có IPv4 riêng — TURN hoàn toàn dựa vào kết nối đi vào trên nhiều cổng, còn gói NAT chỉ nhận SSH từ bên ngoài. Trên các gói có IP riêng của chúng tôi, địa chỉ công khai nằm ngay trên giao diện mạng của máy chủ, nên coturn tự tìm thấy mà không cần dòng external-ip. Đặt máy chủ gần người dùng: Đức hoặc Phần Lan, tình trạng còn chỗ hiển thị khi đặt hàng. Thanh toán bằng crypto, không cần KYC, nếu điều đó quan trọng với bạn.

Các cổng cần mở: 3478 UDP và TCP, 49152–65535 UDP cho dữ liệu chuyển tiếp, và 5349 TCP nếu bạn thêm TLS.

Cài đặt và cấu hình

Với quyền root trên Ubuntu 24.04 hoặc Debian 12:

apt install -y coturn
ip -4 addr    # IP công khai của bạn phải có trên interface

Ghi cấu hình với một bí mật dùng chung mới:

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 của bạn cần giá trị này
systemctl restart coturn
ufw allow 22/tcp && ufw allow 3478 && ufw allow 49152:65535/udp && ufw enable

Đừng bỏ các dòng denied-peer-ip. Thiếu chúng, bất kỳ ai có thông tin đăng nhập hợp lệ cũng có thể dùng relay của bạn để tới các địa chỉ riêng — kể cả dịch vụ ở phía nội bộ của chính máy chủ. Chúng tôi đã kiểm tra: có các dòng này, relay tới địa chỉ riêng bị từ chối với “403 Forbidden IP”.

Thông tin đăng nhập có hạn

Với use-auth-secret, coturn chấp nhận tên người dùng chứa thời điểm hết hạn và mật khẩu là HMAC của tên đó. Backend của bạn tạo ra chúng; bí mật không bao giờ rời phía máy chủ. Bằng Node.js:

const crypto = require("crypto");

// Tên người dùng/mật khẩu TURN tạm thời (lược đồ TURN REST API mà coturn hiểu qua 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")));

Trong trình duyệt, hãy xin backend một cặp mới và đưa nó cho 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,
    },
  ],
});

Kiểm tra

Từ máy chủ, theo cùng sơ đồ bằng openssl (nó cho ra đúng mật khẩu như mã Node.js — chúng tôi đã so):

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

Cuối cùng bạn muốn thấy “Total lost packets 0”. Với mật khẩu sai, client dừng ở “Cannot complete Allocation” — đó là máy chủ đang làm đúng việc.

Chúng tôi cũng đã kiểm tra từ một Chromium thật: với iceTransportPolicy: "relay" và thông tin đăng nhập mới, trình duyệt nhận được relay candidate từ máy chủ; với mật khẩu sai thì không có cái nào. Nếu muốn thử cấu hình của bạn theo cách tương tự, hãy bật tùy chọn đó một lúc — nó buộc mọi cuộc gọi đi qua TURN.

TLS, nếu cần

Một số mạng chặn UDP và khó tính với TCP thường; TURN qua TLS đi lọt được nhiều mạng hơn. Lấy chứng chỉ cho turn.example.com (certbot là được). Tệp của nó chỉ root đọc được, trong khi coturn chạy dưới người dùng turnserver, nên hãy cho coturn một bản sao riêng:

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

Thêm turns:turn.example.com:5349?transport=tcp vào danh sách urls. Chứng chỉ có thời hạn ngắn, nên hãy đưa bước sao chép vào deploy hook của certbot — nếu không, TLS sẽ âm thầm hỏng ở lần gia hạn đầu tiên.

Nên biết

  • TURN không biến kết nối kém thành kết nối tốt. Nó thêm một chặng, nên hãy đặt máy chủ gần những người cần nó.
  • Nếu bạn chạy SFU — ví dụ videobridge của Jitsi — đó là một thành phần riêng. TURN giúp các client không tới được nó trực tiếp.
  • Toàn bộ mô hình bảo mật nằm ở bí mật. Giữ nó ngoài frontend, và đổi nó nếu có lúc bị lộ.

Liên quan

Sẵn sàng triển khai? Thanh toán bằng crypto, không KYC — trực tuyến trong khoảng một phút.

Triển khai ngay →

FAQ

Vì sao cuộc gọi WebRTC lại cần máy chủ TURN?

WebRTC cố kết nối trực tiếp các bên, và thường thành công. Khi cả hai phía nằm sau NAT đối xứng hoặc tường lửa chặn UDP — Wi-Fi khách sạn, mạng văn phòng, một số nhà mạng di động — không có đường trực tiếp và cuộc gọi thất bại lặng lẽ. Máy chủ TURN chuyển tiếp âm thanh và hình ảnh cho đúng những cuộc gọi đó; tỷ lệ hay được nhắc đến là khoảng một trên mười cuộc gọi.

TURN có chạy được trên gói NAT không?

Không. Client kết nối tới UDP và TCP 3478 và tới dải cổng relay, còn gói NAT từ bên ngoài chỉ nhận cổng SSH của bạn. Bạn cần gói có IPv4 riêng.

Nó dùng bao nhiêu băng thông?

Mỗi luồng được chuyển tiếp đi qua máy chủ hai lần — vào từ một phía, ra tới phía kia. Một cuộc gọi video một-một ở 1–2 Mbit/s mỗi chiều là vài Mbit/s trên máy chủ. CPU và RAM gần như không hay biết; giới hạn thật sự là cổng 1 Gbit/s.

Sao không đặt luôn tên người dùng và mật khẩu cố định trong ứng dụng?

Vì mọi thứ trong JavaScript của trình duyệt đều công khai, và một máy chủ TURN có mật khẩu bị lộ là relay miễn phí cho cả internet. Với use-auth-secret, backend của bạn cấp thông tin đăng nhập có hạn, được ký bằng một bí mật mà trình duyệt không bao giờ thấy.

Tôi có cần TLS trên cổng 5349 không?

Nó hữu ích ở những mạng chặn UDP và khắt khe với TCP thường. Hãy thêm vào khi TURN thường đã chạy: cấp cho coturn chứng chỉ cho tên máy TURN và mở 5349/tcp. Chúng tôi cũng đã thử relay qua TLS.

Bình luận

Chưa có bình luận nào. Hãy là người đầu tiên.

Để lại bình luận

Bình luận được kiểm duyệt trước khi hiển thị.