You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS托管Coturn服务器调试:TURN正常,STUN异常排查

Coturn部署问题与测试情况

部署环境与配置

Coturn配置(turnserver.conf)

listening-port=3478
external-ip=(external ip)/(internal ip)
relay-ip=(internal ip)
tls-listening-port=5349
verbose
realm=(realm name)
min-port=10000
max-port=20000
lt-cred-mech
user=(username):(password)

AWS安全组设置

  • 开放3478和5349端口的所有IPv4、IPv6的TCP、UDP流量

Trickle ICE测试结果

测试1:指定TCP传输的TURN地址(正常)

服务器地址:turn:(public ip):3478/?transport=tcp(携带用户名和凭证)

客户端侧输出

Time    Type    Foundation  Protocol    Address Port    Priority    URL (if present)    relayProtocol (if present)
0.012   host    1419492315  udp e97c311c-26d9-4083-bfd9-bf004d561c76.local  65276   126 | 30 | 255      
0.124   relay   2654650372  udp (external ip)   16106   1 | 31 | 255    turn:(external ip):3478?transport=tcp   tcp
0.137   Done

服务器侧日志

Jan 30 13:32:55 ip-(private ip) turnserver: 28: : session 000000000000000001: new, realm=<(realm name)>, username=<(username)>, lifetime=600
Jan 30 13:32:55 ip-(private ip) turnserver: 28: : session 000000000000000001: realm <(realm name)> user <(username)>: incoming packet ALLOCATE processed, success
Jan 30 13:32:55 ip-(private ip) turnserver: 28: : session 000000000000000001: refreshed, realm=<(realm name)>, username=<(username)>, lifetime=0
Jan 30 13:32:55 ip-(private ip) turnserver: 28: : session 000000000000000001: realm <(realm name)> user <(username)>: incoming packet REFRESH processed, success
Jan 30 13:32:55 ip-(private  ip) turnserver: 28: : session 000000000000000001: TCP socket closed remotely (client ip):43114
Jan 30 13:32:55 ip-(private ip) turnserver: 28: : session 000000000000000001: usage: realm=<(realm name)>, username=<(username)>, rp=3, rb=228, sp=3, sb=288
Jan 30 13:32:55 ip-(private ip) turnserver: 28: : session 000000000000000001: peer usage: realm=<(realm name)>, username=<(username)>, rp=0, rb=0, sp=0, sb=0
Jan 30 13:32:55 ip-(private ip) turnserver: 28: : session 000000000000000001: closed (2nd stage), user <(username)> realm <(realm name)> origin <>, local (internal ip):3478, remote (client ip):43114, reason: TCP connection closed by client (callback)
Jan 30 13:32:55 ip-(private  ip) turnserver: 28: : session 000000000000000001: delete: realm=<(realm name)>, username=<(username)>

测试2:不指定传输协议的TURN地址(异常)

服务器地址:turn:(public ip):3478(携带用户名和凭证)

客户端侧输出

Time    Type    Foundation  Protocol    Address Port    Priority    URL (if present)    relayProtocol (if present)
0.008   host    3474466919  udp e97c311c-26d9-4083-bfd9-bf004d561c76.local  53711   126 | 30 | 255      
0.020   srflx   710326477   udp (client ip) 34426   100 | 30 | 255  stun:(external ip):3478 
0.100   relay   2859376398  udp (external ip)   14926   2 | 31 | 255    turn:(external ip):3478?transport=udp   udp
0.136   Done

报错信息:服务器stun:(external ip):3478返回错误码701:STUN server address is incompatible.

服务器侧日志

Jan 30 13:45:30 ip-(private ip) turnserver: 783: : session 000000000000000002: new, realm=<(realm name)>, username=<(username)>, lifetime=600
Jan 30 13:45:30 ip-(private ip) turnserver: 783: : session 000000000000000002: realm <(realm name)> user <(username)>: incoming packet ALLOCATE processed, success
Jan 30 13:45:30 ip-(private ip) turnserver: 783: : session 000000000000000002: refreshed, realm=<(realm name)>, username=<(username)>, lifetime=0
Jan 30 13:45:30 ip-(private ip) turnserver: 783: : session 000000000000000002: realm <(realm name)> user <(username)>: incoming packet REFRESH processed, success
Jan 30 13:45:31 ip-(private ip) turnserver: 784: : session 000000000000000002: usage: realm=<(realm name)>, username=<(username)>, rp=4, rb=248, sp=4, sb=384
Jan 30 13:45:31 ip-(private ip) turnserver: 784: : session 000000000000000002: peer usage: realm=<(realm name)>, username=<(username)>, rp=0, rb=0, sp=0, sb=0
Jan 30 13:45:31 ip-(private ip) turnserver: 784: : session 000000000000000002: closed (2nd stage), user <(username)> realm <(realm name)> origin <>, local (private ip):3478, remote (client ip):34426, reason: allocation timeout
Jan 30 13:45:31 ip-(private ip) turnserver: 784: : session 000000000000000002: delete: realm=<(realm name)>, username=<(username)>

测试3:STUN地址(异常)

服务器地址:stun:(external ip):3478

客户端侧输出

Time    Type    Foundation  Protocol    Address Port    Priority    URL (if present)    relayProtocol (if present)
0.004   host    1256359617  udp e97c311c-26d9-4083-bfd9-bf004d561c76.local  62013   126 | 30 | 255      
0.021   srflx   2080670375  udp (client ip) 38039   100 | 30 | 255  stun:(external ip):3478 
0.127   Done

报错信息:服务器stun:(external ip):3478返回错误码701:STUN server address is incompatible.

服务器侧日志

Jan 30 13:56:08 ip-(private ip) turnserver: 1421: : session 001000000000000001: realm <(realm name)> user <>: incoming packet BINDING processed, success

疑问

  1. 为何在地址中添加transport=tcp参数后,服务器行为会出现差异?不加该参数时,客户端不仅尝试连接STUN服务器并报错,连接关闭原因也不同(客户端关闭TCP连接 vs 分配超时)。
  2. 是否需要指定transport=tcp?添加该参数后TURN服务器似乎能正常工作。
  3. 我的STUN配置存在什么问题?目前STUN完全无法正常工作,调整turnserver.conf的各项参数后仍未解决。

问题解答

1. TCP与UDP传输的差异原因

Coturn默认优先用UDP传输,当你不指定transport=tcp时:

  • 客户端先发起STUN绑定请求(TURN地址默认包含STUN功能),但AWS实例的NAT环境下,Coturn通过UDP返回的地址可能和客户端请求的公网IP不匹配——比如返回了实例内部IP,或者返回的公网IP与请求目标IP不一致,触发错误码701(地址不兼容)。
  • 虽然服务器日志显示ALLOCATE请求处理成功,但UDP的RELAY地址无法被客户端正常访问,导致客户端没有发送后续的REFRESH或数据,最终服务器因分配超时关闭会话。

指定transport=tcp时:

  • TCP是面向可靠连接的协议,Coturn会通过TCP正确返回配置的external-ip作为RELAY地址,客户端能正常验证地址匹配,流程顺利完成,最后由客户端主动关闭连接。

2. 是否需要指定transport=tcp?

不是必须,取决于你的场景:

  • 大部分公共网络允许UDP,优先用UDP的延迟更低、开销更小。但如果遇到UDP被防火墙/运营商拦截的情况,TCP作为 fallback 是必要的。
  • 你当前UDP测试异常,核心是AWS NAT转发导致的地址匹配问题,应该先修复UDP配置,而不是只依赖TCP。

3. STUN配置的问题与修复

错误码701的核心原因是:Coturn通过UDP返回的STUN绑定地址,与客户端请求的STUN服务器地址不一致。针对AWS环境,可按以下步骤修复:

  1. 检查端口开放:AWS安全组要开放10000-20000端口的UDP流量——你之前只提到开放3478和5349,而RELAY用的是这个端口段,这是UDP分配超时的关键原因。
  2. 补充Coturn配置:在turnserver.conf中添加:
    # 允许STUN无认证访问(STUN默认不需要凭证)
    no-stun-auth
    # 显式指定监听所有网卡,确保能接收来自任意IP的请求
    listening-ip=0.0.0.0
    listening-ip=::
    
  3. 确认公网IP类型:确保实例使用的是弹性公网IP(EIP),而非临时公网IP——临时IP可能导致Coturn返回的地址与实际访问地址不匹配。
  4. 重启Coturn:修改配置后重启服务,再测试STUN,此时服务器返回的地址应该与客户端请求的公网IP一致,即可解决701错误。

内容的提问来源于stack exchange,提问作者Luke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 10:45:53