Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot connect to example server from Chrome via QUIC #3211

Closed
ydnar opened this issue Jun 24, 2021 · 19 comments
Closed

Cannot connect to example server from Chrome via QUIC #3211

ydnar opened this issue Jun 24, 2021 · 19 comments

Comments

@ydnar
Copy link
Contributor

ydnar commented Jun 24, 2021

I’m trying to connect to a quic-go server from Chrome on localhost with a self-signed certificate. It either fails with a TLS error (unknown certificate), or doesn’t connect at all.

I’ve tried both my own test server as well as the example server in this repo, with the same results. When run with the -tcp flag, the example server will happily serve content via HTTP/1.1, but Chrome refuses to open a QUIC connection.

I’ve tried the following matrix with both the example server and my own server:

  • Chrome (91.0.4472.114)
  • Chrome Canary (93.0.4552.0)
  • With and without the --origin-to-force-quic flag
  • With and without the --allow-insecure-localhost flag

The error message from Chrome, with --origin-to-force-quic enabled:

Screen Shot 2021-06-24 at 12 46 57 PM

Is there some known incompatibility between Chrome and quic-go? Am I missing something?

@marten-seemann
Copy link
Member

You'd have to look at Chrome's net log to find out why Chrome doesn't like the cert.

@ydnar
Copy link
Contributor Author

ydnar commented Jun 25, 2021

Chrome’s netlog shows the following error when connecting:

{"params":{"details":"net::ERR_CONNECTION_REFUSED","from_peer":false,"quic_error":51},"phase":0,"source":{"id":550,"start_time":"406774994","type":11},"time":"406774994","type":279},

However, I’m confused. Should the example in this repo work with Chrome, or not? Because with no changes, and no code of my own, I can’t get Chrome to talk to localhost via HTTP/3. Does it work for you?

@marten-seemann
Copy link
Member

What does the quic-go log say?

@ydnar
Copy link
Contributor Author

ydnar commented Jun 25, 2021

What does the quic-go log say?

When accessing https://localhost:6121/ via Chrome (release) with no additional command line flags:

❯ go run example/main.go -tcp -v -qlog
muxer Increased receive buffer size to 2048 kiB
Activating reading of ECN bits for IPv4.
Activating reading of ECN bits for IPv4.
server Listening for udp connections on 127.0.0.1:6121
http: TLS handshake error from 127.0.0.1:57206: remote error: tls: unknown certificate
http: TLS handshake error from 127.0.0.1:57207: remote error: tls: unknown certificate
&http.Request{Method:"GET", URL:(*url.URL)(0xc0001481b0), Proto:"HTTP/1.1", ProtoMajor:1, ProtoMinor:1, Header:http.Header{"Accept":[]string{"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"}, "Accept-Encoding":[]string{"gzip, deflate, br"}, "Accept-Language":[]string{"en-US,en;q=0.9"}, "Cache-Control":[]string{"max-age=0"}, "Connection":[]string{"keep-alive"}, "Sec-Ch-Ua":[]string{"\" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\""}, "Sec-Ch-Ua-Mobile":[]string{"?0"}, "Sec-Fetch-Dest":[]string{"document"}, "Sec-Fetch-Mode":[]string{"navigate"}, "Sec-Fetch-Site":[]string{"none"}, "Sec-Fetch-User":[]string{"?1"}, "Upgrade-Insecure-Requests":[]string{"1"}, "User-Agent":[]string{"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"}}, Body:http.noBody{}, GetBody:(func() (io.ReadCloser, error))(nil), ContentLength:0, TransferEncoding:[]string(nil), Close:false, Host:"localhost:6121", Form:url.Values(nil), PostForm:url.Values(nil), MultipartForm:(*multipart.Form)(nil), Trailer:http.Header(nil), RemoteAddr:"127.0.0.1:57209", RequestURI:"/", TLS:(*tls.ConnectionState)(0xc00015c790), Cancel:(<-chan struct {})(nil), Response:(*http.Response)(nil), ctx:(*context.cancelCtx)(0xc000143000)}
muxer Tracking 0 connection IDs and 0 reset tokens.

Edit: this is what’s currently on master. It can load https://localhost:6121/demo/tile via HTTP/1.1, but not via QUIC.

@ydnar
Copy link
Contributor Author

ydnar commented Jun 25, 2021

When I run Chrome Canary and try to load the same server (https://localhost:6121/demo/tile) on localhost, there’s no evidence it attempts to make a connection at all:

/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary --allow-insecure-localhost --origin-to-force-quic-on=localhost:6121

quic-go example logs:

🦗

@ydnar
Copy link
Contributor Author

ydnar commented Jun 27, 2021

Narrowed it down to an issue where localhost resolved to IPv6, but Go won’t listen on all interfaces if the listener binds to addr localhost:NNNN.

Now the issue seems to be related to TLS:

2021/06/27 09:09:08 server <- Received Initial packet.
2021/06/27 09:09:08 server 	Long Header{Type: Initial, DestConnectionID: 80ccd4f34ba3509b, SrcConnectionID: (empty), Token: (empty), PacketNumber: 0, PacketNumberLen: 0, Length: 1312, Version: draft-29}
2021/06/27 09:09:08 server Changing connection ID to 6c40204b.
2021/06/27 09:09:08 server -> Sending Retry
2021/06/27 09:09:08 server 	Long Header{Type: Retry, DestConnectionID: (empty), SrcConnectionID: 6c40204b, Token: 0x1bf3b39b37fd0e0ed4277564db357197bc873679fa717b29080d06bc14c62f132347ac9d6fd05042ff44469f9a86a3cc97ee918b6abe3763d7a8f15ee8b30aa94d86744b706138efbda6f711ef0bc9ec40c64abe6ab7f906006eed67964b38343297, Version: draft-29}
2021/06/27 09:09:08 server <- Received Initial packet.
2021/06/27 09:09:08 server Changing connection ID to 97c51ca3.
2021/06/27 09:09:08 muxer Adding connection IDs 6c40204b and 97c51ca3 for a new session.
2021/06/27 09:09:08 server <- Reading packet 2 (1330 bytes) for connection 6c40204b, Initial
2021/06/27 09:09:08 server 	Long Header{Type: Initial, DestConnectionID: 6c40204b, SrcConnectionID: (empty), Token: 0x1bf3b39b37fd0e0ed4277564db357197bc873679fa717b29080d06bc14c62f132347ac9d6fd05042ff44469f9a86a3cc97ee918b6abe3763d7a8f15ee8b30aa94d86744b706138efbda6f711ef0bc9ec40c64abe6ab7f906006eed67964b38343297, PacketNumber: 2, PacketNumberLen: 1, Length: 1217, Version: draft-29}
2021/06/27 09:09:08 server 	<- &wire.CryptoFrame{Offset: 0, Data length: 325, Offset + Data length: 325}
2021/06/27 09:09:08 server Received ClientHello message (325 bytes, encryption level: Initial)
2021/06/27 09:09:08 server Connection from: [::1]:60213
2021/06/27 09:09:08 server Installed Handshake Read keys (using TLS_AES_128_GCM_SHA256)
2021/06/27 09:09:08 server Processed Transport Parameters: &wire.TransportParameters{OriginalDestinationConnectionID: (empty), InitialSourceConnectionID: (empty), InitialMaxStreamDataBidiLocal: 6291456, InitialMaxStreamDataBidiRemote: 6291456, InitialMaxStreamDataUni: 6291456, InitialMaxData: 15728640, MaxBidiStreamNum: 100, MaxUniStreamNum: 103, MaxIdleTimeout: 30s, AckDelayExponent: 3, MaxAckDelay: 25ms, ActiveConnectionIDLimit: 0, MaxDatagramFrameSize: 65536}
2021/06/27 09:09:08 server Installed Handshake Write keys (using TLS_AES_128_GCM_SHA256)
2021/06/27 09:09:08 server Installed 1-RTT Write keys (using TLS_AES_128_GCM_SHA256)
2021/06/27 09:09:08 server 	Queueing ACK because the first packet should be acknowledged.
2021/06/27 09:09:08 server -> Sending coalesced packet (3 parts, 1232 bytes) for connection 80ccd4f34ba3509b
2021/06/27 09:09:08 server 	Long Header{Type: Initial, DestConnectionID: (empty), SrcConnectionID: 97c51ca3, Token: (empty), PacketNumber: 0, PacketNumberLen: 2, Length: 433, Version: draft-29}
2021/06/27 09:09:08 server 	-> &wire.AckFrame{LargestAcked: 2, LowestAcked: 2, DelayTime: 0s}
2021/06/27 09:09:08 server 	-> &wire.CryptoFrame{Offset: 0, Data length: 90, Offset + Data length: 90}
2021/06/27 09:09:08 server 	Long Header{Type: Handshake, DestConnectionID: (empty), SrcConnectionID: 97c51ca3, PacketNumber: 0, PacketNumberLen: 2, Length: 748, Version: draft-29}
2021/06/27 09:09:08 server 	-> &wire.CryptoFrame{Offset: 0, Data length: 726, Offset + Data length: 726}
2021/06/27 09:09:08 server 	Short Header{DestConnectionID: (empty), PacketNumber: 0, PacketNumberLen: 2, KeyPhase: 0}
2021/06/27 09:09:08 server 	-> &wire.StreamFrame{StreamID: 3, Fin: false, Offset: 0, Data length: 3, Offset + Data length: 3}
2021/06/27 09:09:08 muxer Tracking 4 connection IDs and 0 reset tokens.
2021/06/27 09:09:08 server Parsed a coalesced packet. Part 1: 1217 bytes. Remaining: 113 bytes.
2021/06/27 09:09:08 server <- Reading packet 3 (1217 bytes) for connection 97c51ca3, Initial
2021/06/27 09:09:08 server 	Long Header{Type: Initial, DestConnectionID: 97c51ca3, SrcConnectionID: (empty), Token: 0x1bf3b39b37fd0e0ed4277564db357197bc873679fa717b29080d06bc14c62f132347ac9d6fd05042ff44469f9a86a3cc97ee918b6abe3763d7a8f15ee8b30aa94d86744b706138efbda6f711ef0bc9ec40c64abe6ab7f906006eed67964b38343297, PacketNumber: 3, PacketNumberLen: 1, Length: 1104, Version: draft-29}
2021/06/27 09:09:08 server 	<- &wire.AckFrame{LargestAcked: 0, LowestAcked: 0, DelayTime: 248µs}
2021/06/27 09:09:08 server 	newly acked packets (1): [0]
2021/06/27 09:09:08 server 	updated RTT: 589.762µs (σ: 294.881µs)
2021/06/27 09:09:08 server 	<- &wire.ConnectionCloseFrame{IsApplicationError:false, ErrorCode:0x12e, FrameType:0x6, ReasonPhrase:"199:TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown"}
2021/06/27 09:09:08 server Peer closed session with error: CRYPTO_ERROR (0x12e) (frame type: 0x6): 199:TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown
2021/06/27 09:09:08 server Parsed a coalesced packet. Part 2: 113 bytes. Remaining: 0 bytes.
2021/06/27 09:09:08 server Dropping Initial keys.
2021/06/27 09:09:08 server <- Reading packet 4 (113 bytes) for connection 97c51ca3, Handshake
2021/06/27 09:09:08 server 	Long Header{Type: Handshake, DestConnectionID: 97c51ca3, SrcConnectionID: (empty), PacketNumber: 4, PacketNumberLen: 1, Length: 100, Version: draft-29}
2021/06/27 09:09:08 server 	<- &wire.AckFrame{LargestAcked: 0, LowestAcked: 0, DelayTime: 256µs}
2021/06/27 09:09:08 server 	newly acked packets (1): [0]
2021/06/27 09:09:08 server 	updated RTT: 589µs (σ: 220µs)
2021/06/27 09:09:08 server 	<- &wire.ConnectionCloseFrame{IsApplicationError:false, ErrorCode:0x12e, FrameType:0x6, ReasonPhrase:"199:TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown"}
2021/06/27 09:09:08 muxer Replacing session for connection ID 6c40204b with a closed session.
2021/06/27 09:09:08 server accepting unidirectional stream failed: CRYPTO_ERROR (0x12e) (frame type: 0x6): 199:TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown
2021/06/27 09:09:08 muxer Replacing session for connection ID 97c51ca3 with a closed session.
2021/06/27 09:09:08 server Accepting stream failed: CRYPTO_ERROR (0x12e) (frame type: 0x6): 199:TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown
2021/06/27 09:09:08 server Connection 80ccd4f34ba3509b closed.
2021/06/27 09:09:09 muxer Removing connection ID fcfa7a0a for a closed session after it has been retired.
2021/06/27 09:09:09 muxer Removing connection ID d06b6832 for a closed session after it has been retired.
2021/06/27 09:09:10 muxer Tracking 2 connection IDs and 0 reset tokens.
2021/06/27 09:09:12 muxer Tracking 2 connection IDs and 0 reset tokens.
2021/06/27 09:09:13 muxer Removing connection ID 97c51ca3 for a closed session after it has been retired.
2021/06/27 09:09:13 muxer Removing connection ID 6c40204b for a closed session after it has been retired.
2021/06/27 09:09:14 muxer Tracking 0 connection IDs and 0 reset tokens.
2021/06/27 09:09:38 server <- Received Initial packet.
2021/06/27 09:09:38 server 	Long Header{Type: Initial, DestConnectionID: 3bc65fd4a4b73818, SrcConnectionID: (empty), Token: (empty), PacketNumber: 0, PacketNumberLen: 0, Length: 1312, Version: draft-29}
2021/06/27 09:09:38 server Changing connection ID to 2b96090c.
2021/06/27 09:09:38 server -> Sending Retry
2021/06/27 09:09:38 server 	Long Header{Type: Retry, DestConnectionID: (empty), SrcConnectionID: 2b96090c, Token: 0x37150d4422315ad41d20ba0324e5bed1f345539346b6dce6310aa4557c1b3a403e85039b7eb1f5d3ce57f2914a3e06bba47045830245842c2b56c9357c15045c2b266fb61b6236c38e5cf9f7622c04987662f6b4ec5a810525ecbbe36f24fbdd921e, Version: draft-29}
2021/06/27 09:09:38 server <- Received Initial packet.
2021/06/27 09:09:38 server Changing connection ID to 862bf966.
2021/06/27 09:09:38 muxer Adding connection IDs 2b96090c and 862bf966 for a new session.
2021/06/27 09:09:38 server <- Reading packet 2 (1330 bytes) for connection 2b96090c, Initial
2021/06/27 09:09:38 server 	Long Header{Type: Initial, DestConnectionID: 2b96090c, SrcConnectionID: (empty), Token: 0x37150d4422315ad41d20ba0324e5bed1f345539346b6dce6310aa4557c1b3a403e85039b7eb1f5d3ce57f2914a3e06bba47045830245842c2b56c9357c15045c2b266fb61b6236c38e5cf9f7622c04987662f6b4ec5a810525ecbbe36f24fbdd921e, PacketNumber: 2, PacketNumberLen: 1, Length: 1217, Version: draft-29}
2021/06/27 09:09:38 server 	<- &wire.CryptoFrame{Offset: 0, Data length: 318, Offset + Data length: 318}
2021/06/27 09:09:38 server Received ClientHello message (318 bytes, encryption level: Initial)
2021/06/27 09:09:38 server Connection from: [::1]:62666
2021/06/27 09:09:38 server Installed Handshake Read keys (using TLS_AES_128_GCM_SHA256)
2021/06/27 09:09:38 server Processed Transport Parameters: &wire.TransportParameters{OriginalDestinationConnectionID: (empty), InitialSourceConnectionID: (empty), InitialMaxStreamDataBidiLocal: 6291456, InitialMaxStreamDataBidiRemote: 6291456, InitialMaxStreamDataUni: 6291456, InitialMaxData: 15728640, MaxBidiStreamNum: 100, MaxUniStreamNum: 103, MaxIdleTimeout: 30s, AckDelayExponent: 3, MaxAckDelay: 25ms, ActiveConnectionIDLimit: 0, MaxDatagramFrameSize: 65536}
2021/06/27 09:09:38 server Installed Handshake Write keys (using TLS_AES_128_GCM_SHA256)
2021/06/27 09:09:38 server Installed 1-RTT Write keys (using TLS_AES_128_GCM_SHA256)
2021/06/27 09:09:38 server 	Queueing ACK because the first packet should be acknowledged.
2021/06/27 09:09:38 server -> Sending coalesced packet (3 parts, 1232 bytes) for connection 3bc65fd4a4b73818
2021/06/27 09:09:38 server 	Long Header{Type: Initial, DestConnectionID: (empty), SrcConnectionID: 862bf966, Token: (empty), PacketNumber: 0, PacketNumberLen: 2, Length: 428, Version: draft-29}
2021/06/27 09:09:38 server 	-> &wire.AckFrame{LargestAcked: 2, LowestAcked: 2, DelayTime: 0s}
2021/06/27 09:09:38 server 	-> &wire.CryptoFrame{Offset: 0, Data length: 90, Offset + Data length: 90}
2021/06/27 09:09:38 server 	Long Header{Type: Handshake, DestConnectionID: (empty), SrcConnectionID: 862bf966, PacketNumber: 0, PacketNumberLen: 2, Length: 753, Version: draft-29}
2021/06/27 09:09:38 server 	-> &wire.CryptoFrame{Offset: 0, Data length: 731, Offset + Data length: 731}
2021/06/27 09:09:38 server 	Short Header{DestConnectionID: (empty), PacketNumber: 0, PacketNumberLen: 2, KeyPhase: 0}
2021/06/27 09:09:38 server 	-> &wire.StreamFrame{StreamID: 3, Fin: false, Offset: 0, Data length: 3, Offset + Data length: 3}
2021/06/27 09:09:38 server Parsed a coalesced packet. Part 1: 1217 bytes. Remaining: 113 bytes.
2021/06/27 09:09:38 server <- Reading packet 3 (1217 bytes) for connection 862bf966, Initial
2021/06/27 09:09:38 server 	Long Header{Type: Initial, DestConnectionID: 862bf966, SrcConnectionID: (empty), Token: 0x37150d4422315ad41d20ba0324e5bed1f345539346b6dce6310aa4557c1b3a403e85039b7eb1f5d3ce57f2914a3e06bba47045830245842c2b56c9357c15045c2b266fb61b6236c38e5cf9f7622c04987662f6b4ec5a810525ecbbe36f24fbdd921e, PacketNumber: 3, PacketNumberLen: 1, Length: 1104, Version: draft-29}
2021/06/27 09:09:38 server 	<- &wire.AckFrame{LargestAcked: 0, LowestAcked: 0, DelayTime: 296µs}
2021/06/27 09:09:38 server 	newly acked packets (1): [0]
2021/06/27 09:09:38 server 	updated RTT: 569.493µs (σ: 284.746µs)
2021/06/27 09:09:38 server 	<- &wire.ConnectionCloseFrame{IsApplicationError:false, ErrorCode:0x12e, FrameType:0x6, ReasonPhrase:"199:TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown"}
2021/06/27 09:09:38 server Peer closed session with error: CRYPTO_ERROR (0x12e) (frame type: 0x6): 199:TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown
2021/06/27 09:09:38 server Parsed a coalesced packet. Part 2: 113 bytes. Remaining: 0 bytes.
2021/06/27 09:09:38 server Dropping Initial keys.
2021/06/27 09:09:38 server <- Reading packet 4 (113 bytes) for connection 862bf966, Handshake
2021/06/27 09:09:38 server 	Long Header{Type: Handshake, DestConnectionID: 862bf966, SrcConnectionID: (empty), PacketNumber: 4, PacketNumberLen: 1, Length: 100, Version: draft-29}
2021/06/27 09:09:38 server 	<- &wire.AckFrame{LargestAcked: 0, LowestAcked: 0, DelayTime: 312µs}
2021/06/27 09:09:38 server 	newly acked packets (1): [0]
2021/06/27 09:09:38 server 	updated RTT: 569µs (σ: 213µs)
2021/06/27 09:09:38 server 	<- &wire.ConnectionCloseFrame{IsApplicationError:false, ErrorCode:0x12e, FrameType:0x6, ReasonPhrase:"199:TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown"}
2021/06/27 09:09:38 muxer Replacing session for connection ID 2b96090c with a closed session.
2021/06/27 09:09:38 muxer Replacing session for connection ID 862bf966 with a closed session.
2021/06/27 09:09:38 server Connection 3bc65fd4a4b73818 closed.
2021/06/27 09:09:38 server Accepting stream failed: CRYPTO_ERROR (0x12e) (frame type: 0x6): 199:TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown
2021/06/27 09:09:38 server accepting unidirectional stream failed: CRYPTO_ERROR (0x12e) (frame type: 0x6): 199:TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown
2021/06/27 09:09:40 muxer Tracking 2 connection IDs and 0 reset tokens.
2021/06/27 09:09:42 muxer Tracking 2 connection IDs and 0 reset tokens.
2021/06/27 09:09:43 muxer Removing connection ID 862bf966 for a closed session after it has been retired.
2021/06/27 09:09:43 muxer Removing connection ID 2b96090c for a closed session after it has been retired.
2021/06/27 09:09:44 muxer Tracking 0 connection IDs and 0 reset tokens.

I can’t find a way to get Chrome to accept a self-signed certificate for a QUIC connection.

@ydnar
Copy link
Contributor Author

ydnar commented Jun 27, 2021

@FZambia
Copy link

FZambia commented Jul 16, 2021

@ydnar hello, getting the same errors, have you found any solution to avoid (ENCRYPTION_HANDSHAKE) 46: certificate unknown errors?

@ydnar
Copy link
Contributor Author

ydnar commented Jul 16, 2021

@FZambia it seems like Chrome’s QUIC (or the underlying quiche library) differs how Chrome’s H1 and H2 TLS handles certificate verification.

  • How are you generating the TLS cert?
  • What hostname or IP address are you trying to access with Chrome?
  • What args are you passing to Chrome?

FWIW I was able to get this to work on localhost or 127.0.0.1 using mkcert and https://github.com/alta/insecure.

@FZambia
Copy link

FZambia commented Jul 16, 2021

@ydnar thanks a lot! I spent so much time trying to make it work. With installing CA over mkcert tool and using https://github.com/alta/insecure it finally works. I was also able to successfully run WebTransport example from your branch.

@ydnar
Copy link
Contributor Author

ydnar commented Jul 16, 2021

@ydnar thanks a lot! I spent so much time trying to make it work. With installing CA over mkcert tool and using https://github.com/alta/insecure it finally works. I was also able to successfully run WebTransport example from your branch.

Nice! What have you gotten working?

I’m working with a variation of this: https://gist.github.com/ydnar/f73e1806c50c83f90f9b46e13bf751fc

@FZambia
Copy link

FZambia commented Jul 17, 2021

What have you gotten working?

Thanks for sharing, I just used a simplified version of this you posted before, hopefully will play more with WT very soon.

For now a couple of observations:

  • Looks like the latest Chrome Canary (93) has broken WebTransport (or QUIC itself) implementation, because I can only connect to a server once and then all the following connection attempts result into connection lost (only MacOS restart helped me). In Chrome 91 connection behaviour is stable
  • Chrome does not close connection on tab close/reload - found this issue
  • Currently WebTransport only works if both sides support sending datagrams - wonder if this is a specification requirement? For example I can imagine servers that don't need to send/receive datagrams - only working with bidi/uni streams.

@ydnar
Copy link
Contributor Author

ydnar commented Jul 17, 2021

It definitely seems flaky. I've had decent luck with Crome Canary and retrying until it works.

QUIC datagram support is required for WebTransport.

I'm curious how/when the spec authors will resolve the multiplexing differences between the current H3 datagram draft and the WebTransport draft.

@wegylexy
Copy link

Can someone share what exactly is required to self-sign a cert that works with Chrome/Edge?

  • Does it have to chain to a CA, can't be a standalone cert?
  • What key usages and extended key usages are required? (e.g. serverAuth)
  • Which key algorithm? (e.g. ec -pkeyopt ec_paramgen_curve:prime256v1)

@ydnar
Copy link
Contributor Author

ydnar commented Feb 27, 2022

@wegylexy
Copy link

No, according to https://www.chromium.org/quic/playing-with-quic/ it requires starting Chrome with special switches to use a self-signed cert.

@edhemphill
Copy link

edhemphill commented Mar 2, 2024

Posting this here for a 2024 update - as I am sure plenty of folks want to test the example with Chrome:

To start the server you would do (binary from quic-go/example/main.go):

./example -bind 0.0.0.0:8888 -cert cert.pem -key key.pem -www ~/my-www

Assuming you just generated a self-sign cert with openssl, you can run Chrome like this:

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --enable-quic --allow-insecure-localhost --origin-to-force-quic-on=127.0.0.1:8888 --ignore-certificate-errors  --user-data-dir=/tmp/temp-chrome --ignore-certificate-errors-spki-list="1dCBR30ix2GJYCr2sPVOmiTfj+4ZdTHAqxu4NiQc5GQ="

To get the SPKI bas64 hash above you do this:

 openssl x509 -pubkey -noout -in ~/path-to-my-cert/cert.pem | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
1dCBR30ix2GJYCr2sPVOmiTfj+4ZdTHAqxu4NiQc5GQ=

It seems Chrome is irritatingly finicky about TLS self-sign with QUIC - but with all that it works.

Note a few things:

  • You must (according to their code comments) use the ignore-certificate-errors-spki-list option. You also must specify a user-data-dir
  • Don't use localhost if your machine uses both IPv6 and IPv4 b/c Chrome may default to IPv6. Like on a Mac.

@marten-seemann
Copy link
Member

What about using mkcert?

@edhemphill
Copy link

Nice! - had no idea about this tool - but will check it out. You would still need --origin-to-force-quic-on I would think (?). But that would take care of the spki issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants