CoTURN: How to use TURN REST API?

前端 未结 6 681
不知归路
不知归路 2020-12-02 18:57

I have build coturn and run it successfully. ip:192.168.1.111. Now the question I faced is to get the Turn credential through REST API. http://tools.ietf.org/html/draft-ube

相关标签:
6条回答
  • 2020-12-02 19:12

    Here is my c# implementation with TTL

    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;
    }
    
    
    0 讨论(0)
  • 2020-12-02 19:16

    Building upon @Mido and @HeyHeyJC answers, here is the Python implementation to build credentials for coturn.

    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)
    

    Here is a web based page to test the login to your coturn server. Use turn:host.example.com as the server name.

    0 讨论(0)
  • 2020-12-02 19:17

    After (many) hours of frustration, @Mido's excellent answer here was the only thing that actually got CoTurn's REST API working for me.

    My credential server is PHP and I use CoTurn's config file 'turnserver.conf' so here's a tested and working translation of Mido's work for that situation:

    Assuming a 'shared secret' of '3575819665154b268af59efedee8826e', here are the relevant turnserver.conf entries:

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

    ...and the PHP (which misled me for ages):

    $ttl = 24 * 3600;  // Time to live
    $time = time() + $ttl;
    $username = $time . ':' . $user;
    $password = base64_encode(hash_hmac('sha1', $username, '3575819665154b268af59efedee8826e', true));
    
    0 讨论(0)
  • 2020-12-02 19:18

    Well @Augusto Destrero provided implementation will cause TypeError: key: expected bytes or bytearray, but got 'str' on Python 3.7.6, for anyone looking for another Python implementation, here is an example:

    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())
    

    The main difference is key and message keyword arguments in hmac lib has to be bytes in newer version , while in older versions, it requires str.

    0 讨论(0)
  • 2020-12-02 19:24

    I came across similar issue (getting REST API working with TURN server) recently and learned that TURN server doesn't support REST API calls at all and just provides support for an authentication format with shared secret when we enable REST API support in TURN config. The draft only provides info on things that we need to consider while implementing such REST API and WE need to create the API on our own or use something like turnhttp to generate the temporary username password combo.

    As @mido detailed, you can implement the username/password generation part in the application itself. But if you have reasons to separate this from the application and want to implement it as an entirely different API service, instead of implementing a complete API as per the draft, I came across another post in which the OP provided a PHP script to generate temp username & password and this one works pretty well once you modify the hash_hmac() function to the following,

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

    We need to base64 encode the RAW output of hash_hmac to get it working and I believe this is why it was not working for the OP in that link.

    You should be able to test authentication using turnutils_uclient command to verify that the temp username/password combo is working as expected.

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

    Once you have verified authentication and confirmed that it's working, you can setup webserver for the PHP script to make it available to your application and fetch the temporary username/password combo. Also, you would need to implement other security setup (authentication) to protect the API from unauthorized access.

    I know this is an old post, just sharing my findings here hoping that it will be useful for someone someday.

    0 讨论(0)
  • 2020-12-02 19:26

    Few things to be clarified here are:

    • GET /?service=turn&username=mbzrxpgjys which returns a JSON, is just a suggested uri for retrieving time-limited TURN credentials from the server, you do not have to follow that, your uri can be just /?giveMeCredentials. In fact, I use my socket connection to retrieve this data, not direct http call with json response. End of day, it does not matter how you( the client that uses said TURN) get those credentials as long as they are valid.

    • You do not make any requests to the TURN server directly, no rest api call to TURN server is under your control.

    • you allocate a secret key when you are starting the TURN server, this can be taken from a db(thus dynamically changable), but lazy that I am, just hard-coded, and gave it in the turn config file, also remember to enable REST API. As part of turn command, turnserver ... --use-auth-secret --static-auth-secret=MySecretKey

    • Now, in your application server, you would use the same secret key to generate credentials, for username, it is UNIX timestamp and some string( can be random or user id or something) seperated by : and the password would be HMAC of the username with your secret key.

    • about the UNIX timestamp, this has be the time in TURN server till which your credentials has to be valid, so which calculating this make sure you take into account of the clock time difference between your application server and your turn server.

    Now some sample code taken from my answer to another question

    command for stating TURN server:

    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 code for creating TURN credentials in application server:

    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
        };
    }
    

    Browser code for using this:

      ...
      iceServers:[
        {
          urls: "turn:turn_server_ip",
          username: username,
          credential:password
        }
      ...
    
    0 讨论(0)
提交回复
热议问题