WebRTC服务器Coturn服务器用户管理和安全性
1、概述
1.1、相关术语
1.1.1 realm
在 coturn 服务器中,域(realm)是一种逻辑上的分组概念,用于对不同的用户群体、应用或者服务进行区分和管理,可以用turnadmin工具进行管理域。
可以针对同一服务器不同的域进行权限、连接会话、流量的控制。
1.1.2 origin
在coturn服务器中,源(origin)可以用在多租户或者隔离环境
2、用户管理
coturn的用户主要分为 web的admin用户(web-admin配置),cli用户(telnet访问配置),普通用户
2.1 Coturn服务器的用户类型
2.1.1 web-admin用户
可以通过网页访问管理整个coturn服务器,查看coturn服务器配置,添加普通用户,设置REST API的共享密钥
2.1.2 cli用户
可以通过telnet协议访问查看当前coturn服务器的信息,会话数等操作,这是虚拟的用户,其实无需添加cli用户,只需要在配置文件turnserver.conf配置了cli功能、设置密码即可通过telnet登录coturn服务器进行查看coturn服务器的状态。
2.1.3 普通用户
访问coturn服务器进行通信, 可以在/etc/turnserver.conf中添加认证
2.2 用户访问认证与安全性
coturn支持用户访问认证控制。用户的访问认证机制分为长期凭证机制和临时凭证机制
2.2.1 长期凭证机制(long term credentials mechanism)
定义与作用:基于RFC5389规范,固定用户名+访问密码设置,凭证长期有效
安全性: 安全性比较弱(静态密码容易泄露)
适用场景:可信网络环境
配置: 在turnserver.conf文件配置如(user=test:123)或者通过turnadmin工具添加或者通过web-admin网页访问直接添加用户
2.2.2 临时凭证机制
定义与作用:通过时间戳+共享密钥动态生成的临时凭证,限制凭证有效期,防止重放攻击
安全性:高(动态密码+时间窗口)
适用场景:公网/高风险环境
配置:在turnserver.conf中配置开启use-auth-secret,配置共享密钥(可在配置文件配置static-auth-secret字段来配置共享密钥)或者通过turnadmin工具添加共享密钥方式或者通过web-admin网页设置临时凭证的共享密钥,最终这个密钥会保存在数据库表turn_secret中
2.2.3 临时凭证原理
临时凭证可通过REST API生成,只要按照下面的规则来生成临时的用户名和密码即可安全访问coturn服务器,coturn服务器只设置共享密码(跟REST API用的共享密钥要一样)即可
图1:webrtc客户端获取临时凭证节点图
图2:webrtc通过REST API获取临时凭证后访问coturn时序图
2.2.3.1 用户名生成
临时用户名采用与时间戳组合usercombo: 时间戳:用户名
eg: 1742608315:test
1742608315:代表通信的过期时间,比如当前时间是1742608000,想让此次通信315s,则时间戳为1742608000 + 315
: 分号为时间戳和用户名的组合分割符,默认是冒号:,要是想用别的分割符,可以通过配置文件turnserver.conf配置rest-api-separator=:
test: 临时用户名
2.2.3.2 密码生成
密码的生成采用: base64(hmac(input_buffer = usercombo, key = shared-secret))
凭证的密码生成基于 HMAC-SHA1 算法,通过共享密钥(Secret Key)和动态用户名(含时间戳)usercombo 生成一次性密码
python代码示例生成临时凭证密码代码示例:
import time, hmac, hashlib, base64
# 配置参数
shared_secret = "123456" #共享密钥
user_id = "ccc" #用户ID# 生成时间戳
timestamp = int(time.time()) + 600
# 用时间戳+用户ID,生成临时用户名
usercombo = f"{timestamp}:{user_id}"
# 生成密码
hmac_digest = hmac.new(shared_secret.encode('utf-8'),usercombo.encode('utf-8'),hashlib.sha1).digest()
password = base64.b64encode(hmac_digest).decode('utf-8')
# 得到用户名和密码
print(f"username={usercombo}, password={password}")
2.2.3.3 共享密钥安全性加强
共享密钥(shared-secret)建议采用设置多个,保存在coturn数据库表turn_secret里面(REST API生成也是用那一批共享密钥(shared-secret)),REST API生成时候可随机选择一个共享密钥(shared-secret)生成密码,密码随着shared-secret的不同而变化,这样可以增加黑客的破解难度。
coturn在验证密码时候会遍历表中所有共享密钥,一个一个计算,跟webrtc客户端传过来的密码进行比较。
2.2.3.4 coturn验证用户登录的原理
coturn验证webrtc登录过程其实是验证签名过程。
1)webrtc客户端通过REST API 拿到上面计算的password
2)webrtc客户端内部使用MD5(user:realm:password)计算出key。然后在turn协议中使用HMAC-SHA1和key签名自己的内容,并把签名也附加到内容后面。
3)coturn收到了客户端的username、realm和数据库表中的shared-secrt实时计算出key
4)coturn使用key对客户端传过来的内容进行HMAC-SHA1签名,跟客户端的签名进行对比,如果一样则验证通过(说明: webrtc内部本身没有realm,这个realm是跟coturn登录前握手拿到的,webrtc客户端登录消息提供username、收到的realm和HMAC签名)
备注: coturn验证客户端登录过程,coturn只是去数据库拿到shared-secret列表,验证只是验证消息包的签名而已,安全保证在于shared-secret,如果shared-secret泄露,整个系统就被破解,使用多个shared-secret的目的为了增加黑客碰撞猜测shared-secret的难度,但是只要一个shared-secret被破解,那么整个系统也就被破解。