Setup ephemeral password for TURN, Learn RTC in less than 200 Lines of code
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Setup ephemeral password for TURN, Learn RTC in less than 200 Lines of code

  • 1,270 views
Uploaded on

TURN is used for relaying data from source to target. TURN consumes bandwidh and it is expensive. ...

TURN is used for relaying data from source to target. TURN consumes bandwidh and it is expensive.

Therefore there is a need for authorizing the TURN connection. However given that the connection is made from a client using javascript, use of a static username/password can be easily compromised.

Ephemeral password comes to the rescue here.


Learn WebRTC in 200 Line of code:
You will need a lot of patience going through libraries that are present today simply because they have thousands of line of code. So I will highly encourage you all to refer the source code located here: github.com/amiteshawa/learn-rtc

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
1,270
On Slideshare
1,254
From Embeds
16
Number of Embeds
2

Actions

Shares
Downloads
15
Comments
0
Likes
0

Embeds 16

https://twitter.com 12
https://www.linkedin.com 4

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. WebRTC Amitesh Madhur (@amiteshawa) Cisco Systems
  • 2. Agenda 1. Media Stream 2. Constraints 3. RTCPeerConnection 4. Network (STUN, TURN) 5. DataChannel 6. Ephemeral password
  • 3. Peer to peer, plugin free! X Server
  • 4. WebRTC 1. MediaStream 2. RTCPeerConnection 3. DataChannel
  • 5. Media Stream 1. 2. 3. 4. 5. getUserMedia Collects audio, video, screen inputs Synchronizes Audio & Video Noise Cancellation Image Enhancement
  • 6. <video id=“me" autoplay></video> navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia; if (navigator.getUserMedia) { navigator.getUserMedia({video: true}, onSuccess, onError); } window.URL = window.URL || window.webkitURL; var me = document.getElementById('me'); function onSuccess(stream) { me.src = window.URL.createObjectURL(stream); } function onError(e) { // error }
  • 7. Demo
  • 8. Confused Left/Right? <style> video { -webkit-transform: scaleX(-1); } </style> canvasContext.translate(width, 0); canvasContext.scale(-1, 1); <video id=“me" autoplay></video>
  • 9. <video id=“me" autoplay></video> navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia; navigator.getUserMedia( {video: true}, onSuccess, onError); window.URL = window.URL || window.webkitURL; if (navigator.getUserMedia) { navigator.getUserMedia({video: true}, onSuccess, onError); } var me = document.getElementById('me'); function onSuccess(stream) { me.src = window.URL.createObjectURL(stream); } Constraints function onError(e) { // error }
  • 10. Constraints (audio, video) {audio: true, video: true}
  • 11. Constraints (video height, width) { audio: true, video: { mandatory: { maxWidth: 320, maxHeight: 180 } } }
  • 12. Constraints for screen capture getUserMedia({video: { mandatory: { chromeMediaSource: 'screen' } }, audio: false}, onSuccess, onError);
  • 13. chromeMediaSource: 'screen' 1. Works only on https 2. chrome://flags/#enable-usermedia-screencapture
  • 14. Peer Connection
  • 15. 1. 2. 3. 4. Establish a connection though Signaling Pass the user media stream Other side gets the stream Add the received stream to <video> tag
  • 16. Demo
  • 17. github.com/amiteshawa/learn-rtc
  • 18. <video id=“me" autoplay></video> <video id=“other" autoplay></video> peer = new RTCPeerConnection(servers); peer.onaddstream = gotRemoteStream; peer.addStream(localStream); if(host) { peer.createOffer(callGotOffer, null, {mandatory: { OfferToReceiveAudio: true, OfferToReceiveVideo: true}}); } else { peer.createAnswer(peer.remoteDescription, callGotOffer); } function callGotOffer(sd) { peer.setLocalDescription(sd); } function gotAnswer(desc) { peer.setRemoteDescription(new RTCSessionDescription(desc)); } function gotRemoteStream(e) { attachMediaStream(remoteVideo, e.stream); }
  • 19. <video id=“me" autoplay></video> <video id=“other" autoplay></video> peer = new RTCPeerConnection(servers); peer.onaddstream = gotRemoteStream; peer.addStream(localStream); if(host) { peer.createOffer(callGotOffer, null, {mandatory: { OfferToReceiveAudio: true, var STUN, TURN, config = {}; OfferToReceiveVideo: true}}); } STUN {= { url: “stun:stun.l.google.com:19302”}; else peer.createAnswer(peer.remoteDescription, callGotOffer); TURN = { username: “turn-user", } credential: "NGFmNGRlMOWZmMTVmZGZiNg==", function callGotOffer(sd) { url: "turn:10.5.7.13:3333?transport=udp“ peer.setLocalDescription(sd); } }; function gotAnswer(desc) { config.iceServers = [STUN, TURN]; peer.setRemoteDescription(new RTCSessionDescription(desc)); } function gotRemoteStream(e) { attachMediaStream(remoteVideo, e.stream); }
  • 20. User 1 Page Load Renders Invite Button Websocket User 2 Page Load Renders Invite Button
  • 21. User 1 Page Load Websocket Open connection User 2 Open connection Page Load
  • 22. User 1 Page Load Websocket Open connection GUM Clicks Invite Button Create Invite User 2 Open connection Page Load
  • 23. User 1 Page Load Websocket Open connection Open connection GUM Create Invite User 2 Broadcast Invite Page Load
  • 24. User 1 Page Load Websocket Open connection User 2 Open connection Page Load GUM Create Invite Ignored Invite Broadcast Invite Invite Button Changed to “Join”
  • 25. User 1 Page Load Websocket Open connection User 2 Open connection Page Load GUM Create Invite Broadcast Invite Ignored Invite Offer SDP Offer SDP Invite Button Changed to “Join” Clicked Join Button GUM
  • 26. User 1 Page Load Websocket Open connection User 2 Open connection Page Load GUM Create Invite Broadcast Invite Ignored Invite Remote Desc Offer SDP Answer SDP Offer SDP Answer SDP Invite Button Changed to “Join” Clicked Join Button GUM Remote Desc
  • 27. User 1 Page Load Websocket Open connection User 2 Open connection Page Load GUM Create Invite Broadcast Invite Ignored Invite Remote Desc Offer SDP Answer SDP ICE Candidate Offer SDP Answer SDP ICE Candidate Invite Button Changed to “Join” Clicked Join Button GUM Remote Desc
  • 28. User 1 Page Load User 2 Websocket Open connection Open connection Page Load GUM Create Invite Broadcast Invite Ignored Invite Remote Desc Offer SDP Answer SDP Offer SDP Answer SDP ICE Candidate ICE Candidate ICE Candidate ICE Candidate Add Stream Add Stream Invite Button Changed to “Join” Clicked Join Button GUM Remote Desc
  • 29. User 1 Page Load Websocket Open connection User 2 Open connection Page Load GUM Create Invite Broadcast Invite Ignored Invite Remote Desc Offer SDP Answer SDP Offer SDP Answer SDP ICE Candidate Add Stream ICE Candidate ICE Candidate Invite Button Changed to “Join” Clicked Join Button GUM Remote Desc ICE Candidate Add Stream
  • 30. STUN/TURN and ICE
  • 31. S T U N N A T N A T
  • 32. S T U N N A T Not 100% Reliable N A T
  • 33. T U R N N A T S E C U R E N A T
  • 34. T U R N Expensive & Slow N A T S E C U R E N A T
  • 35. TURN ICE STUN S E C U R E N A T N A T
  • 36. Public STUN stun.l.google.com:19302 stun1.l.google.com:19302 stun2.l.google.com:19302 stun3.l.google.com:19302 stun4.l.google.com:19302
  • 37. Wanna Setup your own? slideshare.net/amiteshawa/webrtc-media-stra
  • 38. Data Channel
  • 39. RTCDataChannel 1. 2. 3. 4. Peer to peer data sharing Works with RTCPeerConnection Secure Websocket like APIs
  • 40. webkitRTCPeerConnection(config, {optional: [{RtpDataChannels: true}]}); channel = peer.createDataChannel("sendDataChanne l", {reliable: false}); channel.onopen = manageChannel; channel.onclose = manageChannel; }, sendData = function(data){ channel.send(data); }, onMsg = function(e){ obj.innerHTML += 'He: ' + e.data ; }, manageChannel = function(){
  • 41. Demo
  • 42. Ephemeral password
  • 43. IN JAVASCRIPT var turn; turn = { url: 'turn:<user-name>@<IP>:<PORT>', credential: ‘password‘ }; // for chrome 28 and above turn = { url: 'turn:<IP-address>:<PORT>', username: ‘<user-name>‘, credential: ‘<password>' };
  • 44. Ephemeral password 1. 2. 3. 4. 5. 6. Limited time TURN credentials Based on REST Service Webserver creates password Shared secret TURN Server does NOT implement the REST API Based on long-term credentials mechanism
  • 45. long-term credentials User TURN User sends request to TURN without password
  • 46. long-term credentials User TURN User sends request to TURN without password TURN send Error 401, with realm and nonce
  • 47. long-term credentials User TURN User sends request to TURN without password TURN send Error 401, with realm and nonce User Checks 401 and extracts realm and nonce
  • 48. long-term credentials User TURN User sends request to TURN without password TURN send Error 401, with realm and nonce User Checks 401 and extracts realm and nonce User generates MD5 key with user, realm
  • 49. long-term credentials User TURN User sends request to TURN without password TURN send Error 401, with realm and nonce User Checks 401 and extracts realm and nonce User generates MD5 key with user, realm User sends new request to TURN with password
  • 50. long-term credentials User TURN User sends request to TURN without password TURN send Error 401, with realm and nonce User Checks 401 and extracts realm and nonce User generates MD5 key with user, realm User sends new request to TURN with password TURN Validates Matches? Then connected
  • 51. Long-term password alone does not solve the problem for WebRTC
  • 52. Ephemeral credentials User TURN REST Server my-svc/get-turn-auth Creates username, password Shared Secret Sends username, password MySQL Send connection request to TURN After this it same as long term auth
  • 53. Create Tables CREATE TABLE turnusers_lt ( name varchar(512) PRIMARY KEY, hmackey char(32) ); CREATE TABLE turn_secret ( value varchar(512) ); CREATE TABLE allowed_peer_ip ( ip_range varchar(256) ); CREATE TABLE denied_peer_ip ( ip_range varchar(256) );
  • 54. Create REST API Generate username and credential username= <USER NAME> + ":" + <timestamp> password = base64(hmac-sha1(secret, username))
  • 55. { "username" : "user1:1393412082", "password" : "NGFmNzUzZDIxOWE1OWI0NTBmZGZiNg==", "ttl" : 86400, "uris" : [ "turn:1.2.3.4:3333?transport=udp" ] } var i, uri, iceServer, config = {"iceServers": []}; for (i = 0; i < response.uris.length; ++i) { uri = response.uris[i]; iceServer = { "username":response.username, "credential":response.password, "uri":uri }; config.iceServers.push(iceServer); } var pc = new PeerConnection(config);
  • 56. Config 1. In turnserver.conf Uncomment/Enable 1. 2. 3. 4. lt-cred-mech use-auth-secret static-auth-secret mysql-userdb="host=127.0.0.1 dbname=turn user=root password= port=3306 connect_timeout=60" 5. realm=foobar 6. fingerprint 7. Start turn: turnserver -c /usr/local/etc/turnserver.conf
  • 57. Create User & Secret Create Secret $ turnadmin --mysql-userdb="host=127.0.0.1 dbname=turn user=root password= connect_timeout=10" --set-secret=no1knows
  • 58. >= 21 >= 20 >= 12
  • 59. WebRTC4all…
  • 60. Thank you Twitter: @amiteshawa