البته نصب coturn بهتنهایی کافی نیست. برای استفاده واقعی باید realm، Authentication، Public IP، Relay Port Range، Firewall، TLS و در صورت قرارداشتن خود TURN Server پشت NAT، external-ip را درست تنظیم کنید. مهمتر از آن، بعد از نصب باید ثابت کنید که واقعاً یک Candidate از نوع relay ساخته میشود؛ صرف بازبودن پورت 3478 به معنی سالمبودن TURN نیست.
در این آموزش یک TURN Server مناسب WebRTC و VoIP را روی Linux میسازیم، تفاوت STUN و TURN را توضیح میدهیم، دو روش احراز هویت ثابت و زماندار را بررسی میکنیم، TLS را فعال میکنیم و در پایان با ابزارهای خود coturn و تست WebRTC مشخص میکنیم Relay واقعاً کار میکند یا خیر.
نسخه مبنا: در زمان بررسی این مقاله، coturn 4.18.0 آخرین Release رسمی پروژه است. اگر با apt install coturn نصب میکنید، نسخه Repository سیستمعامل الزاماً با آخرین نسخه upstream یکی نیست؛ پس قبل از Upgrade یا استفاده از Optionهای جدید، خروجی turnserver --version را بررسی کنید.
TURN Server چیست و چرا در VoIP لازم میشود؟
در یک تماس ساده، بهترین حالت این است که Media مستقیماً بین دو Endpoint عبور کند.
Browser A
|
| SRTP
v
Browser B / Asterisk
اما اگر یکی از دو طرف پشت:
🔹 CGNAT
🔹 Symmetric NAT
🔹 Firewall سازمانی
🔹 شبکهای با محدودیت UDP
باشد، ICE ممکن است هیچ مسیر مستقیمی پیدا نکند.
در این شرایط TURN وارد مسیر میشود:
Browser
|
| Media
v
TURN Server
|
| Media
v
Asterisk / Peer
تفاوت STUN و TURN چیست؟
STUN معمولاً به Client کمک میکند بفهمد از دید اینترنت با چه Public IP و Port دیده میشود.
TURN خودش یک Relay ایجاد میکند و Media را از Server عبور میدهد.
یعنی STUN میگوید:
«آدرس بیرونی تو این است.»
ولی TURN میگوید:
«اگر نمیتوانی مستقیم وصل شوی، Packetها را به من بده؛ من آنها را به مقصد میرسانم.»
ICE چه نقشی دارد؟
ICE بین Candidateهای مختلف تصمیم میگیرد.
Candidate میتواند:
🔹 host — آدرس محلی
🔹 srflx — آدرس کشفشده با STUN
🔹 prflx — مسیر Peer Reflexive
🔹 relay — آدرس Relay ساختهشده توسط TURN
باشد.
برای تشخیص اینکه coturn واقعاً وارد تماس شده است، Candidate نوع relay بسیار مهم است.
coturn چیست؟
coturn پیادهسازی متنباز TURN و STUN است و برای NAT Traversal در VoIP و WebRTC طراحی شده است.
اجزای مهم آن شامل:
🔹 turnserver برای سرویس اصلی TURN/STUN
🔹 turnadmin برای مدیریت User و Secret
🔹 turnutils_uclient برای تست Relay
🔹 turnutils_peer برای Peer آزمایشی
🔹 turnutils_stunclient برای تست STUN
است.
معماری پیشنهادی برای VoIP
سادهترین معماری Production:
Internet
|
turn.example.com
|
Coturn VPS
Public IP
|
WebRTC Clients / Asterisk
اگر امکانش را دارید، TURN Server را مستقیماً روی Public IP قرار دهید. قرار دادن TURN پشت NAT ممکن است ولی Configuration و Port Mapping حساستر میشود.
پیشنیازها
برای این آموزش نیاز داریم:
🔹 یک VPS لینوکسی با Public IP ثابت
🔹 Ubuntu یا Debian
🔹 یک Domain مانند turn.example.com
🔹 دسترسی Root یا sudo
🔹 Firewall قابلکنترل
مرحله ۱: DNS را تنظیم کنید
یک A Record بسازید:
turn.example.com
|
v
203.0.113.20
IP بالا فقط نمونه مستندسازی است.
بررسی کنید:
dig +short turn.example.com
باید Public IP درست برگردد.
مرحله ۲: coturn را نصب کنید
روی Ubuntu/Debian:
sudo apt update
sudo apt install -y coturn
نسخه را بررسی کنید
turnserver --version
اگر Package Distribution قدیمیتر از نسخه upstream است، الزاماً مشکل ندارید؛ اما Optionهای این آموزش را با `turnserver –help` همان نسخه تطبیق دهید.
مرحله ۳: فایل تنظیمات coturn
در نصب Package معمولاً فایل اصلی:
/etc/turnserver.conf
است.
قبل از ویرایش Backup بگیرید:
sudo cp /etc/turnserver.conf /etc/turnserver.conf.bak
realm در coturn چیست؟
`realm` فقط یک Label تزئینی نیست.
در Long-Term Credential Mechanism، Realm بخشی از فرآیند Authentication و محاسبه Credential است.
برای همین بهتر است Realm پایدار باشد و معمولاً همان Domain سرویس انتخاب میشود:
realm=turn.example.com
Realm را بیدلیل تغییر ندهید
در Credentialهای Long-Term، Key به:
Username + Realm + Password
وابسته است.
اگر Realm تغییر کند، Credentialهای ذخیرهشده نیز ممکن است نیاز به بازسازی داشته باشند.
دو مدل Authentication مهم در coturn
برای WebRTC دو روش اصلی کاربردی داریم.
روش اول: User/Password ثابت
برای Lab، سیستم داخلی یا تعداد محدود Client مناسب است.
از:
lt-cred-mech
استفاده میکنیم.
روش دوم: Credential زماندار
برای Web Application عمومی بهتر است.
در coturn با:
use-auth-secret
static-auth-secret=...
فعال میشود.
برای Production WebRTC کدام بهتر است؟
اگر Browserهای عمومی دارید، بهتر است Secret اصلی را داخل JavaScript قرار ندهید.
Backend شما Credential کوتاهعمر میسازد و برای Client ارسال میکند.
در این صورت حتی اگر Credential در Browser دیده شود، پس از مدت کوتاهی Expire میشود.
نسخه ساده برای شروع: Long-Term User
ابتدا Configuration پایه را میسازیم.
listening-port=3478
tls-listening-port=5349
realm=turn.example.com
server-name=turn.example.com
fingerprint
lt-cred-mech
min-port=49160
max-port=49260
no-multicast-peers
verbose
چرا Relay Range را محدود کردیم؟
Default coturn برای Relay Endpointها:
49152-65535/UDP
است.
برای Lab میتوانید Range کوچکتری تعریف کنید تا Firewall سادهتر باشد.
اما تعداد Portها ظرفیت همزمان Relay را محدود میکند؛ برای Production پرترافیک Range بسیار کوچک انتخاب نکنید.
مرحله ۴: User تست بسازید
بهجای ذخیره Password ساده داخل Config، میتوانید User را با `turnadmin` به Database اضافه کنید.
sudo turnadmin -a \
-u webrtc-test \
-r turn.example.com \
-p 'CHANGE_TO_A_STRONG_RANDOM_PASSWORD'
User را بررسی کنید
sudo turnadmin -l -r turn.example.com
مرحله ۵: Firewall را باز کنید
برای Configuration مثال بالا:
| کاربرد | پورت | پروتکل |
|---|---|---|
| TURN/STUN معمولی | 3478 | UDP/TCP |
| TURN روی TLS | 5349 | TCP |
| DTLS در صورت فعالسازی | 5349 یا Listener انتخابی | UDP |
| Relay Media | 49160-49260 | UDP |
UFW نمونه
sudo ufw allow 3478/udp
sudo ufw allow 3478/tcp
sudo ufw allow 5349/tcp
sudo ufw allow 49160:49260/udp
اگر DTLS Listener را فعال کردهاید و روی UDP 5349 نیاز دارید:
sudo ufw allow 5349/udp
چرا فقط بازکردن 3478 کافی نیست؟
3478 Port کنترل و Allocation است.
بعد از Allocation، coturn یک Relay Endpoint از Range تعریفشده میسازد.
اگر Relay Portها بسته باشند:
Client میتواند TURN Server را ببیند، Authentication موفق شود و حتی Allocation ساخته شود؛ اما Media واقعی عبور نکند.
مرحله ۶: سرویس را Restart کنید
sudo systemctl enable coturn
sudo systemctl restart coturn
sudo systemctl status coturn --no-pager
Logها را ببینید
sudo journalctl -u coturn -n 100 --no-pager
برای مشاهده زنده:
sudo journalctl -u coturn -f
Listenerها را بررسی کنید
sudo ss -lntup | grep -E '3478|5349'
مرحله ۷: اگر Server مستقیماً Public IP دارد
اگر Interface سرور همان Public IP را دارد، معمولاً نیازی به `external-ip` ندارید.
مثلاً:
ip addr
و Public IP روی Interface واقعی دیده میشود.
اگر خود coturn پشت NAT است چه؟
اینجا `external-ip` مهم میشود.
فرض کنیم:
Private IP:
10.20.0.15
Public IP:
203.0.113.20
Configuration:
listening-ip=10.20.0.15
relay-ip=10.20.0.15
external-ip=203.0.113.20/10.20.0.15
NAT باید Port-Preserving باشد
این قسمت بسیار مهم است.
اگر coturn Relay Port:
49180
را تخصیص داده است، NAT باید همان Port عمومی را به همان Port خصوصی Forward کند.
اگر Router Relay Portها را به شمارههای تصادفی دیگری Rewrite کند، `external-ip` بهتنهایی مشکل را حل نمیکند.
بهترین انتخاب برای TURN Server چیست؟
اگر انتخاب دارید:
Public IP مستقیم روی VPS
معمولاً سادهتر، قابلپیشبینیتر و مناسبتر از قرار دادن coturn پشت چند لایه NAT است.
مرحله ۸: TLS را فعال کنیم
برای TURN Secure یک Certificate معتبر برای:
turn.example.com
داشته باشید.
برای مثال Let’s Encrypt.
در coturn:
tls-listening-port=5349
cert=/etc/letsencrypt/live/turn.example.com/fullchain.pem
pkey=/etc/letsencrypt/live/turn.example.com/privkey.pem
Permission فایل Certificate را بررسی کنید
Service User coturn باید بتواند فایل موردنیاز را بخواند.
نباید برای حل مشکل Permission، Private Key را World-readable کنید.
بهجای:
chmod 777 privkey.pem
Permission و Group را اصولی تنظیم کنید.
تست TLS با OpenSSL
openssl s_client \
-connect turn.example.com:5349 \
-servername turn.example.com
Certificate Chain و Expiration را بررسی کنید.
تغییر مهم coturn جدید درباره DTLS
در نسخههای جدید coturn، DTLS Listener دیگر الزاماً بهصورت خودکار Start نمیشود.
اگر واقعاً به TURN over DTLS نیاز دارید، در نسخه جدید باید آن را صریحاً فعال کنید:
dtls
قبل از Copy کردن Configuration قدیمی، `turnserver –help` نسخه نصبشده را بررسی کنید.
برای WebRTC بهتر است چه URLهایی به Client بدهیم؟
حداقل میتوانید UDP و TLS/TCP را ارائه کنید.
مثال JavaScript:
const rtcConfig = {
iceServers: [
{
urls: [
"stun:turn.example.com:3478",
"turn:turn.example.com:3478?transport=udp",
"turns:turn.example.com:5349?transport=tcp"
],
username: "webrtc-test",
credential: "YOUR_TURN_PASSWORD"
}
]
};
const pc = new RTCPeerConnection(rtcConfig);
چرا UDP و TLS/TCP هر دو؟
UDP برای Media Real-Time معمولاً مناسبتر است.
اما برخی شبکههای سازمانی UDP را محدود میکنند.
در این شرایط TURN روی TCP/TLS میتواند مسیر جایگزین باشد.
آیا پورت 443 برای TURN لازم است؟
الزام نیست.
اما در شبکههای بسیار محدود، TURN/TLS روی 443 میتواند عبورپذیری بیشتری داشته باشد.
اگر چنین کاری انجام میدهید، باید مطمئن شوید Port 443 از قبل توسط Nginx/Apache یا سرویس دیگری اشغال نشده است.
TURN over TCP با Media TCP یکی است؟
خیر.
Transport بین Client و TURN Server میتواند TCP/TLS باشد، در حالی که TURN در سمت Relay هنوز UDP Endpoint برای Peer بسازد.
Transport Client-to-TURN و Relay-to-Peer را جدا در نظر بگیرید.
مرحله ۹: TURN را با ابزار خود coturn تست کنیم
اول STUN:
turnutils_stunclient turn.example.com
این ابزار STUN Binding Request میفرستد.
در نسخههای جدید حالت Continuous نیز برای بررسی RTT و Packet Loss دارد.
تست مداوم STUN
turnutils_stunclient -c turn.example.com
برای توقف:
Ctrl+C
تست TURN با turnutils_uclient
برای یک تست ساده Client-to-Client:
turnutils_uclient \
-u webrtc-test \
-w 'YOUR_TURN_PASSWORD' \
-r turn.example.com \
-y \
turn.example.com
`-y` باعث میشود Utility در حالت Client-to-Client تست کند و به Peer خارجی جدا نیاز نداشته باشد.
تست TCP
turnutils_uclient \
-t \
-u webrtc-test \
-w 'YOUR_TURN_PASSWORD' \
-r turn.example.com \
-y \
turn.example.com
تست TLS
`turnutils_uclient` گزینه Secure Connection دارد.
turnutils_uclient \
-t \
-S \
-p 5349 \
-u webrtc-test \
-w 'YOUR_TURN_PASSWORD' \
-r turn.example.com \
-y \
turn.example.com
بهترین تست WebRTC چیست؟
Utility خط فرمان عالی است، اما برای WebRTC باید Candidate واقعی Browser را هم بررسی کنید.
هدف:
Candidate از نوع relay ساخته شود.
Forced Relay Test
برای تست موقت:
const pc = new RTCPeerConnection({
iceServers: [
{
urls: "turn:turn.example.com:3478?transport=udp",
username: "webrtc-test",
credential: "YOUR_TURN_PASSWORD"
}
],
iceTransportPolicy: "relay"
});
اگر Candidate ساخته شد باید نوع:
relay
را ببینید.
اگر relay Candidate ساخته نمیشود
بهترتیب بررسی کنید:
مرحله ۱: DNS.
مرحله ۲: Port 3478/5349.
مرحله ۳: Username/Password یا Credential زماندار.
مرحله ۴: Realm.
مرحله ۵: coturn Log.
مرحله ۶: external-ip در صورت NAT.
مرحله ۷: Relay Range Firewall.
اگر Allocation ساخته میشود ولی Media عبور نمیکند
این نشانه معمولاً ما را به:
🔹 Relay Port Range
🔹 NAT Port Mapping
🔹 Peer Routing
🔹 denied-peer-ip / allowed-peer-ip
هدایت میکند.
Packet Capture روی TURN Server
Listener:
sudo tcpdump -ni any port 3478
Relay Range:
sudo tcpdump -ni any udp portrange 49160-49260
اگر روی 3478 Packet میبینید ولی روی Relay Range چیزی نیست
احتمالاً:
🔹 Allocation کامل نشده است.
🔹 Authentication مشکل دارد.
🔹 Client از Candidate Relay استفاده نکرده است.
اگر Relay Range ورودی دارد ولی خروجی ندارد
بررسی کنید:
🔹 Route سرور
🔹 Peer Permission
🔹 Firewall خروجی
🔹 private/public mapping
روش بهتر Authentication برای Web Application
User/Password ثابت داخل JavaScript مناسب Production عمومی نیست.
برای این حالت coturn از Secret-based Authentication پشتیبانی میکند.
Configuration:
use-auth-secret
static-auth-secret=CHANGE_TO_A_LONG_RANDOM_SECRET
realm=turn.example.com
use-auth-secret و lt-cred-mech را همزمان دستی نگذارید
در Configuration فعلی coturn، `use-auth-secret` بهصورت داخلی بر مکانیزم Long-Term Credential تکیه میکند و بخشی از تنظیمات `lt-cred-mech` را Override میکند.
برای جلوگیری از Configuration مبهم، یکی از دو روش را انتخاب کنید.
Credential زماندار چگونه ساخته میشود؟
Username معمولاً شامل Timestamp است.
مثلاً:
1792242000:user123
Password با HMAC بر اساس Shared Secret تولید میشود.
نمونه PHP برای ساخت Credential کوتاهعمر
<?php
$secret = getenv('TURN_SHARED_SECRET');
$ttl = 3600;
$username =
(time() + $ttl) . ':user123';
$credential = base64_encode(
hash_hmac(
'sha1',
$username,
$secret,
true
)
);
echo json_encode([
'username' => $username,
'credential' => $credential
]);
Shared Secret را داخل Source عمومی یا JavaScript قرار ندهید؛ فقط Backend باید آن را بداند.
چرا Credential زماندار بهتر است؟
اگر User فایل JavaScript یا Network Request را ببیند، Credential دائمی TURN به دست او نمیافتد.
Credential بعد از Timestamp مشخص دیگر معتبر نیست.
Security: TURN Server را Open Relay نکنید
TURN یک Relay شبکه است.
اگر بدون Authentication در اینترنت رها شود، دیگران میتوانند Bandwidth سرور شما را مصرف کنند یا از آن برای Relay Traffic استفاده کنند.
برای WebRTC Production:
Anonymous TURN مناسب نیست.
STUN Anonymous با TURN Anonymous یکی نیست
coturn میتواند STUN Binding را بدون Authentication پاسخ دهد، در حالی که TURN Allocation نیازمند Authentication باشد.
این رفتار طبیعی است.
اگر بخواهید حتی STUN Binding هم Authentication بخواهد، گزینه:
secure-stun
وجود دارد، اما برای هر معماری لازم نیست.
Loopback Peer را برای Production باز نکنید
coturn بهصورت پیشفرض برای جلوگیری از سوءاستفاده، Relay به Loopback را محدود میکند.
گزینه:
allow-loopback-peers
برای محیط Production توصیه نمیشود مگر دقیقاً بدانید چرا لازم است.
Multicast Peer را محدود کنید
برای کاهش Attack Surface:
no-multicast-peers
انتخاب مناسبی است.
Private Network Peerها را هم بررسی کنید
TURN Server میتواند به IPهایی دسترسی داشته باشد که User اینترنتی مستقیماً نمیبیند.
اگر سرور شما داخل شبکه سازمانی نیز Route دارد، با `denied-peer-ip` میتوانید Rangeهایی را که نباید از طریق TURN قابلدسترسی باشند محدود کنید.
Quota برای جلوگیری از مصرف بینهایت
coturn از محدودیت Allocation پشتیبانی میکند.
مثلاً:
user-quota=12
total-quota=1200
این اعداد فقط مثالاند.
عدد واقعی باید بر اساس تعداد کاربران، تماس همزمان و Pattern واقعی WebRTC تعیین شود.
Bandwidth Limit هم وجود دارد
coturn Optionهایی برای:
🔹 محدودیت Bandwidth Session
🔹 ظرفیت کلی Server
دارد.
اما Limit اشتباه میتواند خودش باعث Packet Loss و صدای بد شود.
قبل از محدودسازی Production، Traffic واقعی Codecها را اندازه بگیرید.
Bandwidth موردنیاز TURN را دستکم نگیرید
وقتی TURN Media را Relay میکند، Traffic از Server عبور میکند.
اگر یک تماس Audio در هر جهت دهها کیلوبیت بر ثانیه مصرف کند و هزاران تماس Relay شوند، Bandwidth تجمعی قابلتوجه میشود.
همچنین TURN برای Video بسیار سنگینتر از Voice است.
CPU یا Network؛ کدام Bottleneck است؟
در Relay ساده اغلب Network، PPS و Bandwidth بسیار مهماند.
اگر TLS/DTLS نیز زیاد استفاده شود، Encryption روی CPU اثر بیشتری دارد.
مانیتور کنید:
🔹 Network Mbps
🔹 Packets Per Second
🔹 CPU per Core
🔹 Active Allocations
🔹 Packet Drop
TURN را نزدیک کاربران قرار دهیم یا نزدیک PBX؟
Media از TURN عبور میکند، پس Location اهمیت مستقیم دارد.
اگر همه کاربران در ایران باشند ولی TURN در قارهای دور قرار گیرد، Latency اضافه وارد تماس میشود.
برای سرویس بینالمللی میتوانید چند TURN Server منطقهای داشته باشید.
چند TURN Server برای HA
در Browser میتوانید چند ICE Server معرفی کنید:
iceServers: [
{
urls: [
"turn:turn1.example.com:3478?transport=udp",
"turn:turn2.example.com:3478?transport=udp",
"turns:turn1.example.com:5349?transport=tcp",
"turns:turn2.example.com:5349?transport=tcp"
],
username,
credential
}
]
Browser Candidateها را از Serverهای مختلف میگیرد و ICE تصمیم میگیرد.
DNS Round Robin بهتنهایی HA کامل نیست
اگر `turn.example.com` چند IP داشته باشد، Client ممکن است رفتار متفاوتی در Resolve و Cache داشته باشد.
برای معماری مهم، Health Monitoring و چند URL/Region را جداگانه طراحی کنید.
Monitoring coturn
لاگ Session بهتنهایی کافی نیست.
حداقل این موارد را دنبال کنید:
🔹 Active Allocations
🔹 Authentication Failures
🔹 Allocation Errors
🔹 Bandwidth
🔹 Packet Drop
🔹 CPU
🔹 Relay Port Usage
🔹 TLS Certificate Expiry
Prometheus در نسخههای جدید
Buildهای جدید coturn میتوانند با وابستگی مربوط به Prometheus Metrics ساخته شوند.
اگر این قابلیت را استفاده میکنید، Endpoint مانیتورینگ را بدون Authentication یا Network Restriction روی اینترنت عمومی باز نکنید.
تست Certificate Expiry
echo | openssl s_client \
-connect turn.example.com:5349 \
-servername turn.example.com 2>/dev/null \
| openssl x509 -noout -dates
بعد از تمدید Certificate سرویس را Reload کنیم؟
بعد از تغییر فایل Certificate بررسی کنید coturn نسخه جدید Certificate را واقعاً Load کرده باشد.
در بسیاری از Setupها Restart کنترلشده مطمئنترین راه است:
sudo systemctl restart coturn
قبل از Production بررسی کنید Restart چه اثری روی Allocationهای فعال شما دارد.
Drain قبل از Maintenance
coturn جدید قابلیت Drain Mode نیز دارد تا قبل از Shutdown منتظر کاهش Allocationهای فعال بماند.
این قابلیت برای Rolling Maintenance روی چند TURN Node مفید است.
اگر HA دارید:
Node 1 را از سرویس جدید خارج کنید → Sessionها را Drain کنید → Upgrade کنید → تست کنید → به Pool برگردانید.
Upgrade از نسخههای قدیمی به 4.18
قبل از Upgrade مستقیم:
🔹 Config را Backup کنید.
🔹 `turnserver –help` جدید را مقایسه کنید.
🔹 TLS/DTLS Listenerها را تست کنید.
🔹 Candidate Relay واقعی بگیرید.
🔹 Forced Relay Test اجرا کنید.
در نسخههای 4.17 و بعد تغییر رفتار DTLS مهم است و Configهای قدیمی را نباید بدون تست جایگزین کرد.
مقاله مرتبط ایرانیکاسرور درباره coturn
اگر هدفتان استفاده از TURN برای انتقال فایل مستقیم و PairDrop است، مقاله راهاندازی PairDrop و Coturn روی VPS ایران سناریوی متفاوتی را بررسی میکند. مقاله فعلی مخصوص VoIP، WebRTC، ICE و Relay تماس صوتی نوشته شده است.
سناریوی عیبیابی ۱: 401 Unauthorized
نشانه: Allocation Request با 401 تکراری شکست میخورد.
بررسی:
🔹 Username
🔹 Password
🔹 Realm
🔹 روش Auth انتخابی
علت رایج: User با Realm دیگری ساخته شده است.
رفع: Realm Server و User Credential را یکسان کنید.
سناریوی عیبیابی ۲: Candidate relay نداریم
نشانه: فقط host و srflx دیده میشوند.
بررسی: Browser Console و coturn Log.
علت محتمل: TURN URL یا Authentication مشکل دارد.
تست: `iceTransportPolicy: “relay”`.
سناریوی عیبیابی ۳: Candidate relay داریم ولی صدا نداریم
نشانه: Candidate از نوع relay ساخته شده است.
بررسی: آیا همان Candidate در Selected Pair انتخاب شده؟
اگر بله، Relay Range و Packet Capture را بررسی کنید.
سناریوی عیبیابی ۴: فقط UDP کار نمیکند
اگر:
TURN/TCP یا TURN/TLS کار میکند ولی UDP نه
احتمالاً Firewall، Cloud Security Group یا ISP مسیر UDP را محدود کرده است.
سناریوی عیبیابی ۵: TLS روی 5349 شکست میخورد
بررسی کنید:
🔹 Certificate برای Domain صحیح باشد.
🔹 Full Chain کامل باشد.
🔹 Private Key با Certificate Match باشد.
🔹 Permission فایل مناسب باشد.
🔹 ساعت Server درست باشد.
سناریوی عیبیابی ۶: Server پشت NAT است و Relay IP خصوصی میدهد
`external-ip` را بررسی کنید.
اگر XOR-RELAYED-ADDRESS همچنان Private IP نشان میدهد، Client اینترنتی نمیتواند به Relay Endpoint برسد.
سناریوی عیبیابی ۷: روی VPS کار میکند ولی Docker نه
اگر coturn داخل Docker است باید Listenerها و مخصوصاً Relay Range را Publish کنید.
Repository رسمی برای Docker نمونهای شبیه این دارد:
docker run -d \
-p 3478:3478 \
-p 3478:3478/udp \
-p 5349:5349 \
-p 5349:5349/udp \
-p 49152-65535:49152-65535/udp \
coturn/coturn
اما برای Production باید Version Image را Pin کنید و Configuration، Secret و Certificate را بهصورت کنترلشده Mount کنید.
از latest بدون Version Pin در Production استفاده نکنید
بهتر است Image مشخصی مانند Release مورد تأیید خودتان استفاده شود تا Restart آینده ناگهان نسخه دیگری وارد محیط نکند.
تست نهایی قبل از اتصال به Asterisk
این ترتیب را طی کنید:
مرحله ۱: DNS صحیح است.
مرحله ۲: 3478 و 5349 در حال Listen هستند.
مرحله ۳: STUN Binding پاسخ میدهد.
مرحله ۴: User/Auth صحیح است.
مرحله ۵: TURN Allocation ساخته میشود.
مرحله ۶: Relay Port باز است.
مرحله ۷: Browser Candidate نوع relay میگیرد.
مرحله ۸: Forced Relay Call صدا دارد.
مرحله ۹: TLS Test سالم است.
مرحله ۱۰: سپس TURN را وارد Asterisk/WebRTC Application اصلی کنید.
چرا این ترتیب مهم است؟
اگر مستقیماً TURN را داخل Application اصلی قرار دهید و تماس صدا نداشته باشد، معلوم نیست مشکل از:
🔹 Asterisk
🔹 JavaScript
🔹 ICE
🔹 TURN
🔹 Firewall
است.
TURN را ابتدا بهصورت مستقل Verify کنید.
Configuration پیشنهادی نهایی برای TURN عمومی
نمونه زیر یک Base Configuration است و باید IP، Domain، Port Range و Authentication را با محیط خودتان تطبیق دهید:
listening-port=3478
tls-listening-port=5349
realm=turn.example.com
server-name=turn.example.com
fingerprint
use-auth-secret
static-auth-secret=CHANGE_TO_A_LONG_RANDOM_SECRET
min-port=49152
max-port=65535
cert=/etc/letsencrypt/live/turn.example.com/fullchain.pem
pkey=/etc/letsencrypt/live/turn.example.com/privkey.pem
no-multicast-peers
user-quota=12
total-quota=1200
syslog
اگر Server پشت NAT است، `external-ip` را اضافه کنید.
اگر DTLS لازم دارید و نسخه جدید coturn استفاده میکنید، `dtls` را نیز طبق نیاز فعال کنید.
چه زمانی اصلاً TURN لازم نیست؟
اگر:
🔹 همه Clientها Candidate مستقیم موفق دارند.
🔹 Asterisk Public IP صحیح دارد.
🔹 Firewall و NAT درست هستند.
🔹 کاربران پشت CGNAT سخت نیستند.
ممکن است هیچ تماس واقعی از TURN استفاده نکند.
این اتفاق خوب است؛ TURN باید مسیر Backup باشد، نه اینکه بدون دلیل تمام Media را از یک Relay عبور دهید.
چه زمانی TURN تقریباً ضروری میشود؟
🔹 WebRTC عمومی برای کاربران ناشناس از انواع ISP
🔹 کاربران موبایل پشت CGNAT
🔹 شبکههای شرکتی با NAT/Firewall سخت
🔹 تماسهایی که روی بعضی شبکهها بیصدا هستند
🔹 سرویسی که باید درصد موفقیت اتصال بالایی داشته باشد
پرسشهای رایج
coturn چیست؟
coturn یک TURN/STUN Server متنباز است که برای NAT Traversal در WebRTC و VoIP استفاده میشود و در صورت شکست ارتباط مستقیم میتواند Media را Relay کند.
آخرین نسخه coturn در اکتبر ۲۰۲۶ چیست؟
در زمان بررسی، coturn 4.18.0 جدیدترین Release رسمی پروژه است.
پورت 3478 برای چیست؟
3478 پورت پیشفرض TURN/STUN روی UDP و TCP است. خود Media Relay معمولاً روی Portهای جداگانه از Relay Range عبور میکند.
پورت 5349 برای چیست؟
5349 پورت پیشفرض TURN روی TLS و در صورت فعالسازی DTLS است.
چرا 3478 باز است ولی TURN کار نمیکند؟
ممکن است Authentication یا Realm اشتباه باشد یا Relay Port Range در Firewall بسته باشد. فقط Reachable بودن 3478 سلامت Media Relay را ثابت نمیکند.
realm در coturn چیست؟
Realm بخشی از Long-Term Authentication است و همراه Username و Password در ساخت Credential نقش دارد. بهتر است یک Domain پایدار برای آن انتخاب شود.
آیا TURN Server باید Public IP داشته باشد؟
Public IP مستقیم سادهترین حالت است. اگر coturn پشت NAT باشد باید external-ip و Port Mapping دقیق تنظیم شوند.
چرا Candidate نوع relay ندارم؟
TURN URL، Authentication، Realm، DNS، Listener Port و Logهای coturn را بررسی کنید. Forced Relay Test با iceTransportPolicy برابر relay برای تشخیص بسیار مفید است.
آیا Username و Password ثابت برای WebRTC امن است؟
برای Lab یا سیستم داخلی قابل استفاده است؛ برای Web Application عمومی بهتر است Credentialهای زماندار با use-auth-secret تولید شوند.
آیا TURN تمام تماسها را Relay میکند؟
نه. ICE معمولاً مسیر مناسب را انتخاب میکند و در صورت وجود مسیر مستقیم ممکن است TURN اصلاً استفاده نشود، مگر اینکه iceTransportPolicy روی relay تنظیم شده باشد.
چرا TURN روی UDP کار نمیکند ولی TLS کار میکند؟
معمولاً محدودیت UDP در Firewall، NAT یا شبکه کاربر مطرح است. TURN/TLS روی TCP ممکن است از شبکههای محدود راحتتر عبور کند.
آیا برای Asterisk WebRTC حتماً coturn لازم است؟
خیر. در شبکههایی که ICE مسیر مستقیم پیدا میکند، STUN یا حتی Candidate مستقیم ممکن است کافی باشد. coturn برای شرایطی مهم میشود که Media مستقیم قابل برقراری نیست.
جمعبندی
راهاندازی TURN Server فقط نصب پکیج coturn و بازکردن پورت 3478 نیست. برای یک Relay قابلاعتماد باید Authentication، Realm، Public IP، Relay Port Range، Firewall، TLS و NAT Mapping درست باشند.
برای WebRTC عمومی، استفاده از Credential زماندار با `use-auth-secret` از قرار دادن Username و Password دائمی داخل JavaScript مناسبتر است. Realm را نیز ثابت نگه دارید، چون در Long-Term Credential Mechanism بخشی از محاسبه Credential است.
اگر coturn مستقیماً Public IP دارد، Configuration سادهتر است. اگر پشت NAT قرار دارد، `external-ip` و Port Mapping یکبهیک Relay Portها اهمیت زیادی پیدا میکند.
برای تست نیز فقط با `telnet` یا بازبودن 3478 قانع نشوید. با `turnutils_stunclient`، `turnutils_uclient` و Forced Relay Test مطمئن شوید Allocation واقعی ایجاد میشود و Browser Candidate از نوع `relay` دریافت میکند.
اگر Candidate relay ساخته میشود ولی تماس هنوز صدا ندارد، Selected Candidate Pair، Relay Port Range، Packet Capture و مسیر TURN تا Asterisk را بررسی کنید.
در نهایت، TURN باید بهعنوان مسیر پشتیبان قابلاعتماد برای NATهای دشوار طراحی شود؛ نه راهی برای مخفیکردن مشکلات اشتباه Firewall یا NAT در زیرساخت VoIP.
WebRTC روی بعضی اینترنتها صدا ندارد؟ TURN Server را روی یک VPS مستقل با IP ثابت تست کنید
coturn زمانی بیشترین ارزش را دارد که کاربران شما از شبکههای مختلف، CGNAT، اینترنت موبایل یا Firewallهای سازمانی به سامانه تلفنی متصل میشوند. یک VPS با Public IP مستقیم باعث میشود Configuration مربوط به `external-ip` و NAT پیچیدهتر نشود و Relay Portها نیز قابلکنترلتر باشند.
برای شروع میتوانید coturn را روی یک VPS ایرانیکاسرور جدا از Asterisk راهاندازی کنید، Credential کوتاهعمر بسازید و قبل از اتصال به سامانه اصلی، Forced Relay Test انجام دهید. اگر Candidate نوع `relay` ساخته شد و تماس در حالت Relay صدای دوطرفه داشت، TURN Server شما آماده اتصال به WebRTC Production است.
مشاوره coturn، Asterisk، ICE و WebRTC: 021-91302467






دیدگاهها (۰)