NGINX-QUIC, ALPN offering only Http/1.1 and h2, but not h3
pluknet at nginx.com
Fri Sep 17 11:22:28 UTC 2021
> On 15 Sep 2021, at 09:39, J B <jeremias.bosch at gmail.com> wrote:
> Hello all,
> I played around with nginx-quic branch, following the blog post here https://www.nginx.com/blog/our-roadmap-quic-http-3-support-nginx/
> I have trouble to get my browser to use http3 with the server. I checked with CURL http3 enabled - there it works when providing the http3 option, it does not when using --alt-svc option.
> I assume it's a configuration issue, or an issue with self-signed certificates, ...
> What did I do:
> 1. Build Docker (copy from blogpost) and generate self signed certs.
> COPY ./nginx/csr.conf /root/csr.conf
> COPY ./nginx/cert.pass /etc/keys/cert.pass
> # generate self signed certificate
> RUN openssl genrsa -aes128 -passout "pass:supersecure" -out ca.key 4096
> RUN openssl req -new -config csr.conf -key ca.key -out ca.csr -passin "pass:supersecure"
> RUN openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt -passin "pass:supersecure"
> # copy them to /etc/ssl/
> RUN cp ca.crt /etc/ssl/certs/
> RUN cp ca.key /etc/ssl/private/
> RUN cp ca.csr /etc/ssl/private/
> # setup ssl config
> COPY ./nginx/ssl.conf /etc/nginx/conf.d/ssl.conf
> EXPOSE 80 443
> 2. Run the Docker with
> docker run -it --rm -p 443:443/udp -p 443:443/tcp nginx_quic
> Using HTTP3 enabled curl ends up in:
> ``` curl -k -vvv --alt-svc altsvc.cache https://localhost:443
> * Trying 127.0.0.1:443...
> * TCP_NODELAY set
> * Connected to localhost (127.0.0.1) port 443 (#0)
> * ALPN, offering h2
> * ALPN, offering http/1.1
> * successfully set certificate verify locations:
> * CAfile: /etc/ssl/certs/ca-certificates.crt
> CApath: /etc/ssl/certs
> * TLSv1.3 (OUT), TLS handshake, Client hello (1):
> * OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:443
> * Closing connection 0
> curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:443
This means you didn't proceed up to obtaining alternative services
as specified in the Alt-SVC HTTP response field.
Successful response would look like this:
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
< HTTP/1.1 200 OK
< Server: nginx/1.21.3
< Date: Fri, 17 Sep 2021 11:12:26 GMT
< Content-Type: text/plain
* Added alt-svc: localhost:443 over h3-29
< Alt-Svc: h3-29=":443"; ma=86400
Note the last two lines.
Then, on next curl command, with saved alt service:
$ curl -vvv --alt-svc svc.txt ...
* Alt-svc connecting from [h1]localhost:443 to [h3-29]localhost:443
> using http3 option on curl works as expected:
> ./curl -v --http3 https://localhost:443/
> * Trying 127.0.0.1:443...
> * Connect socket 5 over QUIC to 127.0.0.1:443
> * Connected to localhost () port 443 (#0)
> * Using HTTP/3 Stream ID: 0 (easy handle 0x55c46567b290)
> > GET / HTTP/3
> > Host: localhost
> > user-agent: curl/7.79.0-DEV
> > accept: */*
> * ngh3_stream_recv returns 0 bytes and EAGAIN
> < HTTP/3 200
> < server: nginx/1.21.3
> < date: Tue, 14 Sep 2021 22:21:26 GMT
> < content-type: text/html
> < content-length: 615
> < last-modified: Tue, 07 Sep 2021 15:21:03 GMT
> < etag: "6137835f-267"
> < alt-svc: h3=":443"; ma=2592000
> < quic-status: quic
> < x-quic: quic
> < accept-ranges: bytes
> Any Idea how to solve this?
The latest curl uses quic draft-29 if connecting directly.
I presume it would also expect the same version in Alt-Svc.
So, I'd try to substitute it with "h3-29" as provided above.
More information about the nginx-devel