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被破解,那么整個系統也就被破解。