The most important point: an external TURN server should be configured as a fallback for clients that cannot establish a usable WebRTC path because of NAT or restrictive firewalls. It is not a replacement for the Jitsi Videobridge (JVB) in normal multiparty meetings. If your Jitsi server itself is behind NAT, you must still make JVB reachable from the Internet, normally on UDP 10000, or configure the bridge's advertised public address correctly.
For current Jitsi deployments, the cleanest design is usually a publicly reachable coturn host with a DNS name such as turn.example.com, time-limited credentials supplied by Prosody through XEP-0215, and TURN over UDP/TCP plus TURN over TLS for restrictive networks. Jitsi's current TURN documentation explicitly recommends dynamic credentials instead of embedding a permanent username and password in browser configuration. See the official Jitsi TURN setup documentation .
Jitsi media should use the normal bridge path when possible, while the external TURN server provides a fallback for clients on restrictive networks.
When an external TURN server is the right solution
Use TURN when some participants can open the Jitsi web page but cannot establish reliable media, especially from corporate networks, hotel Wi-Fi, campuses, mobile carriers, VPNs, or other environments that block or heavily filter UDP. TURN is also useful for one-to-one Jitsi calls when peer-to-peer connectivity cannot be established directly.
Do not treat TURN as the first fix for a misconfigured Jitsi Videobridge. The official Jitsi Debian/Ubuntu guide says that when the server is behind NAT, the router must forward the required ports and the bridge may need an explicit local-to-public address mapping. By default, the important Jitsi-facing ports are TCP 443 and UDP 10000. Review the current Jitsi self-hosting guide for Debian/Ubuntu before adding TURN.
Symptom or requirement What to check first
Two users fail to connect directly on restrictive networks TURN is a strong candidate.
Three or more participants have no audio/video Verify JVB UDP 10000 and its public address before blaming TURN.
Users on normal home networks work, but corporate users fail Add TURN/TLS, preferably reachable on TCP 443 if your network design allows it.
You want credentials that are not permanently exposed in JavaScript Use Prosody external services with a shared secret and short-lived credentials.
Step 1: Prepare a public TURN host and DNS
โครงสร้างเครือข่ายที่ง่ายที่สุดคือการใช้ VM หรือเซิร์ฟเวอร์แยกต่างหากที่มีที่อยู่ IP สาธารณะ สร้างเรคอร์ด A หรือ AAAA ที่turn.example.comสามารถระบุไปยังโฮสต์นั้นได้ ชื่อโฮสต์ที่เฉพาะเจาะจงนั้นมีประโยชน์อย่างยิ่งหากคุณจะให้บริการ TURN ผ่าน TLS ในภายหลัง เนื่องจากใบรับรองจะต้องตรงกับชื่อโฮสต์ที่ไคลเอ็นต์ใช้
หากโฮสต์ TURN อยู่หลัง NAT เอง coturn จำเป็นต้องทราบที่อยู่สาธารณะที่ควรประกาศ coturn รองรับexternal-ipการแมป รวมถึงคู่ที่อยู่สาธารณะ/ส่วนตัว เช่น เอกสารประกอบยังระบุด้วยว่าพอร์ตรีเลย์ต้องได้รับการแมปอย่างสม่ำเสมอผ่าน NAT โปรด ดู ตัวอย่างการกำหนดค่า coturn external-ip=203.0.113.10/192.168.1.10อย่างเป็นทางการ
โดยทั่วไปแล้ว การเปิดเผยโฮสต์ TURN สาธารณะแยกต่างหากจะทำได้ง่ายกว่าและสม่ำเสมอกว่าการเปิดเผยบริการ TURN ที่ซ่อนอยู่หลังเครือข่ายส่วนตัวเดียวกันกับ Jitsi
ขั้นตอนที่ 2: ติดตั้ง coturn
บนระบบ Debian หรือ Ubuntu ที่รองรับ ให้ติดตั้ง coturn จากที่เก็บซอฟต์แวร์ของระบบปฏิบัติการ:
sudo apt update
sudo apt install coturn
เวอร์ชันของแพ็กเกจจะแตกต่างกันไปตามรุ่นของระบบปฏิบัติการ ดังนั้นอย่าคัดลอกหมายเลขเวอร์ชันจากภาพหน้าจอหรือเซิร์ฟเวอร์อื่น หลังจากติดตั้งแล้ว โปรดตรวจสอบว่าหน่วยบริการมีอยู่จริงและแพ็กเกจได้รับการติดตั้งเรียบร้อยturnserverแล้ว
ติดตั้ง coturn โดยใช้ตัวจัดการแพ็กเกจบนโฮสต์ TURN เฉพาะ โดยเวอร์ชันของแพ็กเกจที่ใช้จะขึ้นอยู่กับเวอร์ชันของ Linux ที่ใช้งาน
ขั้นตอนที่ 3: กำหนดค่า coturn สำหรับการตรวจสอบสิทธิ์ด้วยรหัสลับร่วมกัน
สำหรับ Jitsi การตั้งค่าใช้งานจริงจะใช้กลไกการใช้รหัสลับร่วมกันของ coturn เพื่อให้ Prosody สามารถสร้างข้อมูลรับรอง TURN ชั่วคราวได้ ควรใช้รหัสลับเดียวกันทั้งสองฝั่ง จุดเริ่มต้นขั้นต่ำจะมีลักษณะดังนี้:
listening-port=3478
tls-listening-port=5349
realm=turn.example.com
fingerprint
use-auth-secret
static-auth-secret=REPLACE_WITH_A_LONG_RANDOM_SECRET
min-port=49160
max-port=49200
no-multicast-peers
no-cli
หากโฮสต์ TURN อยู่หลัง NAT ให้เพิ่มexternal-ipการแมปที่เหมาะสม หากคุณเปิดใช้งาน TURN ผ่าน TLS ให้กำหนดค่าcertและpkeyใช้ใบรับรองที่เชื่อถือได้สำหรับturn.example.comเอกสารประกอบคอนเทนเนอร์ coturn อย่างเป็นทางการอธิบายว่า TURN ใช้ช่วงพอร์ตรีเลย์สำหรับสื่อ และสามารถจำกัดช่วงให้แคบลงได้ด้วยmin-portและmax-portดูเอกสารประกอบ Docker ของ coturn อย่างเป็นทางการ สำหรับพฤติกรรมพอร์ตรีเลย์เดียวกัน
การตั้งค่า coturn ทั่วไปประกอบด้วยพอร์ตผู้รับฟัง รหัสลับร่วม ช่วงพอร์ตรีเลย์ และการแมป IP ภายนอก เมื่อโฮสต์ TURN อยู่หลัง NAT
ขั้นตอนที่ 4: เปิดพอร์ตผู้ฟังและพอร์ตรีเลย์
ข้อผิดพลาดที่พบบ่อยคือ การเปิดพอร์ต 3478 หรือ 5349 เพียงอย่างเดียว โดยลืมกำหนดช่วงพอร์ตรีเลย์ ตัวรับฟังของ Coturn จะยอมรับการเชื่อมต่อ TURN ครั้งแรก แต่สื่อที่ส่งต่อจะใช้พอร์ตรีเลย์ที่จัดสรรไว้ หากคุณเลือกช่วงพอร์ตดังกล่าว49160-49200โปรดอนุญาตช่วงพอร์ตเดียวกันนั้นผ่านไฟร์วอลล์ของโฮสต์ กลุ่มความปลอดภัยบนคลาวด์ และ NAT ต้นทางใดๆ ด้วย
sudo ufw allow 3478/udp
sudo ufw allow 3478/tcp
sudo ufw allow 5349/tcp
sudo ufw allow 49160:49200/udp
หากคุณต้องการความเข้ากันได้สูงสุดกับเครือข่ายองค์กรที่มีการรักษาความปลอดภัยอย่างเข้มงวด คู่มือ TURN ของ Jitsi อธิบายถึงการให้บริการ TURN ผ่าน TLS บนพอร์ต TCP 443 ซึ่งอาจต้องใช้ชื่อโฮสต์ TURN เฉพาะ และเมื่อเว็บ HTTPS ใช้ที่อยู่สาธารณะเดียวกัน อาจต้องใช้การมัลติเพล็กซ์ TLS SNI อย่าทำการย้าย TURN ไปยังพอร์ต 443 โดยพลการ เว้นแต่คุณจะเข้าใจว่าพอร์ตนั้นถูกใช้งานโดยใครอยู่แล้ว
ไฟร์วอลล์ต้องอนุญาตทั้งตัวรับฟัง TURN และช่วงพอร์ตรีเลย์ที่เลือกไว้ใน coturn
ขั้นตอนที่ 5: กำหนดค่า Jitsi เพื่อประกาศบริการ TURN ภายนอก
ในการติดตั้งแพ็กเกจ Jitsi บน Debian/Ubuntu ในปัจจุบัน Prosody ใช้mod_external_servicesเพื่อเผยแพร่ข้อมูล STUN/TURN ไปยังไคลเอ็นต์ ตัวอย่าง Prosody ของ Jitsi เองใช้ ตาราง external_service_secretที่มีรหัสลับที่ใช้ร่วมexternal_servicesกัน โดยsecret = trueรหัสลับที่ใช้ร่วมกันจะต้องตรงกับรหัสลับของstatic-auth-secretcoturn
external_service_secret = "REPLACE_WITH_THE_SAME_LONG_RANDOM_SECRET";
external_services = {
{ type = "stun", host = "turn.example.com", port = 3478 },
{ type = "turn", host = "turn.example.com", port = 3478,
transport = "udp", secret = true, ttl = 86400, algorithm = "turn" },
{ type = "turns", host = "turn.example.com", port = 5349,
transport = "tcp", secret = true, ttl = 86400, algorithm = "turn" }
};
เก็บโมดูลและค่าการตั้งค่าเฉพาะไซต์ที่มีอยู่เดิมในไฟล์ Prosody ที่สร้างโดย Jitsi ไว้ อย่าแทนที่ไฟล์ทั้งหมดด้วยโค้ดตัวอย่างด้านบน ชื่อไฟล์ที่ถูกต้องมักจะตรงกับโดเมนการใช้งานของคุณ คุณ/etc/prosody/conf.d/สามารถตรวจสอบตัวอย่างการกำหนดค่า Jitsi ต้นทางได้ใน ที่เก็บโค้ดอย่างเป็นทางการ ของJitsi
หากคุณใช้การปรับใช้ Docker อย่างเป็นทางการ โปรดใช้ตัวแปรสภาพแวดล้อมที่ระบุไว้ในเอกสารแทนการแก้ไขไฟล์ Prosody ที่สร้างขึ้นด้วยตนเอง เอกสาร Docker ปัจจุบันแสดงค่าTURN_CREDENTIALS, TURN_HOST, TURN_PORT, TURN_TRANSPORT, TURNS_HOST, และTURNS_PORTโปรดตรวจสอบคู่มือการโฮสต์ Docker ด้วยตนเองของ Jitsi ในปัจจุบัน เนื่องจากค่าเริ่มต้นของตัวแปรอาจเปลี่ยนแปลงได้ระหว่างเวอร์ชันต่างๆ
ก่อนทำการเปลี่ยนแปลง Jitsi โปรดตรวจสอบให้แน่ใจว่าชื่อโฮสต์ TURN สามารถใช้งานได้ และ coturn กำลังทำงานเพื่อรับฟังการเชื่อมต่อบนพอร์ตการขนส่งที่คาดไว้
ขั้นตอนที่ 6: รีสตาร์ทและตรวจสอบความถูกต้องของบริการ
หลังจากเปลี่ยนค่า coturn แล้ว ให้รีสตาร์ทโปรแกรมและตรวจสอบสถานะ:
sudo systemctl restart coturn
sudo systemctl status coturn
sudo ss -lntup | grep -E '3478|5349'
หลังจากเปลี่ยนการตั้งค่า Prosody แล้ว ให้ตรวจสอบไวยากรณ์หากแพ็กเกจ Prosody ของคุณมีตัวตรวจสอบ จากนั้นรีสตาร์ท Prosody ทั้งนี้ ขึ้นอยู่กับสิ่งที่คุณเปลี่ยนแปลงใน Jitsi การรีสตาร์ทบริการ Jitsi ที่เกี่ยวข้องก็อาจเหมาะสมเช่นกัน:
sudo prosodyctl check config
sudo systemctl restart prosody
สถานะบริการ coturn ที่สะอาดหมดจดนั้นพิสูจน์ได้เพียงว่า daemon กำลังทำงานอยู่เท่านั้น ไม่ได้พิสูจน์ว่าข้อมูลรับรองตรงกัน ช่วง relay สามารถเข้าถึงได้ หรือเบราว์เซอร์สามารถค้นหา relay candidate ได้
ใช้การตรวจสอบสถานะบริการและตัวรับฟังเป็นขั้นตอนการตรวจสอบความถูกต้องเบื้องต้น เนื่องจากเวลาประทับและรหัสกระบวนการจะแตกต่างกันไปในแต่ละเซิร์ฟเวอร์
รีสตาร์ทเฉพาะบริการ Jitsi ที่ได้รับผลกระทบจากการเปลี่ยนแปลงการตั้งค่าของคุณ จากนั้นทดสอบด้วยการใช้งานเบราว์เซอร์ใหม่
ขั้นตอนที่ 7: ทดสอบว่า TURN สามารถส่งต่อสื่อได้จริงหรือไม่
การทดสอบจากเครือข่าย LAN เดียวกันนั้นไม่เพียงพอ ควรใช้ไคลเอนต์อย่างน้อยหนึ่งตัวบนเครือข่ายอื่น โดยควรเป็นเครือข่ายมือถือหรือเครือข่ายที่ทราบว่าจำกัดการใช้งาน UDP ในการวินิจฉัย WebRTC ในเบราว์เซอร์ ให้มองหา ICE candidate ประเภทrelay. relay candidate หมายความว่าเบราว์เซอร์ได้รับข้อมูลรับรอง TURN และสร้างการจัดสรร TURN ได้สำเร็จ
นอกจากนี้ ให้สังเกตบันทึก coturn ขณะที่ผู้ใช้ทดสอบเข้าร่วม คุณควรเห็นการจัดสรรที่ได้รับการตรวจสอบสิทธิ์และการรับส่งข้อมูลรีเลย์เมื่อเลือก TURN หากคุณพบข้อผิดพลาดในการตรวจสอบสิทธิ์ ให้เปรียบเทียบ coturn static-auth-secretกับรหัสลับรับรอง TURN ของ Prosody หรือ Docker หากการจัดสรรสำเร็จ แต่สื่อยังคงล้มเหลว ให้ตรวจสอบไฟร์วอลล์พอร์ตรีเลย์และการแมป NAT
อย่าบังคับให้ระบบเปิด-ปิด (TURN) เพียงเพื่อพิสูจน์ว่าเซิร์ฟเวอร์มีอยู่จริง เว้นแต่คุณจะมีเหตุผลในการทดสอบที่ควบคุมได้ ภายใต้สภาวะปกติ ICE จะเลือกเส้นทางการทำงานที่ดีที่สุด ดังนั้น การใช้งานที่ประสบความสำเร็จจึงอาจมีการประชุมหลายครั้งที่ไม่จำเป็นต้องใช้ TURN เลย
ขั้นตอนที่ 8: แยกการตั้งค่า JVB NAT ออกจากการแก้ไขปัญหา TURN
นี่คือจุดที่ช่วยป้องกันการเสียเวลาในการแก้ไขปัญหาโดยเปล่าประโยชน์มากที่สุด เซิร์ฟเวอร์ Jitsi ที่อยู่หลัง NAT ยังคงต้องการการกำหนดค่าการเข้าถึงสาธารณะของบริดจ์อย่างถูกต้อง คู่มือเริ่มต้นใช้งาน Jitsi ฉบับปัจจุบันระบุว่าบริดจ์จะกำหนดค่าตัวเองโดยอัตโนมัติ แต่หากการโทรขนาดใหญ่ล้มเหลว คุณสามารถเพิ่มการแมปแบบคงที่ได้ภายice4j.harvest.mappingใต้/etc/jitsi/videobridge/jvb.conf:
ice4j {
harvest {
mapping {
static-mappings = [
{
local-address = "192.168.1.20"
public-address = "203.0.113.20"
}
]
}
}
}
ส่งต่อพอร์ต UDP 10000 จากขอบเครือข่ายสาธารณะไปยังโฮสต์ JVB และตรวจสอบให้แน่ใจว่าที่อยู่สาธารณะนั้นเป็นที่อยู่เดียวกับที่ไคลเอ็นต์ระยะไกลสามารถเข้าถึงได้จริง ฟังก์ชัน TURN อาจช่วยไคลเอ็นต์ในเครือข่ายที่มีข้อจำกัดได้ แต่ไม่ควรใช้เพื่อปกปิดการแมป NAT ของ JVB ที่ผิดพลาด
สถาปัตยกรรมที่ต้องการนี้จะทำให้ JVB สามารถเข้าถึงได้โดยตรงสำหรับสื่อทั่วไป ในขณะที่ TURN จะยังคงเป็นตัวเลือกสำรองสำหรับเครือข่ายที่ไม่สามารถใช้เส้นทางโดยตรงได้
รายการตรวจสอบการแก้ไขปัญหาอย่างรวดเร็ว
ชื่อโฮสต์ TURN ไม่สามารถแก้ไขได้: แก้ไข DNS ก่อนทดสอบ Jitsi
3478/5349 รับฟังการเชื่อมต่อในพื้นที่ แต่ไม่รับฟังการเชื่อมต่อจากระยะไกล: ตรวจสอบไฟร์วอลล์ของโฮสต์ ไฟร์วอลล์คลาวด์ NAT ของเราเตอร์ และการกรองของผู้ให้บริการ
ข้อมูลรับรองไม่ถูกต้อง: ตรวจสอบว่ารหัสลับที่ใช้ร่วมกันนั้นตรงกันทั้งใน coturn และการตั้งค่า Jitsi/Prosody
ปรากฏตัวเลือกรีเลย์ แต่สื่อล้มเหลว: ตรวจสอบว่าช่วงพอร์ตรีเลย์ที่กำหนดค่าไว้เปิดใช้งานได้ตั้งแต่ต้นจนจบ
เฉพาะการโทรแบบหลายฝ่ายที่ล้มเหลว: ตรวจสอบ JVB UDP 10000 และการประกาศที่อยู่สาธารณะของ JVB
มีเพียงเครือข่ายขององค์กรเท่านั้นที่ล้มเหลว: เพิ่มหรือตรวจสอบ TURN ผ่าน TLS ซึ่งมักจะใช้พอร์ต TCP 443 ตามความเหมาะสม
การเปลี่ยนแปลงใน Docker จะหายไปหลังจากรีสตาร์ท: ให้กำหนดค่าตัวแปรที่รองรับ.envแทนการแก้ไขไฟล์ที่สร้างขึ้นภายในคอนเทนเนอร์
ผลลัพธ์ที่ถูกต้องควรมีลักษณะอย่างไร
การตั้งค่าที่ดีควรมีพฤติกรรมที่สังเกตได้สามประการ ประการแรก ผู้ใช้ทั่วไปสามารถเข้าถึง Jitsi Videobridge ได้โดยตรงโดยไม่ต้องใช้ TURN เมื่อเครือข่ายของพวกเขารองรับ ประการที่สอง ผู้ใช้ในเครือข่ายที่มีข้อจำกัดสามารถรับข้อมูลรับรอง TURN ชั่วคราวและรับrelayICE candidate ได้ ประการที่สาม coturn จะแสดงการจัดสรรที่ได้รับการตรวจสอบสิทธิ์เฉพาะเมื่อจำเป็นเท่านั้น แทนที่จะแสดงการประชุมทุกครั้งโดยค่าเริ่มต้น
การผสมผสานนี้ช่วยให้คุณมีทางเลือกสำรองที่มีประโยชน์โดยไม่ทำให้เซิร์ฟเวอร์ TURN กลายเป็นคอขวดด้านแบนด์วิดท์โดยไม่จำเป็น นอกจากนี้ยังช่วยให้การแก้ไขปัญหาทำได้ง่ายขึ้น: ปัญหา JVB NAT ก็ยังคงเป็นปัญหาของ JVB ในขณะที่ TURN แก้ปัญหาเฉพาะด้านของการเชื่อมต่อ WebRTC เมื่อเส้นทางตรงถูกบล็อก