WebRTC/ Coturn Authentication using TURN REST API flag (use-auth-secret), based upon authentication secret
Asked Answered
T

0

7

I was playing with this was able to get it working immediately using Node/Javascript, took a while using Golang (this is just generating the user/password to be sent to coturn.) Notice the secret should match the coturn configuration and in the API JS/Go side.

The configuration on coturn: /etc/turnserver.conf

listening-port=443
tls-listening-port=443
listening-ip=10.100.0.2
relay-ip=10.100.0.2
external-ip=123.456.78.9
min-port=10000
max-port=20000
verbose
fingerprint
lt-cred-mech
server-name=myserver
realm=myserver
cert=/etc/SSL/fullchain.pem
pkey=/etc/SSL/privkey.pem
log-file=/var/log/turnserver.log
use-auth-secret
static-auth-secret=MySecret

The following is Node/Js Implementation API (copied from elsewhere - worked):

var crypto = require('crypto');
var unixTimeStamp = parseInt(Date.now()/1000) + 24*3600,   // this credential valid for 24 hours
    TempUser = [unixTimeStamp, "SomeUser"].join(':'),
    TempPassword,
    hmac = crypto.createHmac('sha1', "MySecret");
hmac.setEncoding('base64');
hmac.write(TempUser);
hmac.end();
TempPassword = hmac.read();

The following is GOLANG Implementation API (took a while):

UserId := "SomeUser" 
// This worked, returned the exact seconds
timestamp := strconv.FormatInt(time.Now().UTC().Unix()+24*3600, 10)
// Example: The above is 1602692130
secret := "MySecret"
TempUser := timestamp + ":" + UserId  // For API Auth, coturn expects this format, the timestamp is the expiry date of the final temp user/password.

// Create a new HMAC by defining the hash type and the key (as byte array)
//h := hmac.New(sha256.New, []byte(secret))   // sha256 does not work, use sha1
h := hmac.New(sha1.New, []byte(secret))    

h.Write([]byte(TempUser))

//sha := b64.URLEncoding.EncodeToString(h.Sum(nil))  // URLEncoding did not work
TempPassword := b64.StdEncoding.EncodeToString(h.Sum(nil)) // StdEncoding worked

The JS on the Webrtc client. Notice we are using the TempUser and TempPassword here to be sent to coturn.

    ...
 const stunUrl = 'stun:mystun_server',
    turnUsername = TempUser,
    turnPassword = TempPassword,
...
        'iceServers': [
            { 'url': stunUrl },
            {
                'urls': turnUrl1,
                'username': turnUsername,
                'credential': turnPassword
            },

Now coturn will authenticate using the TempUser and TempPassword above. Hope someone will find this useful. Thanks!

Terpene answered 14/10, 2020 at 22:24 Comment(4)
Brilliant! Thanks for posting, I managed to set up my own api thanks to your post. One question, Couldn't you have a short timeout of say 60 secs? as I understand it once a peer connection is established then it lasts until the peer disconnects then one would establish a new connection with a new token etc.Gradus
I am glad you found some use. If I understand your question correctly, change timestamp := strconv.FormatInt(time.Now().UTC().Unix()+24*3600, 10) to timestamp := strconv.FormatInt(time.Now().UTC().Unix()+60, 10) to get the required results. Thanks.Terpene
Question on this the "SomeUser" is coming from the turnserver database table ? I didn't see any database connection in the coturn config, or can you use a static user that you configure in the coturn config?Cu
There is no database [sql or no-sql] in this setup. The "SomeUser" is just a bunch or characters (could be 'abc') not used anywhere else but just used to create the TempUser and TempPassword in the logic. Now, this TempUser and TempPassword exists in the coturn config as shown above and are used for the authentication. Thanks!Terpene

© 2022 - 2025 — McMap. All rights reserved.