Stuck with the TURN server credential/password in clear text issue, proposing allowed_domains config

7,812 views
Skip to first unread message

Rene Tapia

unread,
Mar 23, 2013, 10:47:27 PM3/23/13
to discuss...@googlegroups.com
Hello,

I am almost ready to deploy webRTC into my app, but I got stuck trying to solve the issue of having the TURN server credential/password in clear text.

Currently, the TURN server credential/password is passed to webRTC in clear text in a js file, like so:
    var pc_config = {"iceServers": [{"url": "turn:us...@x.x.x.x:3478", "credential": "pwd_in_clear_text"}]};

The issue here is that anybody can see the user/password, and just copy it, and start relaying calls from other sites using my server bandwidth.

I have been thinking about different approaches to solve this problem.

One of them is OTP (one time passwords). With this solution, everytime my webRTC page is fetched, a new OTP is generated. This way, if somebody copies this OTP into another website, it can only be used once. This solution requires the TURN server to keep track of which OTPs have already been used. It also requires the web server and the TURN server to communicate, which can become complicated if the web server and the TURN server are on different machines. Worst of all, somebody determined to use your server bandwidth can just fetch your webRTC page to get a new OTP everytime he needs one. So OTPs do not really solve the problem.

Another solution that came to mind is to use short term credentials. With this solution, everytime the webRTC page is fetched, a new password that expires in a predefined amount of time is generated. If the expiration time is just a few seconds, then the password has to be fetched with an ajax call, just before the RTCPeerConnection is created. But here again, somebody can just fetch your webRTC page to get a fresh password that has not yet expired, everytime he needs one, so this does not solve the problem either.

I have also read in the webRTC group questions about having the TRUN server communicate with a DB server to authenticate users, but this does not seem to solve this problem either. Here you could place per-user session/bandwidth limits on the TURN server, but somebody could just create many accounts so that these per-user limits are never exceeded.

So all of these approaches seem very cumbersome, and do not really solve the issue.

After giving it some thought, it seems to me that the real issue is in the semantics of the problem.

In other words, when a user arrives at my webRTC page to start a call, the user has already been authenticated through different means, and so the problem really is how to make sure that only users from my site are allowed to relay calls through my webRTC server.

I believe a clean, simple and elegant solution for this issue could be:

1) In RTCPeerConnection, along with the user and password, the browser also sends to the TURN server, the domain of the page on which RTCPeerConnection is executed.
2) The TURN server has an allowed_domains config option in order to allow connections to be allocated only from certain domains (something similar to the config option in an email server that allows only certain IPs to relay email).
3) If the connection attempt comes from one of the allowed domains, the connection is allocated, otherwise it is rejected.

And so, even if somebody copies the TURN server password to another site, the connections will be rejected.

Furthermore, it will be impossible to forge the domain, since the domain will be sent directly from the browser to the TURN server.

This should be pretty straight forward to implement both on the browser side, as well as on the TURN server side.

By looking at the webRTC group, I get the feeling that several developers are going to choose to deploy their own TURN servers, and so several developers might run into the same issue.

Implementing this option could be a simple and great way to accelerate the deployment of a TURN server, and ultimately of webRTC.

Harald Alvestrand

unread,
Mar 24, 2013, 4:48:19 AM3/24/13
to discuss...@googlegroups.com

Serve your JS over https. That is a Good thing anyway.
Generate a new PW every time you give one out, that way all hacks become traceable, and you can turn off hacked pw (or just anything not used for 10 min).
Short term credentials are your friend.

--
 
---
You received this message because you are subscribed to the Google Groups "discuss-webrtc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrt...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Philipp Hancke

unread,
Mar 24, 2013, 5:00:36 AM3/24/13
to discuss...@googlegroups.com

On Sun, Mar 24, 2013 at 9:48 AM, Harald Alvestrand <h...@google.com> wrote:

Serve your JS over https. That is a Good thing anyway.
Generate a new PW every time you give one out, that way all hacks become traceable, and you can turn off hacked pw (or just anything not used for 10 min).
Short term credentials are your friend.

And https://code.google.com/p/webrtc/issues/detail?id=1197 has a neat plan for generating those ;-)

Rene Tapia

unread,
Mar 24, 2013, 8:54:56 PM3/24/13
to discuss...@googlegroups.com, philipp...@googlemail.com
Yes, I had also thought about using short term credentials. I even thought about using the timestamp as the user, and generate/verify a password based on the timestamp plus a secret key, as suggested in the patch in Issue 1197.

However, it seems rather complicated, it is completely dependent on a particular architecture (i.e. in the case of apprtc it depends on GAE), but worst of all, at the end of the day, I get the feeling that the solution is not completely secure. For example, somebody could automate chrome, or even two chrome instances, in order to simulate that this is a genuine Apprtc call, just to extract fresh passwords from JS, and then use those passwords elsewhere.

I believe the underlying problem here, is that once you give any passwords out, the TURN server has absolutely no way of telling whether this password is being used from apprtc.appspot.com, or from my-dubious-app.com.

That is why I would like you guys to consider the following proposed solution:

1) When Chrome contacts the TURN server, Chrome sends user and password as usual, PLUS the domain of the page.
2) The TURN server checks user and password as usual, PLUS the domain of the page. If the domain is in a pre-configured list of domains allowed to relay calls through this server, then the connection is allocated, otherwise it is rejected.

Unless I am missing something, this should be trivial to implement on Chrome.

On the TURN server it is a little more elaborate because you have to add a new config option, parse it, and then add the check for the domain, but it should still be fairly simple to implement, with the benefit that once it is implemented, many developers can use that implementation, test it, make improvements, etc (all the benefits of the open source philosophy).

And so unless there is a simple and secure way to deploy a TURN server, I believe this issue will slow down the adoption of the webRTC technology.

Just think about how long it has taken Apprtc to deploy a TURN server for concerns of opening yourselves to abuse from outsiders.

As a developer, I am right now in the same situation on which on one hand, I need to deploy a TURN server (unless I am willing to neglect 8%-15% percent of my users), but on the other hand, there is right now no simple and secure way to deploy a TURN server.

This issue is right now a show stopper for me, since I do not want to deploy a TURN server that is open and exposed to abuse.

I really like the webRTC initiative, I believe it is a fantastic technology, and I would appreciate it if you could consider this proposal, and whether it is viable or not.

Thank you.

Oleg Moskalenko

unread,
Mar 24, 2013, 9:09:49 PM3/24/13
to discuss...@googlegroups.com, philipp...@googlemail.com
Rene, TURN server implementation is subject to strict standards of RFC 5766. You cannot make up a new TURN attribute (DOMAIN) and require some non-standard behavior from TURN server.

I guess a better solution would be to use access-control-lists based upon client IP addresses and masks. TURN server knows IP address of the party that sends the allocation requests. This can be implemented. I actually have it in our plans for our TURN server.

Short-term credentials can help, too. We also have it in our plans.

Regards,
Oleg

Rene Tapia

unread,
Mar 25, 2013, 12:28:47 AM3/25/13
to discuss...@googlegroups.com, philipp...@googlemail.com
Hi Oleg, thanks for your reply. All right, that makes perfect sense that you can not deviate from the RFC.

On the other hand, I just recently moved to rfc5766-turn-server, and so that's great news that you have short-term credentials in your plans!

I will wait for short-term credentials in rfc5766-turn-server. Thank you.

Regards,
Rene

Justin Uberti

unread,
Mar 25, 2013, 7:55:46 PM3/25/13
to discuss-webrtc, Philipp Hancke
On Sun, Mar 24, 2013 at 5:54 PM, Rene Tapia <rta...@nuxlabs.com> wrote:
Yes, I had also thought about using short term credentials. I even thought about using the timestamp as the user, and generate/verify a password based on the timestamp plus a secret key, as suggested in the patch in Issue 1197.

However, it seems rather complicated, it is completely dependent on a particular architecture (i.e. in the case of apprtc it depends on GAE), but worst of all, at the end of the day, I get the feeling that the solution is not completely secure. For example, somebody could automate chrome, or even two chrome instances, in order to simulate that this is a genuine Apprtc call, just to extract fresh 
passwords from JS, and then use those passwords elsewhere.

If someone is willing to go to this trouble, all bets are off. Even with your scheme, they could run a modified version of Chrome that hardcodes the domain to be that of your site.

I think the solution proposed in 1197 is going to be the standard operating practice for this sort of thing. If you have additional concerns, this would probably be a good thing to discuss on the rtcweb mailing list, which is where security issues like this can be discussed in detail.


I believe the underlying problem here, is that once you give any passwords out, the TURN server has absolutely no way of telling whether this password is being used from apprtc.appspot.com, or from my-dubious-app.com.

That is why I would like you guys to consider the following proposed solution:

1) When Chrome contacts the TURN server, Chrome sends user and password as usual, PLUS the domain of the page.
2) The TURN server checks user and password as usual, PLUS the domain of the page. If the domain is in a pre-configured list of domains allowed to relay calls through this server, then the connection is allocated, otherwise it is rejected.

Unless I am missing something, this should be trivial to implement on Chrome.

On the TURN server it is a little more elaborate because you have to add a new config option, parse it, and then add the check for the domain, but it should still be fairly simple to implement, with the benefit that once it is implemented, many developers can use that implementation, test it, make improvements, etc (all the benefits of the open source philosophy).

And so unless there is a simple and secure way to deploy a TURN server, I believe this issue will slow down the adoption of the webRTC technology.

Just think about how long it has taken Apprtc to deploy a TURN server for concerns of opening yourselves to abuse from outsiders.

FWIW, abuse concerns are not the reason this has taken so long. 

As a developer, I am right now in the same situation on which on one hand, I need to deploy a TURN server (unless I am willing to neglect 8%-15% percent of my users), but on the other hand, there is right now no simple and secure way to deploy a TURN server.

Seems like an opportunity for an entrepreneur :) 

This issue is right now a show stopper for me, since I do not want to deploy a TURN server that is open and exposed to abuse.

I really like the webRTC initiative, I believe it is a fantastic technology, and I would appreciate it if you could consider this proposal, and whether it is viable or not.

Thank you.

 




Em domingo, 24 de março de 2013 03h00min36s UTC-6, Philipp Hancke escreveu:

On Sun, Mar 24, 2013 at 9:48 AM, Harald Alvestrand <h...@google.com> wrote:

Serve your JS over https. That is a Good thing anyway.
Generate a new PW every time you give one out, that way all hacks become traceable, and you can turn off hacked pw (or just anything not used for 10 min).
Short term credentials are your friend.

And https://code.google.com/p/webrtc/issues/detail?id=1197 has a neat plan for generating those ;-)

--

Rene Tapia

unread,
Mar 26, 2013, 1:37:42 AM3/26/13
to discuss...@googlegroups.com, Philipp Hancke
Hi Justin, thank you for your reply. Yes, you are right. For the domain scheme to really work, clients like Chrome would have to provide a certificate that the TURN server could check in order to authenticate the client. If the TURN server can authenticate that this is really Chrome, and if Chrome tells the TURN server that the call is being originated from my domain, then we could be pretty confident about relaying this call.

But then, this solution is already getting complicated. Also, I am not a security expert at all, and I am just getting familiar with webRTC, and so there may be many other considerations that I am not aware of. It just seems to me, that it is more direct, to approach this issue at what to me seems to be the root of the problem, which is verifying the origin of the call. And so I wanted to point this out for your consideration FWIW :)

In order to deploy, I am thinking a combination of short term credentials as proposed in 1197, plus maybe a counter to limit the number of short-term credentials that any user account can request in a day, or something of this sort, will do.

Thank you.

Regards,
Rene

Oleg Moskalenko

unread,
Mar 27, 2013, 7:34:08 PM3/27/13
to discuss...@googlegroups.com, Philipp Hancke
I am thinking about implementing the 1197's suggestion in rfc5766-turn-server. But I have to choose which proposal to implement - the "original" or the "updated" one. The original proposal was:

- TURN user is the AppRTC user id
- TURN password is base64(timestamp + HMAC(secret key, user + timestamp))

The "updated" proposal by Philipp that he implemented in restund is:

turn user -> timestamp
turn password -> base64(hmac(secret key, timestamp))

So, which one people really prefer ?

Also, if the "original" proposal is the way to go, then I have a question. How TURN server will know the "timestamp" value ? Philipp avoided this by making username equal to the timestamp. But if the username is AppRTC user id, then how the timestamp value is discovered by the TURN server ? Clock synchronization is not an option, of course.

So, I have no problem implementing Philipp's solution but the "original" suggestion is kinda unclear for me.

Thanks
Oleg

Rene Tapia

unread,
Mar 27, 2013, 8:26:31 PM3/27/13
to discuss...@googlegroups.com, Philipp Hancke
+1 for the "updated" proposal by Phillip.

I believe the AppRTC user id is something specific to the way the AppRTC demo is implemented, which uses Google App Engine (GAE) for the signaling channel, etc.

If this is correct, then the "original" proposal applies to a specific implementation only.

The "updated" proposal is independent of any particular implementation, and solves the problem of how to pass the timestamp to the TURN server.

BTW Thanks a lot for looking into this Oleg.

Justin Uberti

unread,
Mar 28, 2013, 1:33:56 AM3/28/13
to discuss-webrtc, Philipp Hancke
The original proposal was incorrect. The formulation should have been
usercombo = "user_id : timestamp"
turn user -> usercombo
turn password -> base64(hmac(secret key, usercombo))
This allows TURN credentials to be validated against a specific user id or page instance (i.e. if that user is not logged in, the request can be ignored).
If you don't have a suitable id, the timestamp alone can be used.


Philipp Hancke

unread,
Mar 28, 2013, 1:49:42 AM3/28/13
to discuss...@googlegroups.com
Also, if the "original" proposal is the way to go, then I have a question. How TURN server will know the "timestamp" value ? Philipp avoided this by making username equal to the timestamp. But if the username is AppRTC user id, then how the timestamp value is discovered by the TURN server ? Clock synchronization is not an option, of course.

Because the TURN server has to have implicit knowledge of the password and therefore can't extract the timestamp from anything available in the authentication request? Golly, I hadn't noticed that.

I'm actually considering more away from a pure timestamp in the username field because I need to do some accounting. But that doesn't change the cryptographic procedure, only the way the time-limitness is checked.
Essentially
turn user -> timestamp;account
turn password -> base64(hmac(secret key, turn user))

Oleg Moskalenko

unread,
Mar 28, 2013, 2:25:22 AM3/28/13
to discuss...@googlegroups.com, philipp...@googlemail.com

So, Philipp and Justin propose the same solution, but in somewhat opposite manner:

Justin: username:timestamp
Philipp: timestamp:username

The latest proposals are equivalent. Let's choose the one. I personally think that username:timestamp is more pleasant for the eye.

Does everybody agree ?

Oleg

Rene Tapia

unread,
Mar 28, 2013, 11:56:53 AM3/28/13
to discuss...@googlegroups.com, philipp...@googlemail.com
+1 for Justin's proposal. I also like it more how it looks.

I'd like to ask a couple of questions:
1) Since a username is going to be included, can then a user-quota be defined in the config file, an will this user-quota be applied to each different username? In other words, will the allocations be accounted for each username individually, and the user-quota applied accordignly?
2) The user-quota is applied during the lifetime of the server, not during a specific time period, like 24 hrs, etc. Is this correct?

Oleg Moskalenko

unread,
Mar 28, 2013, 12:35:58 PM3/28/13
to discuss...@googlegroups.com, philipp...@googlemail.com
Rene, as Philipp mentioned above, with combined username:timestamp we can use accounting and we can apply per-user settings

In rfc-5766-turn-server, the "user-quota" option is applied to simultaneous (concurrent) connections, at any moment of time. It is not over a time period.

Thanks
Oleg

Philipp Hancke

unread,
Mar 28, 2013, 1:01:15 PM3/28/13
to Oleg Moskalenko, discuss...@googlegroups.com
The latest proposals are equivalent. Let's choose the one. I personally think that username:timestamp is more pleasant for the eye.

Does everybody agree ?

I'll update my patch with Justins order, eye-pleasing is a good argument ;-)

Justin Uberti

unread,
Mar 28, 2013, 6:30:35 PM3/28/13
to discuss-webrtc, Oleg Moskalenko
To actually document this somewhere other than an email or a bug, I wrote some notes down in https://docs.google.com/document/d/1mG7eXFQ5o-ypMWQ1IzdkBQL0UBkLN1xXUJhJcIF5ujQ/edit#. Please take a look and comment in the document; my hope is that this becomes a standard REST API for allocating TURN services.


--

Oleg Moskalenko

unread,
Mar 28, 2013, 7:47:19 PM3/28/13
to discuss...@googlegroups.com, Oleg Moskalenko
Hi Justin

thanks for putting it together.

It would be great to clarify several things in the document:

1) You use term "short-term credentials". How it corresponds to RFC5766 TURN server's terms "long term credential mechanism" and "short-term credential mechanism" ? As far as I understand, WebRTC uses "long-term credential mechanism" as outlined in RFC. If we are going to continue using "long-term mechanism" but with "short-term credentials" it would be highly confusing. I'd choose a different term for the "quick" credentials. If we are switching to "short-term mechanism" I'd explicitly mention it in the document.

2) I'd explicitly mention that the timestamp is measured in seconds as function time() returns. In VoIP different timestamp formats are often used and people may get confused.

3) When client establishes a session with TURN server, it must maintain the same username, according to RFC 5766:

"All requests after the initial Allocate must use the same username as that used to create the allocation"."

So, the question is: are we maintaining the same "base" "prefix" user during the session, or we maintain the same "full combo" user during the session (the timestamp remains constant for the session) ? According to RFC, probably the constant combo would be more compliant implementation. But probably if we let timestamp to be changing (current time), it would be more secure solution, and the session will not have time limit. We have to mention which option is used explicitly.

4) The last phrases about server implementation are somewhat unclear:

"[TURN server] optionally verifies that the username corresponds to a currently active user of the service (e.g. is currently logged in)"

Probably it is related to question 3. If we clarify the question 3), then probably we can clarify this.

Regards,
Oleg

Oleg Moskalenko

unread,
Mar 28, 2013, 8:27:41 PM3/28/13
to discuss...@googlegroups.com, Oleg Moskalenko
I contemplated over the "variable" timestamp in the session, and I realized there would be too much potential problems. For example, when TURN server sends something to the client, it adds "integrity" to it and it uses the session name and password (and TURN server does not include the username in the messages, by the way). But if the name and the password are variable during the session, then which ones it is supposed to use ? It may use the corresponding request parameters, of course, but then it is getting complicated - and we are limiting ourselves to long-term mechanism only, because in short-term mechanism, the indications must be "signed", too, and the indications do not have corresponding requests. I am afraid that there may be other consistency problems which I do not see right now. So, I'd suggest that the "combo" username remains constant during the session as long as the session is "alive", and the TURN server uses the same password (even when the timestamp is expired, say, after 24 hours). The client has to refresh the session often, so hopefully this solution is OK.

Oleg

Oleg Moskalenko

unread,
Mar 29, 2013, 7:46:42 PM3/29/13
to discuss...@googlegroups.com, Oleg Moskalenko
rfc5766-turn-server now implements functionality described in Justin's document:

http://code.google.com/p/rfc5766-turn-server/

There are two modes: one with "static" constant secret string configured through the command line, and the second mode with "dynamic" secret when a third-party agent can update the secret in the database, and the TURN server starts using the new secret immediately for the new sessions. The existing sessions can continue with old secret as long as the existing session is maintained and refreshed properly.

Thanks

Oleg


On Thursday, March 28, 2013 3:30:35 PM UTC-7, Justin Uberti wrote:

Rene Tapia

unread,
Mar 30, 2013, 7:32:43 PM3/30/13
to discuss...@googlegroups.com, Oleg Moskalenko
Fantastic. This is great.

Thanks a lot Oleg, Justin, Philipp, Harald.

Regards

Rene Tapia

unread,
Apr 3, 2013, 12:22:52 AM4/3/13
to discuss...@googlegroups.com, Oleg Moskalenko
Hello,

I was trying to use Oleg's implementation of shared-secret / timestamp authentication, but there seems to be an issue with the current definition of the user combo.

The issue is that the user combo is currently defined as "userid:timestamp", but whenever there is a colon in the username, webrtc silently discards this iceServer, and never calls the TURN server.

I first added some logging in order to debug the server, and then I ran wireshark, and indeed, whenever there is a colon in the username, there is no traffic at all from webrtc to the TURN server.

I tried other characters in the middle of the username (using static users in the config file), and dash, underscore, slash and pipe, work.

So here is a summary:

    //var pc_config = {'iceServers': [{'url': 'turn:alf...@xxx.xxx.xxx.xxx:3478', 'credential': '123'}]}; // ok
    //var pc_config = {'iceServers': [{'url': 'turn:al:fr...@xxx.xxx.xxx.xxx:3478', 'credential': '123'}]}; // FAILS: webrtc doesn't call
    //var pc_config = {'iceServers': [{'url': 'turn:al-...@xxx.xxx.xxx.xxx:3478', 'credential': '123'}]}; // ok
    //var pc_config = {'iceServers': [{'url': 'turn:al_...@xxx.xxx.xxx.xxx:3478', 'credential': '123'}]}; // ok
    //var pc_config = {'iceServers': [{'url': 'turn:al/fr...@xxx.xxx.xxx.xxx:3478', 'credential': '123'}]}; // ok
    //var pc_config = {'iceServers': [{'url': 'turn:al|fr...@xxx.xxx.xxx.xxx:3478', 'credential': '123'}]}; // ok

Tomorrow, I will make a simple change in Oleg's implementation to use an underscore instead of a colon for the usercombo, and I will report tomorrow how that worked.

Regards,
Rene

Philipp Hancke

unread,
Apr 3, 2013, 1:03:19 AM4/3/13
to discuss...@googlegroups.com
See one of my comments in Justins document. A turn "uri" like turn:user:1234567@host:3478" causes chrome to (incorrectly? i'm not an abnf laywer) interpret the 1234567 as a port number and it correctly rejects that as invalid (which can be seen in the debug logs). 
issue #1508 should fix the problem.

Oleg Moskalenko

unread,
Apr 3, 2013, 1:34:20 AM4/3/13
to discuss...@googlegroups.com, Oleg Moskalenko
Rene, you set the table turn_secret in the database, right ? It would be very interesting to know the results of your tests.

Regards,
Oleg

Rene Tapia

unread,
Apr 3, 2013, 2:08:41 AM4/3/13
to discuss...@googlegroups.com, Oleg Moskalenko
Oleg, actually I am currently using the static-auth-secret in the config file. But once I get that working, I will set up the table turn_secret in the database, and I will give a try as well.

Regards,
Rene

Justin Uberti

unread,
Apr 3, 2013, 2:50:11 PM4/3/13
to discuss-webrtc, Oleg Moskalenko
The colon needs to be URL-encoded. This was broken in Chrome but should be working in today's canary.


Oleg Moskalenko

unread,
Apr 3, 2013, 3:44:43 PM4/3/13
to discuss...@googlegroups.com, Oleg Moskalenko
Justin, you mean, the colon must be URL-encoded in the web page, right ? To the TURN server the "real" colon will be sent, right ? Or the TURN server will have to be able to deal with the URL-encoded colon, like %3a ?

Mallinath Bareddy

unread,
Apr 3, 2013, 4:28:00 PM4/3/13
to discuss...@googlegroups.com, Oleg Moskalenko
"real" colon will be sent to the TURN server.

Justin Uberti

unread,
Apr 3, 2013, 6:31:57 PM4/3/13
to discuss-webrtc, Oleg Moskalenko
And as mentioned before, this will all go away when the TURN username is no longer part of the URI.

Oleg Moskalenko

unread,
Apr 3, 2013, 6:41:22 PM4/3/13
to discuss...@googlegroups.com, Oleg Moskalenko
Justin, are there any documents regarding the future ?

Rene Tapia

unread,
Apr 3, 2013, 9:21:20 PM4/3/13
to discuss...@googlegroups.com, Oleg Moskalenko
Actually, it seems like the "encoded" colon (%3A) is sent to the TURN server.

I added some logging to the get_user_key function (this is where the hmac for the username combo with the shared secret is calculated), in userdb.c of rfc5766-turn-server, in order to write uname to the log, and the uname had the encoded colon %3A.

Unfortunately, I am not able to repro this anymore.

I have two peers on the same local network behind a modem, and the TURN server is outside on the Internet, and it seems that with this configuration the auth check does not happen every time, but very rarely.

In other words, the get_user_key function does not get called every time, but very rarely.

So this is the behavior that I am seeing:

One time, in wireshark I can see that the TURN server responds with 401 Not authorized. And in the server logs I can see that the get_user_key function gets called.

Many times, in wireshark I do not see the 401, and in the server logs I can see that the get_user_key function is not called.

Oleg, I would like to ask a few questions:

1) Why are the credentials not checked every time? Is it because STUN does not require an auth check, and only if the the TURN server needs to relay the connection are the credentials checked?
2) What is the best way to have the credentials checked every time?
3) And what indication could be used in order to tell whether the credentials were valid or not (for example: a 401 in wireshark, or a message in the server log, etc)?

I am attaching my config file, along with the server log and wireshark screen capture when there seems to be no auth check, in case I am doing something wrong and that is the cause of the credentials not being checked.

Thank you.
no_auth_check.png
no_auth_check_log.txt
turnserver_conf.txt

Justin Uberti

unread,
Apr 4, 2013, 1:19:40 AM4/4/13
to discuss-webrtc

Oleg Moskalenko

unread,
Apr 4, 2013, 1:30:50 AM4/4/13
to discuss...@googlegroups.com, Oleg Moskalenko
Hi Rene

it is actually theoretically impossible for get_user_key() to be NOT called at least once for each session - because this is the only place where secret password is get calculated, and without knowing this password the server would not be able to construct the response - the client would simply reject the response without proper INTEGRITY attribute.

Also, remember that the BINDING requests do not require authentication in recent builds of rfc5766-turn-server, this is why you see lots of those requests without authentications.

So, the problem if exists is somewhere else. try to calculate number of real sessions (ones which start with ALLOCATION request) and put the output into a defined log file (option --log-file). Just remember that with each start of the server the log file gets cleaned and rewritten.

Please let me know your findings.

Regards,
Oleg

Philipp Hancke

unread,
Apr 4, 2013, 2:39:47 AM4/4/13
to discuss...@googlegroups.com
so testing this doesn't make sense unless one's chrome://version says the build is larger than the revision where mallinath said it is fixed, eh?

Oleg Moskalenko

unread,
Apr 4, 2013, 2:50:03 AM4/4/13
to discuss...@googlegroups.com, philipp...@googlemail.com
I guess Philipp you are right.

Philipp Hancke

unread,
Apr 4, 2013, 7:39:33 AM4/4/13
to discuss...@googlegroups.com
28.0.1464.0 (Official Build 192202) works as expected, thanks alot!

Oleg Moskalenko

unread,
Apr 4, 2013, 9:55:04 PM4/4/13
to discuss...@googlegroups.com, Philipp Hancke
We added implementation of the short-term credentials mechanism to our rfc5766-turn-server:

http://code.google.com/p/rfc5766-turn-server/

My understanding is that WebRTC is not supporting the short-term credentials. But it could be used in the following fashion:

1) WebRTC server and TURN server are using the same database and have access to the same database table of short-term credentials users.
2) When web server is about to generate a new page for the client, it can generate a new password for the user (or it even can generate a totally new temporary account).
3) Web server updates/inserts the information in the database. The lifetime of this information is very short - a minute or 5 minutes or similar.
4) Web server generates the requested page for the client.
5) Client obtains the page and contacts the TURN server.
6) The TURN server checks the database, grants permission to the client and caches the information for the session.
7) Optionally, the TURN server can be implemented so that it removes or changes the record in the database immediately after the first access so that
it cannot be reused. It makes every password one-time password only. The TURN server needs it only once.
8) After the expiration time, the web server removes the record from the table (if the TURN server has not done that before).

This scheme can be extended with ACL: the web server can generate temporary ACL grant for the particular client IP, so that the password can be used only from a particulr IP. The TURN server checks the ACL rejects the client if it is requesting access from a different address. Of course, the web server and the TURN server must be "near" in the network terms and see the client as network agent with the same IP.

Thanks
Oleg


On Monday, March 25, 2013 10:37:42 PM UTC-7, Rene Tapia wrote:


In order to deploy, I am thinking a combination of short term credentials as proposed in 1197, plus maybe a counter to limit the number of short-term credentials that any user account can request in a day, or something of this sort, will do.

Thank you.

Regards,
Rene

Em segunda-feira, 25 de março de 2013 17h55min46s UTC-6, Justin Uberti escreveu:



On Sun, Mar 24, 2013 at 5:54 PM, Rene Tapia <rta...@nuxlabs.com> wrote:
Yes, I had also thought about using short term credentials. I even thought about using the timestamp as the user, and generate/verify a password based on the timestamp plus a secret key, as suggested in the patch in Issue 1197.

However, it seems rather complicated, it is completely dependent on a particular architecture (i.e. in the case of apprtc it depends on GAE), but worst of all, at the end of the day, I get the feeling that the solution is not completely secure. For example, somebody could automate chrome, or even two chrome instances, in order to simulate that this is a genuine Apprtc call, just to extract fresh 
passwords from JS, and then use those passwords elsewhere.

If someone is willing to go to this trouble, all bets are off. Even with your scheme, they could run a modified version of Chrome that hardcodes the domain to be that of your site.

I think the solution proposed in 1197 is going to be the standard operating practice for this sort of thing. If you have additional concerns, this would probably be a good thing to discuss on the rtcweb mailing list, which is where security issues like this can be discussed in detail.


I believe the underlying problem here, is that once you give any passwords out, the TURN server has absolutely no way of telling whether this password is being used from apprtc.appspot.com, or from my-dubious-app.com.

That is why I would like you guys to consider the following proposed solution:

1) When Chrome contacts the TURN server, Chrome sends user and password as usual, PLUS the domain of the page.
2) The TURN server checks user and password as usual, PLUS the domain of the page. If the domain is in a pre-configured list of domains allowed to relay calls through this server, then the connection is allocated, otherwise it is rejected.

Unless I am missing something, this should be trivial to implement on Chrome.

On the TURN server it is a little more elaborate because you have to add a new config option, parse it, and then add the check for the domain, but it should still be fairly simple to implement, with the benefit that once it is implemented, many developers can use that implementation, test it, make improvements, etc (all the benefits of the open source philosophy).

And so unless there is a simple and secure way to deploy a TURN server, I believe this issue will slow down the adoption of the webRTC technology.

Just think about how long it has taken Apprtc to deploy a TURN server for concerns of opening yourselves to abuse from outsiders.

FWIW, abuse concerns are not the reason this has taken so long. 

As a developer, I am right now in the same situation on which on one hand, I need to deploy a TURN server (unless I am willing to neglect 8%-15% percent of my users), but on the other hand, there is right now no simple and secure way to deploy a TURN server.

Seems like an opportunity for an entrepreneur :) 

This issue is right now a show stopper for me, since I do not want to deploy a TURN server that is open and exposed to abuse.

I really like the webRTC initiative, I believe it is a fantastic technology, and I would appreciate it if you could consider this proposal, and whether it is viable or not.

Thank you.

 




Em domingo, 24 de março de 2013 03h00min36s UTC-6, Philipp Hancke escreveu:

On Sun, Mar 24, 2013 at 9:48 AM, Harald Alvestrand <h...@google.com> wrote:

Serve your JS over https. That is a Good thing anyway.
Generate a new PW every time you give one out, that way all hacks become traceable, and you can turn off hacked pw (or just anything not used for 10 min).
Short term credentials are your friend.

And https://code.google.com/p/webrtc/issues/detail?id=1197 has a neat plan for generating those ;-)

Justin Uberti

unread,
Apr 4, 2013, 9:59:27 PM4/4/13
to discuss-webrtc, Philipp Hancke
On Thu, Apr 4, 2013 at 6:55 PM, Oleg Moskalenko <mom0...@gmail.com> wrote:
We added implementation of the short-term credentials mechanism to our rfc5766-turn-server:

http://code.google.com/p/rfc5766-turn-server/

My understanding is that WebRTC is not supporting the short-term credentials. But it could be used in the following fashion:

1) WebRTC server and TURN server are using the same database and have access to the same database table of short-term credentials users.
2) When web server is about to generate a new page for the client, it can generate a new password for the user (or it even can generate a totally new temporary account).
3) Web server updates/inserts the information in the database. The lifetime of this information is very short - a minute or 5 minutes or similar.
4) Web server generates the requested page for the client.
5) Client obtains the page and contacts the TURN server.
6) The TURN server checks the database, grants permission to the client and caches the information for the session.
7) Optionally, the TURN server can be implemented so that it removes or changes the record in the database immediately after the first access so that
it cannot be reused. It makes every password one-time password only. The TURN server needs it only once.
8) After the expiration time, the web server removes the record from the table (if the TURN server has not done that before).

This scheme can be extended with ACL: the web server can generate temporary ACL grant for the particular client IP, so that the password can be used only from a particulr IP. The TURN server checks the ACL rejects the client if it is requesting access from a different address. Of course, the web server and the TURN server must be "near" in the network terms and see the client as network agent with the same IP.

Even if they are "near", there is no guarantee that multihomed NATs will assign the same IP for web and TURN traffic. And I imagine that often the servers will not be near. 

Oleg Moskalenko

unread,
Apr 4, 2013, 10:08:50 PM4/4/13
to discuss...@googlegroups.com, Philipp Hancke
Yeah, the ACL approach is not universal. I mentioned it only as an optional possibility. But the short-term credentials themselves may work if the the web server and the TURN server can access the same database.

Rene Tapia

unread,
Apr 5, 2013, 2:59:07 AM4/5/13
to discuss...@googlegroups.com, Oleg Moskalenko
Hi Oleg,

All right, it all makes sense, now that you mention that BINDING requests do not require authentication.

In order to force an ALLOCATION request, I blocked all udp/tcp connections from/to the other peer (as was suggested in another thread on this group). The tcp connections have to be blocked too, because if udp fails, webRTC will try to connect locally using tcp (my two peers are on the same local network).

Once all tcp/udp has been blocked to/from the other peer, then I can see the ALLOCATION request, and get_user_key gets called every time, and 401 is returned if the credentials check fails.

In this case, I can not make the audio call at all, unless the credentials check succeeds, so the call can be relayed.

It is actually very, very cool to see  webRTC trying different protocols locally, and finally relaying the call through the TURN server if everything else fails.

I guess the behavior I was seen before, where I could see an ALLOCATION request only once in a while, was maybe just a timing issue, where webRTC would try a local connection, and sporadically that would take a long time for some reason, and then webRTC would make an ALLOCATION request. 

Thank you.

Regards,
Rene

Oleg Moskalenko

unread,
Apr 5, 2013, 3:12:32 AM4/5/13
to discuss...@googlegroups.com, Oleg Moskalenko
Thank you Rene for the feedback. Very good to know that it works for you.

The BINDING request authentication is a kind of grey area. According to RFC5389, the BINDING request is the same as any other request and it may have to be authenticated. But BINDING request is an original STUN request, it is not a real TURN request, and WebRTC initially was developed so that it is not expecting STUN request to be authenticated, which is quite understandable because the BINDING exchange has virtually no secure or valuable information. So we adjusted our server implementation so that BINDING request does not ask for authentication and does meet WebRTC client expectations.

WebRTC follows ICE discovery pattern to find the best communication path between the peers, and this is what you are observing.

Best regards,
Oleg

Rene Tapia

unread,
Apr 5, 2013, 3:26:50 AM4/5/13
to discuss...@googlegroups.com, Oleg Moskalenko
OK, I can confirm now that the "encoded" colon (%3A) is sent to the TURN server.

This is the chrome log:

[7224:7224:0404/155353:INFO:CONSOLE(98)] ">>>>> new RTCPeerConnection > Created RTCPeerConnnection with:
  config: "{"iceServers":[{"url":"turn:125994%3A1365112388@54.225.134.200:3478","credential":"yyyyy"}]}";
  constraints: "{"optional":[{"DtlsSrtpKeyAgreement":true}]}".", source: http://test2.nuxlabs.com/wtmm/js/apprtc_pt.js (98)

This is the TURN server log:

read_client_connection:2388:start
read_client_connection: data.buffer=0x1b44990, data.len=116
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> get_user_key > uname: 125994%3A1365112388
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> inside if use_auth_secret_with_timestamp
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> auth_secret: secret_in_config_file
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> inside if not turn_time_before
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> pwd: 8S1vrnmQXBTBnOzOFJthn15ftVs=
read_client_connection:2388:start
read_client_connection: data.buffer=0x1b44990, data.len=116

And attached is a wireshark screen capture.

I guess this does not matter very much now that this issue has been fixed in 28.0.1464.0 (Official Build 192202), and Philipp confirmed that it works as expected.

But in case someone wants to deploy before 28.0.1464.0, you can replace ":" with "_", in get_user_key and get_real_username, in userdb.c, in rfc5766-turn-server (maybe Oleg can confirm that this is correct?).

Note: I tested underscore and it works, but a dash, slash or pipe might work as well.
encoded_colon.png

Oleg Moskalenko

unread,
Apr 5, 2013, 11:29:14 AM4/5/13
to discuss...@googlegroups.com, Oleg Moskalenko
 Rene, I fixed the bug in the timestamp check (Issue 11), please get the build 1.8.0.3. Thanks for reporting !

Best regards,
Oleg
 

Rene Tapia

unread,
Apr 5, 2013, 9:52:16 PM4/5/13
to discuss...@googlegroups.com, Oleg Moskalenko
Oleg, fantastic, thanks a lot for your prompt reply!

Best regards,
Rene 
Reply all
Reply to author
Forward
0 new messages