5分钟搞定 coturn 认证:长期密钥 vs 临时凭证怎么选
2026/9/16 21:02:05 网站建设 项目流程

5分钟搞定 coturn 认证:长期密钥 vs 临时凭证怎么选

【免费下载链接】coturncoturn TURN server project项目地址: https://gitcode.com/GitHub_Trending/co/coturn

凌晨两点,告警群炸了:移动网络下的 WebRTC 通话大面积掉线,客户端日志满屏 401 Unauthorized。排查到最后,问题出在 coturn 认证上——新环境里没显式开任何认证机制,服务器直接跑在匿名模式,所有客户端的重新认证都打了空。coturn 是 TURN 服务器(NAT 穿透媒体中继,WebRTC 打洞失败时让媒体流量"借道"中转的保底通道)的主流开源实现,它的认证只有两种玩法:长期密钥和临时凭证。选哪种、怎么配,直接决定了你的 401 是消失还是刷屏。

(认证流程示意)

这张图里最该关注的节点是get_user_key——两种机制最终都汇到src/apps/relay/userdb.c里的这一个函数,分叉只发生在函数内部,所以读源码时盯住它就行。第二个值得注意的点是 401 挑战是必经之路:客户端第一次永远不带完整凭证,攻击者也可以伪造源地址疯狂"骗"401,拿它做 UDP 放大,后文清单里有对应的防护参数。

先选型:哪种 coturn 认证方案匹配你的场景

先给结论:长期密钥适合"用户是固定资产"的场景,临时凭证(TURN REST API,一种用共享密钥现算限时用户名密码的机制)适合"用户是流水"的场景。两者不能同时生效,coturn 官方明确建议二选一,配置里写哪个就按哪个来。

  • 用户数固定、总量小于 100、认证频率低、内部系统 → 长期密钥(lt-cred-mech,命令行参数-a)
  • 用户动态生成、高并发、需要按用户统计流量 → 临时凭证(use-auth-secret)
  • 合规要求凭证必须短命、泄露后风险可控 → 只有临时凭证
  • 两种都没配、也没写任何user=→ 服务器回落到匿名访问,这是最危险的默认值

TURN 长期密钥配置:lt-cred-mech 最小可运行配置

一句话原理:预置的用户名密码,每次认证校验 HMAC 完整性,凭证永久有效。

这里的 HMAC 校验(一种用共享密钥生成"数字封条"的完整性验证方式,类似快递封条被拆就发现被调包)是这样用的:客户端用密码算出校验值填进 MESSAGE-INTEGRITY 字段,服务器用同一份密码重算,对不上就 401。

关键流程:

  1. 服务器启动,把user=条目加载进内存
  2. 客户端请求不带完整性,服务器回 401 挑战
  3. 挑战携带 realm(认证域,客户端算 HMAC 必须带同一个值),客户端参与计算
  4. 服务器按用户名取密钥,重算并比对完整性
  5. 通过则分配中继端口,开始转发

下面这段在仓库examples/目录下直接复制运行,开长期密钥认证并启用 TLS(证书文件在examples/etc/):

cd examples turnserver --syslog -a \ --user=ninefingers:youhavetoberealistic \ --user=gorst:hero \ --realm=north.gov \ --cert=etc/turn_server_cert.pem \ --pkey=etc/turn_server_pkey.pem

参数里-a就是--lt-cred-mech;--realm决定 401 挑战里携带的 realm,两端不一致必然认证失败。user=后面除了明文密码,还可以填turnadmin算出的 0x 开头密钥,这条命令的输出可以直接回填:

turnadmin -k -u ninefingers -r north.gov -p youhavetoberealistic # 输出 0xbc807ee29df3c9ffa736523fb2c4e8ee

生产环境建议用密钥形式而不是明文密码,配置文件泄露时多一层缓冲。

coturn 临时凭证生成:时间戳 + 共享密钥的 HMAC 方案

一句话原理:用户名里塞时间戳,密码是共享密钥的 HMAC,凭证随时间自然失效。

关键流程:

  1. 客户端拼出时间戳:userid作为用户名
  2. 用共享密钥对该用户名算 HMAC-SHA1
  3. HMAC 结果做 base64 编码,作为密码
  4. 服务器解析时间戳,过去的时间直接拒绝
  5. 逐个 secret 重算并比对完整性,通过即放行

第 4 步有个容易忽略的细节:服务器只拒绝"已经过期"的时间戳,没有偏移容忍参数,客户端时钟落后于服务器就会认证失败。服务端最小可运行配置(同样在examples/下运行):

cd examples turnserver --syslog \ --use-auth-secret \ --static-auth-secret=logen \ --realm=north.gov \ --cert=etc/turn_server_cert.pem \ --pkey=etc/turn_server_pkey.pem

客户端侧生成凭证的小脚本,密钥与服务器--static-auth-secret保持一致:

NOW=$(date +%s) U="${NOW}:alice" P=$(printf '%s' "$U" | openssl dgst -sha1 -hmac logen -binary | base64)

跑完后$U$P就是这次会话的用户名和密码。建议每次会话前重新生成,有效期按 300 秒掌握,userid 部分填你的业务用户 ID,流量统计就能落到具体人头上。

⚠️ 上线前必踩的 3 个坑

⚠️ 症状:临时凭证稳定 401,时钟快几分钟没事、慢 5 秒就挂。根因:服务器只拒绝过去的时间戳,没有偏移容忍参数。修复:客户端开 NTP 同步,时钟偏差控制在秒级。

⚠️ 症状:同时配了lt-cred-mechuse-auth-secret,静态用户全部认证失败。根因:两种机制互斥,user=静态条目在 REST API 模式下不生效。修复:删掉多余的user=行,二选一改完重启验证。

⚠️ 症状:重启后测试发现任何人不用密码都能建会话。根因:没配用户、没开机制时 coturn 默认 no-auth 匿名放行。修复:显式加-a--use-auth-secret,再用turnutils_uclient验证一次拒绝。

coturn 认证安全与运维清单(可抄进 runbook)

选型对比统一放这,前文不再重复:

维度长期密钥 lt-cred-mech临时凭证 use-auth-secret
凭证生命周期永久,换密码才失效由时间戳决定,自然过期
用户存储配置文件user=或数据库无用户表,只存 secret
流量归属固定用户名可统计userid 可统计到人
泄露后果密码泄露等于永久后门密钥泄露仍可换钥止损
  • TURN 流量走 TLS:配置cert=pkey=,客户端连 5349 端口
  • 会话配额:-q 100(单用户最多 100 个会话)、-Q 300(服务器总量 300 个)
  • 开 401 洪泛防护:unauthorized-ratelimitunauthorized-ratelimit-rps=10(每 IP 每秒最多回 10 个 401)
  • 临时凭证按 300 秒有效期生成,客户端与服务器时钟走 NTP,偏差控制在秒级
  • 长期密钥不用明文密码,turnadmin -k生成 0x 密钥后回填--user=
  • stale-nonce=600保持默认,nonce 10 分钟后强制重新认证
  • 两种机制二选一,配置里不要同时出现lt-cred-mechuse-auth-secret

延伸入口

  1. 全量参数与默认值看 docs/Configuration.md。
  2. 想看两种机制的真实分叉,读src/apps/relay/userdb.cget_user_keyuse_auth_secret_with_timestamp分支,不到百行。
  3. 直接跑起来:git clone https://gitcode.com/GitHub_Trending/co/coturn后执行examples/scripts/restapi/secure_relay_secret.sh(临时凭证)和examples/scripts/longtermsecure/secure_relay.sh(长期密钥)。

【免费下载链接】coturncoturn TURN server project项目地址: https://gitcode.com/GitHub_Trending/co/coturn

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询