coturn配置的核心结论是:修改/etc/turnserver.conf这一个文件就能完成90%的工作,但真正让WebRTC连接稳定,你需要先分清楚STUN和TURN的适用场景。
coturn配置入门:先分清STUN与TURN的区别
很多朋友一上来就照着网上的教程抄配置,结果部署完发现视频通话还是卡顿、掉线。行业共识认为,大部分问题的根源在于把STUN和TURN混为一谈,以为只要搭了个coturn服务,所有NAT穿透问题就都解决了。
STUN(Session Traversal Utilities for NAT) 的作用是帮你找到自己的公网IP和端口映射,它适用于解决锥型NAT(Full Cone、Restricted Cone、Port Restricted Cone) 下的连接问题,当你的网络环境是完整的锥型NAT时,STUN服务器就能轻松帮双方建立直接连接,媒体流不经过服务器中转,延迟最低。
TURN(Traversal Using Relays around NAT) 则是STUN的兜底方案,当遇到对称型NAT(Symmetric NAT) 或者企业级防火墙策略时,STUN无法打通P2P通道,TURN服务器就必须介入,负责中转所有媒体数据,注意,一旦走TURN中继,带宽成本会显著上升,一个1080P视频通话的流量消耗大概是直连的3倍。
coturn 配置的核心决策就是确认你的服务是否需要启用TURN中继。 如果只是做局域网内的WebRTC演示,完全可以只开STUN功能甚至全关TURN,但如果面对的是跨运营商、跨地域的真实用户,TURN功能必须完整开启。
coturn安装与部署:从源码编译到systemd托管
coturn安装路径主要有三种方式,我推荐你看完再选,避免装到一半卡住。
apt直接安装(适合Ubuntu/Debian快速验证)
sudo apt-get update sudo apt-get install coturn
这种方式装出来的版本可能不是最新的,但对于绝大多数生产环境已经足够,装完后服务默认是停着的,需要你去修改/etc/default/coturn文件,把那一行的注释去掉,设置TURNSERVER_ENABLED=1,否则服务启动后马上自动退出。
源码编译(适合需要最新TLS或特定修补的场景)
源码编译coturn需要先安装依赖库,这里给出编译前的必备依赖项,你可以直接复制执行:
sudo apt-get install libssl-dev libevent-dev libhiredis-dev libpq-dev libmysqlclient-dev wget https://github.com/coturn/coturn/archive/refs/tags/4.6.2.tar.gz tar -xzf 4.6.2.tar.gz cd coturn-4.6.2 ./configure make sudo make install
编译过程大概需要5到10分钟,安装完成后,二进制文件会默认放在/usr/local/bin/目录下。行业共识认为

,源码编译的优势在于可以针对特定的openssl版本做适配,但升级维护成本较高。
Docker容器化部署
如果是容器化部署,coturn配置需要注意容器的网络模式。 因为TURN协议涉及多个端口(默认是3478和5349),并且需要监听UDP和TCP,推荐使用host网络模式,否则端口映射会非常痛苦:
docker run -d --network=host \ -v /etc/turnserver.conf:/etc/turnserver.conf \ coturn/coturn
无论用哪种方式,最终都要落到配置文件上,你需要先停下来问自己一个问题:你打算怎么管理用户认证? 是静态密钥,还是临时REST API生成凭据?这会直接改变turnserver.conf里的参数。
手把手修改turnserver.conf文件:关键参数逐个拆解
把这个配置文件放到/etc/turnserver.conf路径下,我用一个最小可用的配置来解释每个参数的具体作用和场景,方便你理解后再修改成自己的配置。
基础监听端口与IP绑定
listening-port=3478 tls-listening-port=5349 listening-ip=你的服务器内网IP relay-ip=你的服务器内网IP external-ip=你的服务器公网IP/内网IP
这里重点解释external-ip,如果服务器在NAT后面,这个参数必须有,它的格式是公网IP/内网IP,如果服务器直接拥有独立公网IP,可以直接写公网IP,很多用户反馈”coturn设置好了但客户端就是连不通”,大多数情况就是漏掉了external-ip这个参数,导致TURN返回给客户端的候选地址是内网IP,客户端根本路由不过去。
用户认证:static-auth-secret与fingerprint
use-auth-secret static-auth-secret=这是一个随机生成的超长字符串 fingerprint
use-auth-secret配合static-auth-secret是关键,这个模式允许你通过REST API动态生成临时的用户名和密码,用户名需要遵循timestamp:userid的格式,该机制可以让你在业务后端控制用户的连接权限,当用户不再活跃时,天然过期。
coturn配置认证方式时,不建议使用lt-cred-mech(长期凭证机制)。 这种方式要求你把用户名和密码写在配置文件里,且密码传输用明文,安全隐患大,动态认证则不用每加一个用户就重启一次服务。
日志输出与详细级别
verbose log-file=/var/log/turnserver.log
调试阶段务必打开verbose,注意,这个日志文件会以非常快的速度增长,生产环境建议配合logrotate使用,先在这里把级别打开,等稳定后再关掉。

测试coturn配置是否生效:用turnutils与官方工具
配置完成后,重启服务:
sudo systemctl restart coturn
然后查看端口监听情况:
ss -ulpn | grep 3478
确认UDP和TCP端口都在监听后,进入测试环节。
本地测试turnutils_uclient
coturn自带一个客户端工具turnutils_uclient,在服务器本机执行:
turnutils_uclient -T -p 3478 -u 账号 -w 密码 你的服务器公网IP
密码就是通过static-auth-secret生成的临时凭证,如果输出中大量出现Success字样,说明TURN中继转发基本正常。如果只出现Fail,优先检查防火墙是否放行了UDP 3478端口和TURN的relay端口范围。
外网穿透测试
建议使用在线WebRTC检测工具(如trickle-ice页面)进行测试,输入你的TURN服务器地址和凭证,如果生成的candidate列表里同时出现了srflx类型和relay类型,说明配置已经生效了。
测试环境与实际用户环境的差异在于防火墙策略。 很多服务器在云控制台还需要额外配置安全组规则,仅打开系统内防火墙是不够的,如果你用的是简米云或酷番云,需要同时检查安全组入方向规则。
coturn证书配置:放通TLS 5349端口和wss的支持
移动端Safari和部分新版Chrome浏览器要求TURN服务器必须使用TLS,否则拒绝连接,这就是证书的用武之地。
通过Let’s Encrypt获取证书
假设你的TURN服务器域名是turn.example.com,使用certbot获取证书:
sudo certbot certonly --standalone -d turn.example.com
拿到证书后,在turnserver.conf中加入以下配置:
cert=/etc/letsencrypt/live/turn.example.com/fullchain.pem pkey=/etc/letsencrypt/live/turn.example.com/privkey.pem
coturn证书配置有个容易踩坑的点:私钥文件的权限。 coturn通常以turnserver用户运行,如果证书文件权限是600且属主是root,服务会启动失败。
sudo chown turnserver:turnserver /etc/letsencrypt/live/turn.example.com/privkey.pem
注意,Let’s Encrypt证书90天过期且自动续期后,需要重启coturn才能加载新证书,可以在certbot的renewal钩子里加上systemctl restart coturn。
证书配置后的防火墙策略变化
放了证书后,除了原有的UDP 3478端口,你还需要额外放通

TCP 5349端口,注意,TURN over TLS的默认端口是5349,WebRTC还需要通过TCP 443端口回退,coturn支持复用443端口,但你需要额外监听该端口:
tls-listening-port=443
如果你的服务器上已经跑了Nginx或Apache,那么443端口会冲突,这种情况下,建议保持5349,不要强行占用443。如果确实想用443端口,需要先停掉Web服务或者改用SNI代理(不推荐,比较复杂)。
常见coturn配置陷阱与性能调优
局域网内部署coturn服务器的场景差异
搭建coturn适合什么场景呢? 比如企业内部网络中有多个子网,或者用户分布在不同的办公区域互相无法直接P2P连接,这时候,你可以在公司内部的一台Linux服务器上部署coturn,配置方法和公网完全一致,只需要保证其他业务服务器和客户端能路由到这台服务器即可。
这种情况下,external-ip可以省略,因为内网环境没有NAT。但需要注意fingerprint参数,如果不开,部分WebRTC客户端会拒绝使用该服务器。
带宽与连接数限制
coturn默认不限制带宽。但实际部署时,建议关注单个用户的连接时长和并发会话数。 一个中型的4核8G服务器,跑coturn大概能同时支撑1000个左右的并发TURN会话(取决于媒体流的码率),如果视频码率是2Mbps,那么服务器出口带宽至少需要2Gbps才能支撑全部中继。
如果日志中出现大量的400错误码,多数是因为用户名和密码的时间戳过期,如果出现437错误码,那是认证失败,请检查你是否正确生成了临时用户名的格式。
Q&A:coturn配置常见问题排查
第一个问题:为什么coturn配置好了,手机端还是连线不上?
确认三件事:第一,external-ip是否正确设置了公网IP;第二,服务器安全组是否正确开放了UDP和TCP的3478、5349端口;第三,TURN凭证是否在有效期内,部分安卓WebView内核会强制使用TLS,若你的TURN没有配证书,需要在客户端侧允许UDP传输协议。
第二个问题:coturn的turnserver.conf修改后,如何确认配置生效?
修改文件后执行sudo systemctl restart coturn,然后执行sudo systemctl status coturn查看服务状态,如果是active (running),再查看/var/log/turnserver.log中的启动日志,里面会明确打印当前监听的地址和端口,还可以用turnutils_uclient -v详细模式连接,确认输出结果没有异常,就可以认为配置已生效。
