pion / webrtc

Pure Go implementation of the WebRTC API
https://pion.ly
MIT License
13.44k stars 1.63k forks source link

DTLS with webRTC. #2764

Closed Tanmay49 closed 4 months ago

Tanmay49 commented 4 months ago

Your environment.

—> Certificates

—> Auth:

—> Business Logic:


import './style.css';
import mqtt from 'mqtt';
const servers = {
  iceServers: [  {
    urls: ['turns:192.168.1.66:3478?transport=udp'],
    username:'Bearer vPomRCrXuKxCbXQ6lDJ_sRPnH37wqc_SC0SZfse4w_Oq3bB25MrlPspbHHCTUlaBHkySIjo',
    credential: 'golain',
  },
  ],  iceCandidatePoolSize: 10,
};
// Global State
const pc = new RTCPeerConnection(servers);

let remoteStream = null;

// HTML elements
const webcamButton = document.getElementById('webcamButton');
const remoteVideo = document.getElementById('remoteVideo');

// 1. Setup media sources

const client = mqtt.connect('mqtt://173.249.7.183:1882');

webcamButton.onclick = async () => {
  remoteStream = new MediaStream();

  // Pull tracks from remote stream, add to video stream
  pc.ontrack = (event) => {
    event.streams[0].getTracks().forEach((track) => {
      remoteStream.addTrack(track);
    });
  };

  remoteVideo.srcObject = remoteStream;
    client.subscribe('offer', (err) => {
      if (err) {
        console.error(err);
        return;
      }

      console.log('Subscribed to topic');
    });

};

client.on('message', async (topic, message) => {
  var answerCandidates=[]
  pc.onicecandidate = (event) => {
    event.candidate && answerCandidates.push(event.candidate.toJSON());
    console.log(answerCandidates);
  };

  // Parse the message to get the offer and the candidates
  const data = JSON.parse(message.toString());
  const {offer, candidates} = data;

  console.log(offer, candidates);
  const offers = new RTCSessionDescription(offer);

  // Set the remote description using the offer
  await pc.setRemoteDescription(new RTCSessionDescription(offers));

  // Create an answer and set the local description
  const answerDescription = await pc.createAnswer();
  await pc.setLocalDescription(answerDescription);

  // Add each candidate to the RTCPeerConnection and wait for all to complete
  await Promise.all(candidates.map(candidate => pc.addIceCandidate(new RTCIceCandidate(candidate))));

  // Publish the answer

  pc.onicegatheringstatechange = () => {
  if (pc.iceGatheringState === 'complete') {
    console.log('ICE gathering complete');
    const answer = {
      type: answerDescription.type,
      sdp: answerDescription.sdp,
      answerCandidates: answerCandidates
    };
    console.log(JSON.stringify({ AnswerData: answer  }));
  client.publish('answer', JSON.stringify({ AnswerData: answer  }));
  }
}
});

Screenshot from 2024-05-03 08-44-22

What did we try?

https://github.com/pion/dtls/blob/master/examples/listen/selfsign/main.go

config := &dtls.Config{
        Certificates:         []tls.Certificate{cert},
        ClientAuth:           dtls.RequireAnyClientCert,
        ClientCAs:            certPool,
        InsecureSkipVerify:   true,
        ExtendedMasterSecret: dtls.RequireExtendedMasterSecret,
    }
        addr := &net.UDPAddr{IP: net.ParseIP("173.249.7.183"), Port: 3456}
    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()

    dtlsConn, err := dtls.DialWithContext(ctx, "udp", addr, config)
    util.Check(err)
    defer func() {
        util.Check(dtlsConn.Close())
    }()

This creates a successful connection and there is a successful handshake.The problem here is that we cannot create a webrtc Peer connection on top of this.

            ------------------ORIGINAL CODE------------------

udpAddr, connectErr := a.net.ResolveUDPAddr(network, turnServerAddr)
                if connectErr != nil {
                    a.log.Warnf("Failed to resolve UDP address %s: %v", turnServerAddr, connectErr)
                    return
                }

                udpConn, dialErr := a.net.DialUDP("udp", nil, udpAddr)
                if dialErr != nil {
                    a.log.Warnf("Failed to dial DTLS address %s: %v", turnServerAddr, dialErr)
                    return
                }

                conn, connectErr := dtls.ClientWithContext(ctx, udpConn, &dtls.Config{
                    ServerName:         url.Host,
                    InsecureSkipVerify: a.insecureSkipVerify, //nolint:gosec
                })
            -----------------------------------------------------

            --------------MODIFIED CODE-------------------------
            case url.Proto == stun.ProtoTypeUDP && url.Scheme == stun.SchemeTypeTURNS:
                udpAddr, connectErr := a.net.ResolveUDPAddr(network, turnServerAddr)
                if connectErr != nil {
                    a.log.Warnf("Failed to resolve UDP address %s: %v", turnServerAddr, connectErr)
                    return
                }

                udpConn, dialErr := a.net.DialUDP("udp", nil, udpAddr)
                if dialErr != nil {
                    a.log.Warnf("Failed to dial DTLS address %s: %v", turnServerAddr, dialErr)
                    return
                }
                cert, err := tls.LoadX509KeyPair("Device1.pub.pem", "Device1.pem")
                if err != nil {
                    panic(err)
                }

                conn, connectErr := dtls.ClientWithContext(ctx, udpConn, &dtls.Config{
                    ServerName:         url.Host,
                    InsecureSkipVerify: a.insecureSkipVerify, //nolint:gosec
                    Certificates:       []tls.Certificate{cert},
                    ClientAuth:        dtls.RequireAndVerifyClientCert,
                    ClientCAs: ,
                })
                if connectErr != nil {
                    a.log.Warnf("Failed to create DTLS client: %v", turnServerAddr, connectErr)
                    return
                }

                relAddr = conn.LocalAddr().(*net.UDPAddr).IP.String() //nolint:forcetypeassert
                relPort = conn.LocalAddr().(*net.UDPAddr).Port        //nolint:forcetypeassert
                relayProtocol = "dtls"
                locConn = &fakenet.PacketConn{Conn: conn}

This creates a successful DTLS connection with the server. This also fails and throws error Bad Certificates when wrong certificates are provided which is the expected behaviour.

dtls DEBUG: 14:28:31.389291 conn.go:755: CipherSuite not initialized, queuing packet
dtls DEBUG: 14:28:31.390055 conn.go:678: received packet of next epoch, queuing packet
turn DEBUG: 14:28:31.518817 server.go:38: Received 36 bytes of udp from 103.157.123.186:37058 on [::]:3456
turn DEBUG: 14:28:31.519568 server.go:63: Handling TURN packet
turn DEBUG: 14:28:31.519828 turn.go:21: Received AllocateRequest from 103.157.123.186:37058
turn DEBUG: 14:28:31.646542 server.go:38: Received 176 bytes of udp from 103.157.123.186:37058 on [::]:3456
turn DEBUG: 14:28:31.646589 server.go:63: Handling TURN packet
turn DEBUG: 14:28:31.646616 turn.go:21: Received AllocateRequest from 103.157.123.186:37058
Device 1 dev.golain.io 103.157.123.186:37058
turn DEBUG: 14:28:31.646836 allocation_manager.go:116: Listening on relay address: 173.249.7.183:34044
turn DEBUG: 14:28:31.914046 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:31 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:31.976767 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:31 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:32.036830 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:32 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:32.099533 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:32 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:32.162344 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:32 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:32.190550 server.go:38: Received 180 bytes of udp from 103.157.123.186:37058 on [::]:3456
turn DEBUG: 14:28:32.190639 server.go:63: Handling TURN packet
turn DEBUG: 14:28:32.190658 turn.go:220: Received CreatePermission from 103.157.123.186:37058
Device 1 dev.golain.io 103.157.123.186:37058
turn DEBUG: 14:28:32.190723 turn.go:250: Adding permission for 192.168.1.66:49671
turn DEBUG: 14:28:32.225874 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:32 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:32.286379 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:32 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:32.316566 server.go:38: Received 144 bytes of udp from 103.157.123.186:37058 on [::]:3456
turn DEBUG: 14:28:32.316617 server.go:63: Handling TURN packet
turn DEBUG: 14:28:32.316631 turn.go:275: Received SendIndication from 103.157.123.186:37058
turn DEBUG: 14:28:32.317461 server.go:38: Received 188 bytes of udp from 103.157.123.186:37058 on [::]:3456
turn DEBUG: 14:28:32.317486 server.go:63: Handling TURN packet
turn DEBUG: 14:28:32.317501 turn.go:308: Received ChannelBindRequest from 103.157.123.186:37058
Device 1 dev.golain.io 103.157.123.186:37058
turn DEBUG: 14:28:32.317598 turn.go:346: Binding channel 16384 to 192.168.1.66:49671
turn DEBUG: 14:28:32.349460 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:32 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:32.412439 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:32 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:32.474458 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:32 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:32.517953 server.go:38: Received 104 bytes of udp from 103.157.123.186:37058 on [::]:3456
turn DEBUG: 14:28:32.518012 server.go:48: Received DataPacket from 103.157.123.186:37058
turn DEBUG: 14:28:32.518028 turn.go:362: Received ChannelData from 103.157.123.186:37058
turn DEBUG: 14:28:32.536921 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:32 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:32.599522 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:32 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:32.661949 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:32 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:32.718505 server.go:38: Received 104 bytes of udp from 103.157.123.186:37058 on [::]:3456
turn DEBUG: 14:28:32.718648 server.go:48: Received DataPacket from 103.157.123.186:37058
turn DEBUG: 14:28:32.718666 turn.go:362: Received ChannelData from 103.157.123.186:37058
turn DEBUG: 14:28:32.724339 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:32 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:32.786786 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:32 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:32.851744 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:32 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:32.913685 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:32 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:32.920312 server.go:38: Received 104 bytes of udp from 103.157.123.186:37058 on [::]:3456
turn DEBUG: 14:28:32.920364 server.go:48: Received DataPacket from 103.157.123.186:37058
turn DEBUG: 14:28:32.920373 turn.go:362: Received ChannelData from 103.157.123.186:37058
turn DEBUG: 14:28:32.974925 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:32 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:33.036948 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:33 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:33.101108 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:33 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:33.120217 server.go:38: Received 104 bytes of udp from 103.157.123.186:37058 on [::]:3456
turn DEBUG: 14:28:33.120298 server.go:48: Received DataPacket from 103.157.123.186:37058
turn DEBUG: 14:28:33.120312 turn.go:362: Received ChannelData from 103.157.123.186:37058
turn DEBUG: 14:28:33.162646 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:33 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:33.225575 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:33 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:33.287036 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:33 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:33.321045 server.go:38: Received 104 bytes of udp from 103.157.123.186:37058 on [::]:3456
turn DEBUG: 14:28:33.321109 server.go:48: Received DataPacket from 103.157.123.186:37058
turn DEBUG: 14:28:33.321134 turn.go:362: Received ChannelData from 103.157.123.186:37058
turn DEBUG: 14:28:33.350038 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:33 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:33.411987 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:33 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:33.474377 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:33 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:33.521546 server.go:38: Received 104 bytes of udp from 103.157.123.186:37058 on [::]:3456
turn DEBUG: 14:28:33.521603 server.go:48: Received DataPacket from 103.157.123.186:37058
turn DEBUG: 14:28:33.521618 turn.go:362: Received ChannelData from 103.157.123.186:37058
turn DEBUG: 14:28:33.537050 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:33 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:33.599417 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:33 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:33.661927 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:33 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:33.722146 server.go:38: Received 104 bytes of udp from 103.157.123.186:37058 on [::]:3456
turn DEBUG: 14:28:33.722202 server.go:48: Received DataPacket from 103.157.123.186:37058
turn DEBUG: 14:28:33.722244 turn.go:362: Received ChannelData from 103.157.123.186:37058
turn DEBUG: 14:28:33.724800 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:33 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:33.788307 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:33 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:33.849916 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:33 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:33.911912 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:33 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:33.974385 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:33 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:34.036846 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:34 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:34.099552 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:34 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:34.161925 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:34 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:34.224924 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:34 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:34.286985 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:34 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:34.350392 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:34 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044
turn DEBUG: 14:28:34.411921 allocation.go:246: Relay socket 173.249.7.183:34044 received 108 bytes from 103.157.123.186:49671
turn INFO: 2024/05/02 14:28:34 No Permission or Channel exists for 103.157.123.186:49671 on allocation 173.249.7.183:34044

What should we expect?

Tanmay49 commented 4 months ago

We were able to figure out the problem with our implementation. --> Firstly, the allocation problem was that we were making a tcp connection from the web client(here:chrome browser) but the web client was generating udp ice candidates. So we had to change the tcp listener to an udp listener on the TURN server. --> Secondly, there is an issue with the way CA certs work. The current webRTC library does not use the provided support for custom CA cert in the certpool hence it was giving us BadCertificate error on the TURN server and signed by unknown authority on the device (here:Raspberry PI). We added the certificate to the OS and then it was working as the DTLS connection does not support using the certificate programatically. @Sean-Der can we make a PR for this ? We were thinking of adding it to the settings engine and then to the agent so it will be accessible in the gatherCandidateRelay method.