kixelated / moq-rs

Rust library for Media over QUIC
Apache License 2.0
385 stars 56 forks source link

Browser support / possible certs issue (local dev demo not working) #124

Open wormoworm opened 9 months ago

wormoworm commented 9 months ago

I'm working on a proof-of-concept that aims to demonstrate video streaming from one machine to another using QUIC.

My first goal in this project is to demonstrate streaming "via localhost" - i.e. running the relay and publisher on the same machine as I view the stream on. To do this have been following the Local Development guide. The machine in question is running Windows 11, and the moq-rs binaries are all running inside a WSL2 Ubuntu 20.04 container.

Errors I am seeing I am running into problems when trying to view the stream in a browser. This is what I see in various browsers I have tried:

The steps I am following are:

Other things I have tried

Questions

Any help with this would be greatly appreciated. I'm not really sure what's going on here - I'm a bit of a newbie to this sort of thing! And if you are able to share the details of a known working setup, perhaps I can use that to help diagnose my issue.

I have attached logs from a run of the relay and publisher, in case they help: moq-rs-logs-1.txt

Thanks for any help in advance!

kixelated commented 9 months ago

It sounds like serverCertificateHashes isn't supported on Firefox yet. We use this hash to serve thr self-signed cert for local development because of a Chrome bug; it doesn't use the local CA for WebTransport only.

  1. Can you try Chrome? Firefox is untested.
  2. Can you comment out serverCertificateHashes in moq-js? It might work in Firefox depending on the cert manager.

When you search for where to comment out, you might notice that it only uses the fingerprint if the hostname starts with "localhost". You can use a different hostname to avoid this behavior if you don't want to run your own copy of moq-js.

Something like: echo dev.moq 127.0.0.1 >>> /etc/hosts And then: https://quic.video/watch/Hefring?server=dev.moq:4443

wormoworm commented 9 months ago
wormoworm commented 9 months ago

I think I made some progress - instead of passing a hostname in the server GET param, I tried passing the IP address of the network adapter that WSL is using, giving me this URL: https://quic.video/watch/Hefring?server=172.30.137.205:4443.

Now when I hit that URL, I see more activity in the relay - it gets further through the handshake before failing. Below is the output I see when hitting that URL in both Chrome and FF nightly:

---------------------------------
CHROME
---------------------------------

[2023-11-15T15:13:03Z DEBUG rustls::server::hs] decided upon suite TLS13_AES_128_GCM_SHA256
[2023-11-15T15:13:03Z DEBUG rustls::server::hs] Chosen ALPN protocol [104, 51]
[2023-11-15T15:13:03Z DEBUG moq_relay::session] received QUIC handshake: ip=[::ffff:172.30.128.1]:58199
[2023-11-15T15:13:03Z WARN  moq_relay::quic] connection terminated: failed to establish QUIC connection

    Caused by:
        aborted by peer: the cryptographic handshake failed: error 46: 199:TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown

---------------------------------
FIREFOX NIGHTLY
---------------------------------

[2023-11-15T15:13:25Z DEBUG rustls::server::hs] decided upon suite TLS13_AES_128_GCM_SHA256
[2023-11-15T15:13:25Z DEBUG rustls::server::hs] Chosen ALPN protocol [104, 51]
[2023-11-15T15:13:25Z DEBUG moq_relay::session] received QUIC handshake: ip=[::ffff:172.30.128.1]:62107
[2023-11-15T15:13:25Z WARN  moq_relay::quic] connection terminated: failed to establish QUIC connection

    Caused by:
        aborted by peer: the cryptographic handshake failed: error 48
kixelated commented 9 months ago

I think you stumbled upon the fact that the QUIC server is binding to a different address than the browser is trying to connect to. Ignore Firefox for now, it's a red herring.

You can't use an IP address in the ?server parameter unless the TLS certificate is valid for that IP. Try adding the IP to dev/cert or adding the equivalent of /etc/hosts to have localhost.moq point to 172.30.137.205.

I believe that Quiche binds to a single interface instead of all interfaces like intended with 0.0.0.0. I've never tested this code on Windows but yeah, the split network interfaces sounds like an issue.

wormoworm commented 9 months ago

I made some more progress today by running everything (relay, publisher and moq-js client) on a Pi4. This worked pretty much out-of-the-box, which is great as it proves that most of the setup is fine.

What I'm trying to get working now is running the client on another machine on the same LAN (so relay and publisher on the Pi, client on another machine). My process is as follows:

One thing I have noticed is that the readme for the development scripts mention that the serverFingerprints options must be used - but I don't see any occurence of this string in this repo, or in moq-js. Since this section of that readme talks about WebTransport and certificates, I feel like it might be relevant!

kixelated commented 9 months ago

mkcert needs to be run on the host that will accept the cert. That means mkcert on the client and copy the generated cert to the server (Pi).

serverCertificatesHash not serverFingerprints

wormoworm commented 9 months ago

I tried running mkcert on the client machine (the machine that will recieved the video stream), but I'm still getting a TLS error 46 during handshake. Below are the steps I'm taking:

I'm still getting the same TLS error 46 - below are all the logs that result from attempting to load the stream URL in Chrome on the client machine:

[2023-11-20T17:58:48Z DEBUG rustls::server::hs] decided upon suite TLS13_AES_128_GCM_SHA256
[2023-11-20T17:58:48Z DEBUG rustls::server::hs] Chosen ALPN protocol [104, 51]
[2023-11-20T17:58:48Z DEBUG moq_relay::session] received QUIC handshake: ip=[::ffff:10.0.1.50]:49530
2023-11-20T17:58:48.936467Z ERROR quinn_udp::imp: got transmit error, halting segmentation offload
2023-11-20T17:58:48.936798Z  WARN quinn_udp: sendmsg error: Os { code: 5, kind: Uncategorized, message: "Input/output error" }, Transmit: { destination: [::ffff:10.0.1.50]:49530, src_ip: Some(::ffff:10.0.1.199), enc: Some(Ect0), len: 1305, segment_size: Some(1200) }
[2023-11-20T17:58:49Z WARN  moq_relay::quic] connection terminated: failed to establish QUIC connection

    Caused by:
        aborted by peer: the cryptographic handshake failed: error 46: 199:TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown
wormoworm commented 9 months ago

I had some (limited) success by using Firefox. In FF, you can make exception for individual certificates, so I visited https://:4443 whilst the relay was running, and accepted the certificate. I was then able to visit https://quic.video/watch/dev?server=:4443 and view the video stream. However, the stream itself is very unstable (I'm guessing this is caused by FF's WebTransport implementation):

I believe my problems boil down to the following two statements:

  1. I am unable to get Chrome to trust the certificate that is being served by relay. As per the posts above, I've tried generating certificates on both the server and the client machine, and I've tried every method I know of importing the generated CA into the Windows / Ubuntu certificate stores. The error I see in Chrome's console is net::ERR_QUIC_PROTOCOL_ERROR.QUIC_TLS_CERTIFICATE_UNKNOWN (TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown)
  2. The only browser that will allow me to trust the certificate is Firefox, which currently has a very buggy implementation of WebTransport / WebCodecs.

Are you able to share how you import certificates into the certificate store in such a way that Chrome will trust them? mkcert reports that it has installed the CA in FF's and Chrome's trust stores: The local CA is now installed in the Firefox and/or Chrome/Chromium trust store (requires browser restart)!, but Chrome is still not accepting the cert.

wormoworm commented 9 months ago

Hi, I'm still not able to get Chrome to accept the self-signed certificate, despite mkcert reporting The local CA is now installed in the Firefox and/or Chrome/Chromium trust store (requires browser restart)!.

Any ideas on what I might be missing?