Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TURN server for WebRTC with REST API authentication

I'm trying to set up the rfc5766-turn-server TURN server for webRTC from here. I was able to successfully relay my video through this TURN server using a turnuserdb.conf file where I have my username and password (my_user_name:my_password). And on the web client side I used:

"iceServers":{[
    "url": "turn:my_user_name,@turn_server_ip",
    "credential":"my_password"
}]

I'm trying to use the REST API feature that comes with the TURN server to avoid sending the password over the network or storing it on the client side. I followed this spec and this explanation under the Rest API

However unfortunately I get a 401 and I cannot authenticate.

Here's what I did exactly:

  1. I created a secret "my_secret" and I ran the turn server like this:

    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
    

    (I just replaced the IP address with xx.xxx.xx.xx yy.yyy.yyy.yy zz.zzz.zz.zzz)

  2. Later I generated a timestamp that would be now + 1 hour so I ran on nodejs:

    Date.now()+1000*60*60;      // output 1433895918506.
    

    I generated the temporary password on this website, Using my secret, and got a result 0ca57806bdc696b3129d4cad83746945b00af77b

  3. I encoded the password to base64.

  4. Now I tried to log communicate with the turn server from the web client using the temporary username : 1433895918506:my_user_name and password: MGNhNTc4MDZiZGM2OTZiMzEyOWQ0Y2FkODM3NDY5NDViMDBhZjc3Yg==, on the web client now I use

    "iceServers":"url":"turn:1433895918506:my_user_name@turn_server_ip","credential":"MGNhNTc4MDZiZGM2OTZiMzEyOWQ0Y2FkODM3NDY5NDViMDBhZjc3Yg=="}]
    

But it doesn't work, I get:

401 user <1433895918506:my_user_name>  incoming packet message processed, error 401: Unauthorised.

Can you help me figure out what's wrong?

like image 344
Michael P Avatar asked Jun 10 '15 00:06

Michael P


People also ask

Does WebRTC require a turn server?

For most WebRTC applications to function a server is required for relaying the traffic between peers, since a direct socket is often not possible between the clients (unless they reside on the same local network). The common way to solve this is by using a TURN server.

What is turn server WebRTC?

In essence, it enables a media server to provide in the SDP a ICE candidate using a TCP transport. This means the media server will actively wait on a TCP port for an incoming connection from the device. It used to be a Chrome feature, but now it is available in all web browsers that support WebRTC.

Is turn server secure?

The benefits of a turn server include Increased security when actively used (less chance of IP leaking) and better network compatibility. Without a TURN server, about 10% of remote guests will not be able to connect with each other.


1 Answers

when I generated credential with your name and secret, I got 1Dj9XZ5fwvKS6YoQZOoORcFnXaI= not MGNhNTc4MDZiZGM2OTZiMzEyOWQ0Y2FkODM3NDY5NDViMDBhZjc3Yg==, check your algorithm/code for errors.

and the time is in Unix Timestamp, so in seconds and not milliseconds as you did( though this should not affect, but just makes your credentials never expire)

check if your system and the system where the TURN server is running, the clocks are in sync( at least not days apart), and in general, to avoid issue of clocks not being in sync, better to use ttl as 24 hours, so your timestamp:

timestamp=  parseInt(Date.now()/1000) + 24*3600

the code for generating TURN credential:

var crypto = require('crypto');

function getTURNCredentials(name, secret){    

    var unixTimeStamp = parseInt(Date.now()/1000) + 24*3600,
        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
    };
}
like image 69
mido Avatar answered Sep 20 '22 06:09

mido