37

我已经构建了 coturn 并成功运行它。ip:192.168.1.111。现在我面临的问题是通过 REST API 获得 Turn 凭证。 https://datatracker.ietf.org/doc/html/draft-uberti-behave-turn-rest-00根据段落请求格式应该是

GET /?service=turn&username=mbzrxpgjys

和响应应该是JSON。现在我的问题是:

a) 如何配置和命令 TURN SERVER 使其在REST API模式下运行?

b) 如何以正确的格式编写 http 请求以便TURN SERVER正确回复?你能给我举个例子吗?

4

7 回答 7

66

这里需要澄清的几件事是:

  • GET /?service=turn&username=mbzrxpgjys它返回一个 JSON,只是一个建议的uri,用于从服务器检索限时TURN 凭据,您不必遵循它,您的 uri 可以只是/?giveMeCredentials. 事实上,我使用我的套接字连接来检索这些数据,而不是直接使用 json 响应进行 http 调用。一天结束,只要它们有效,您(使用所述 TURN 的客户端)如何获得这些凭据并不重要。

  • 您不直接向 TURN 服务器发出任何请求,对 TURN 服务器的其余 api调用不在您的控制之下。

  • 您在启动 TURN 服务器时分配了一个密钥,这可以从 db 中获取(因此可以动态更改),但是我很懒,只是硬编码,并在 turn 配置文件中提供了它,还记得启用REST API。作为转弯命令的一部分,turnserver ... --use-auth-secret --static-auth-secret=MySecretKey

  • 现在,在您的应用程序服务器中,您将使用相同的密钥来生成凭据,对于用户名,它是 UNIX 时间戳和一些字符串(可以是随机或用户 ID 或其他内容):,密码将是用户名的 HMAC你的密钥。

  • 关于 UNIX 时间戳,这是 TURN 服务器中的时间,直到您的凭据必须有效为止,因此计算此时间时请确保您考虑到应用程序服务器和转弯服务器之间的时钟时间差。

现在从我对另一个问题的回答中获取一些示例代码

用于说明 TURN 服务器的命令:

turnserver -v --syslog -a -L xx.xxx.xx.xx -X yy.yyy.yyy.yy -E zz.zzz.zz.zzz --max-bps=3000000 -f -m 3 --min-port=32355 --max-port=65535 --use-auth-secret --static-auth-secret=my_secret --realm=north.gov --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout -q 100 -Q 300 --cipher-list=ALL

node.js在应用服务器中创建 TURN 凭证的代码:

var crypto = require('crypto');

function getTURNCredentials(name, secret){    

    var unixTimeStamp = parseInt(Date.now()/1000) + 24*3600,   // this credential would be valid for the next 24 hours
        username = [unixTimeStamp, name].join(':'),
        password,
        hmac = crypto.createHmac('sha1', secret);
    hmac.setEncoding('base64');
    hmac.write(username);
    hmac.end();
    password = hmac.read();
    return {
        username: username,
        password: password
    };
}

使用它的浏览器代码:

  ...
  iceServers:[
    {
      urls: "turn:turn_server_ip",
      username: username,
      credential:password
    }
  ...
于 2016-03-03T08:48:38.267 回答
9

经过(许多)小时的挫折之后,@Mido 的出色回答是唯一真正让 CoTurn 的 REST API 为我工作的东西。

我的凭证服务器是 PHP,我使用 CoTurn 的配置文件“turnserver.conf”,所以这是针对这种情况的 Mido 工作的经过测试和工作的翻译:

假设“3575819665154b268af59efedee8826e”的“共享密钥”,以下是相关的 turnserver.conf 条目:

lt-cred-mech
use-auth-secret
static-auth-secret=3575819665154b268af59efedee8826e

...和 ​​PHP(误导了我多年):

$ttl = 24 * 3600;  // Time to live
$time = time() + $ttl;
$username = $time . ':' . $user;
$password = base64_encode(hash_hmac('sha1', $username, '3575819665154b268af59efedee8826e', true));
于 2019-02-16T16:18:12.660 回答
5

基于@Mido 和@HeyHeyJC 的答案,这里是为coturn 构建凭据的Python 实现。

import hashlib
import hmac
import base64
from time import time

user = 'your-arbitrary-username'
secret = 'this-is-the-secret-configured-for-coturn-server'

ttl = 24 * 3600 # Time to live
timestamp = int(time()) + ttl
username = str(timestamp) + ':' + user
dig = hmac.new(secret, username, hashlib.sha1).digest()
password = base64.b64encode(dig).decode()

print('username: %s' % username)
print('password: %s' % password)

这是一个Web 应用程序,用于测试您的 coturn 服务器的登录。用作turn:host.example.com服务器名称。

于 2020-06-06T14:44:26.980 回答
4

我最近遇到了类似的问题(让 REST API 与 TURN 服务器一起工作),并了解到当我们在 TURN 配置中启用 REST API 支持时,TURN 服务器根本不支持 REST API 调用,并且只提供对具有共享密钥的身份验证格式的支持。该草案仅提供了我们在实现此类 REST API 时需要考虑的事项的信息,我们需要自己创建 API 或使用类似turnhttp的东西来生成临时用户名密码组合。

正如@mido 详细说明的那样,您可以在应用程序本身中实现用户名/密码生成部分。但是,如果您有理由将其与应用程序分开并希望将其实现为完全不同的 API 服务,而不是按照草稿实现完整的 API ,我遇到了另一篇文章,其中 OP 提供了一个 PHP 脚本来生成临时用户名和密码,一旦您将 hash_hmac() 函数修改为以下内容,这个就可以很好地工作,

$turn_password = hash_hmac('sha1', $turn_user, $secret_key, true);

我们需要对hash_hmac的 RAW 输出进行 base64 编码以使其正常工作,我相信这就是为什么它不适用于该链接中的 OP。

您应该能够使用turnutils_uclient命令测试身份验证,以验证临时用户名/密码组合是否按预期工作。

turnutils_uclient -y -u GENERATED_USERNAME -w GENERATED_PASSWORD yourturnserver.com

一旦您验证了身份验证并确认它正在工作,您可以为 PHP 脚本设置网络服务器以使其可用于您的应用程序并获取临时用户名/密码组合。此外,您还需要实施其他安全设置(身份验证)以保护 API 免受未经授权的访问。

我知道这是一篇旧帖子,只是在这里分享我的发现,希望有一天它对某人有用。

于 2018-12-04T11:29:02.510 回答
3

这是我的带有 TTL 的 c# 实现

public string[] GenerateTurnPassword(string username)
{
    long ttl = 3600 * 6;
    var time = DateTimeOffset.Now.ToUnixTimeSeconds() + ttl;
    var newuser = time + ":" + username;
    byte[] key = Encoding.UTF8.GetBytes("YOURSECRET");
    HMACSHA1 hmacsha1 = new HMACSHA1(key);
    byte[] buffer = Encoding.UTF8.GetBytes(newuser);
    MemoryStream stream = new MemoryStream(buffer);
    var hashValue = hmacsha1.ComputeHash(stream);
    string[] arr = new string[2];
    arr[0] = Convert.ToBase64String(hashValue);
    arr[1] = newuser;
    return arr;
}

于 2020-07-02T12:09:18.727 回答
2

好吧,@Augusto Destrero 提供的实现将TypeError: key: expected bytes or bytearray, but got 'str'在 Python 3.7.6 上引起,对于任何寻找另一个 Python 实现的人来说,这里有一个例子:

import time
import hmac
import hashlib
import base64

secret = b'abcdefghijkmln'

def generateTurnUsernamePwd():
    username = "arbitry username here"
    password = hmac.new(secret, bytes(username, 'UTF-8'), hashlib.sha1).digest()
    passwordStr = base64.b64encode(password).decode("utf-8")
    
    return username,passwordStr

print(generateTurnUsernamePwd())

主要区别在于lib 中keymessage关键字参数在hmac新版本中必须是字节,而在旧版本中,它需要 str。

于 2020-11-25T07:01:47.187 回答
0

我认为值得在答案中添加 coturn 有关此主题的文档的实际文本以及感兴趣的人的链接

--auth-secret TURN REST API 标志。设置基于身份验证机密的特殊 WebRTC 授权选项的标志。该功能的目的是支持“TURN Server REST API”,如下面的 TURN REST API 部分所述。此选项使用时间戳作为组合用户名的一部分:usercombo -> "timestamp:username", turn user -> usercombo, turn password -> base64(hmac(input_buffer = usercombo, key = shared-secret))。这允许将 TURN 凭证用于特定的用户 ID。如果没有合适的 id,可以单独使用时间戳。此选项只是打开基于秘密的身份验证。秘密的实际值由选项 static-auth-secret 定义,

于 2021-07-24T18:33:41.280 回答