在虚拟机里部署TURN服务,核心路径是安装coturn、修改turnserver.conf、放行端口、验证中继,四步走完就能给WebRTC接入可靠的中继穿透。很多人卡在“服务起来了但客户端还是连不通”这一步,多数情况下不是coturn本身的问题,而是配置里少了一个参数,或者防火墙漏放了一段端口,下面按真实部署顺序把每一步讲透。
turn服务器和stun服务器有什么区别?选错会直接影响连接成功率
先搞清楚TURN是干什么的,WebRTC建立点对点连接时,第一步走STUN做NAT穿透,让两个终端找到对方的公网地址映射,但穿透不是百分百能成,对称型NAT、企业防火墙、运营商级NAT这些场景下,STUN直接失效,这时候就得靠TURN服务器做中继转发,媒体流绕道服务器中转,代价是带宽成本直线上升,好处是连接几乎必达。
业内专家指出,TURN中继消耗的带宽是STUN的数十倍,所以很多产品优先依赖STUN,打洞失败才降级到TURN,这意味着你选型时心里要有数:
- 仅STUN:适合公网IP互访、内网测试场景,零带宽成本。
- 同时部署STUN+TURN:适合生产环境,尤其是视频会议、在线教育、远程桌面这类必须保证连通的场景。
- 只部署TURN:TURN内部实现了STUN的binding请求,反过来当STUN用,但没必要这么干。
TURN和STUN不是二选一,而是兜底关系。 搭建时如果只盯STUN,线上出现“前几分钟正常,后面一半用户掉线”的情况,大概率就是打洞失败却没有中继兜底。
虚拟机安装coturn详细教程:从装包到跑通全流程
coturn是目前开源TURN服务的事实标准,活跃维护,功能覆盖TURN/STUN,下面以Ubuntu 22.04虚拟机为例,Debian系操作完全一致。
第一步:安装coturn
sudo apt update sudo apt install coturn -y
安装完成后确认版本:
coturn -v
Ubuntu的coturn包安装后默认带一份较完整的配置模板,但服务默认是关闭状态,装完先不急着启动,改完配置再说。
第二步:写turnserver.conf配置文件
coturn的配置文件在/etc/turnserver.conf,可以用模板改,也可以直接清空重写一份干净的,核心参数如下:
listening-port=3478 relay-port-range=49160-49200 fingerprint lt-cred-mech user=webrtc:your_password realm=yourdomain.com no-tls no-dtls
逐行解释:
- listening-port:UDP/TCP监听端口,默认3478,是RFC标准,一般不改。
- relay-port-range:中继分配端口范围,按需定义,每路通话会占用2个UDP端口(RTP/RTCP),并发100路的话,200个端口起步。
- fingerprint:给STUN消息加指纹属性,协商时需要,WebRTC场景必开。
- lt-cred-mech:开启长期凭证机制,不开启的话,coturn不会校验你配置的用户密码,客户端拿错误凭证也能连上,生产环境必须开。
- user:格式是
用户名:密码,明文写进去没问题,coturn重启时会提示权限警告,忽略即可,也可以先用turnadmin -k -u webrtc -r yourdomain.com生成密钥,再把返回的密文填进去。 - realm:认证域,填你域名或服务器IP都行,但前后必须一致,客户端用域名连接时,realm写域名。
- no-tls / no-dtls:暂时没有证书时关掉TLS监听,生产环境装好证书后删掉这两行,改配cert和pkey。
还有一个关键参数,external-ip,虚拟机如果跑在NAT网络下,或者用的是云服务器(私网IP+公网EIP),必须把内网IP映射到公网IP:
external-ip=你的公网IP/虚拟机内网IP
例如external-ip=203.0.113.5/192.168.1.100,这一行漏掉的话,客户端会拿到一个内网中继地址,连过来直接被网卡丢掉,多数“部署成功但连不通”的案例都栽在这里。
第三步:启动服务并检查状态
启动前先确认配置文件语法没有问题:
sudo turnserver -c /etc/turnserver.conf -o
-o参数让进程前台运行,如果配置有问题会直接打印错误,确认没报错后,Ctrl+C停掉,用systemd正式启动:
sudo systemctl enable coturn sudo systemctl start coturn
检查监听状态:
sudo ss -ulpn | grep 3478
看到UD6监听就说明服务起来了。
不加这两个细节,虚拟机的TURN多半是白搭
虚拟机场景有两件事和物理机部署不同,值得单独讲。
本地NAT网络转发,虚拟机如果用的是VirtualBox或VMware的NAT模式,宿主机外部访问虚拟机的3478端口需要手动做转发,VirtualBox里是“端口转发”规则,VMware是“NAT设置”,把宿主机的3478和49160-49200转发到虚拟机的相同端口,桥接模式则跳过这一步。
云服务器安全组,酷番云、简米云的服务器即使防火墙全开,安全组没放行端口一样白搭,3478端口需要同时放行TCP和UDP,中继端口段49160-49200只放UDP,控制台操作时注意别只开TCP,UDP漏了会导致媒体流无声或卡顿。
turn服务器搭建后如何测试?两个命令验证中继链路
服务启动不等于真正可用,coturn自带两个命令行测试工具,装完coturn就在系统里,路径在/usr/bin/turnutils_stunclient和/usr/bin/turnutils_uclient。
测STUN穿透
turnutils_stunclient 你的服务器IP
输出末尾能看到公网IP和端口映射信息,就说明STUN功能正常。
测TURN中继分配
turnutils_uclient -p 3478 -u webrtc -w your_password 你的服务器IP
看到输出里出现relay分配的行,带有IP和端口,说明TURN中继建立成功。
IPv4. Address of relay: 192.0.2.10:50201
这一行代表中继地址分配到位,如果报401 Unauthorized,回头检查user和密码是否与turnserver.conf里一致,如果卡住不动,大概率是3478的UDP端口被防火墙拦了。
命令行测试通过之后,还有个网页端验证方法,打开Trickle ICE测试页面,输入STUN/TURN服务器地址和凭证,点击Gather candidates,能看到relay类型的candidate(服务器反射地址)就算完整通链,这一步验证的是浏览器到TURN服务器的真实链路,比命令工具更能代表实际WebRTC场景。
生产环境部署TURN必须处理的三件硬事
测试环境跑通后,上线前还要补齐三件事,缺一件都可能导致线上事故。
TLS证书,WebRTC强制要求安全上下文,TURN服务器没有TLS证书的话,Chrome和Firefox会直接拒绝连接,用Let’s Encrypt免费证书就行:
cert=/etc/letsencrypt/live/yourdomain.com/fullchain.pem pkey=/etc/letsencrypt/live/yourdomain.com/privkey.pem
配置好删掉turnserver.conf里的no-tls和no-dtls,重启coturn,默认的5349端口就开始提供TLS服务。
认证管理,多用户场景不要手动加user条目,写个脚本调用turnadmin -a -u 用户名 -r realm -p 密码批量添加,用户密码存数据库,coturn支持开源的coturnREST API,但简单运维用turnadmin逐条加也完全够。
日志监控,配置里加一行:
log-file=/var/log/coturn.log
排错时看日志比看任何文档都管用,中继分配失败、认证失败、端口绑定冲突都会在这里留下记录,syslog模式也行,但独立文件好查找。
常见报错排查清单
遇到连不通的问题,按顺序检查下面几项,基本能定位九成故障:
- 3478端口无响应:先用
nc -vz 服务器IP 3478测TCP,再用nc -vuz测UDP,TCP通UDP不通,在防火墙和安全组里找UDP放行问题。 - 认证失败401:检查turnserver.conf里的user和realm,注意realm必须与客户端传递的realm一致,大小写敏感。
- 客户端拿不到relay地址:看
external-ip是否配置,公网IP是否与服务器实际出网IP一致。 - 中继地址连不通:relay-port-range的UDP端口段没有放行,或者虚拟机NAT模式下端口未转发。
- 服务启动报端口占用:
lsof -i :3478查占用进程,多半是重复启动的turnserver。
turn服务器配置常见问题Q&A:免费服务、端口和虚拟机网络
免费TURN服务和自建TURN服务哪个靠谱?
公共免费TURN服务(比如Google公开的turn:turn.example.com)只适合demo验证,并发限制、带宽限制、地域延迟都是问题,国内访问海外免费TURN服务延迟动辄两三百毫秒,视频通话体验完全不行,自建TURN的成本就是一台最便宜云服务器的月租,简米云或酷番云的入门规格一年几百元,生产环境从延迟和稳定性角度都更可控。
虚拟机桥接模式和NAT模式对TURN服务分别有什么影响?
桥接模式下虚拟机直接占用局域网IP,和物理机地位一样,不需要额外端口转发,配置最省心,NAT模式下宿主机必须发起端口转发,把3478和relay端口段映射到虚拟机,否则外部流量进不来,云服务器的“私有网络”本质上就是一种NAT,所以也必须配置external-ip,否则客户端拿到私网中继地址直接不通。
只放行3478端口能不能满足TURN服务使用?
不能,3478是控制信令端口,负责STUN binding和TURN allocate请求,真正传输音视频媒体的RTP/RTCP流量走的是relay-port-range定义的动态端口,只开3478会导致客户端能分配中继地址,但媒体流传不动,表现为画面卡在“连接中”或对方听不到声音,放行规则建议把relay端口段的UDP全部放行,TCP可不开。
把端口、认证、IP映射三件事做对,虚拟机上的TURN服务就能稳定跑起来,建议部署后保留turnutils_uclient的测试记录,后续升级系统或迁移机房时拿来回归,比什么都管用。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/626406.html





