owncloud / ocis

:atom_symbol: ownCloud Infinite Scale Stack
https://doc.owncloud.com/ocis/next/
Apache License 2.0
1.38k stars 181 forks source link

oCIS does not support HTTP/2 #5116

Open wkloucek opened 1 year ago

wkloucek commented 1 year ago

Describe the bug

Connections to oCIS without an additional reverse proxy are not using HTTP/2

Steps to reproduce

Steps to reproduce the behavior:

  1. ocis server
  2. curl --http2-prior-knowledge -v https://localhost:9200/config.json -k

Expected behavior

Get a response and see that HTTP/2 is used

Actual behavior

*   Trying 127.0.0.1:9200...
* Connected to localhost (127.0.0.1) port 9200 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS header, Finished (20):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.2 (OUT), TLS header, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN: server did not agree on a protocol. Uses default.
* Server certificate:
*  subject: O=Acme Corp; CN=OCIS
*  start date: Nov 24 10:03:00 2022 GMT
*  expire date: Nov 24 10:03:00 2023 GMT
*  issuer: O=Acme Corp; CN=OCIS
*  SSL certificate verify result: self-signed certificate (18), continuing anyway.
* Using HTTP2, server supports multiplexing
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* h2h3 [:method: GET]
* h2h3 [:path: /config.json]
* h2h3 [:scheme: https]
* h2h3 [:authority: localhost:9200]
* h2h3 [user-agent: curl/7.86.0]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x55d71fb11e60)
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> GET /config.json HTTP/2
> Host: localhost:9200
> user-agent: curl/7.86.0
> accept: */*
> 
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* OpenSSL SSL_write: Connection reset by peer, errno 104
* Failed sending HTTP2 data
* Connection #0 to host localhost left intact
curl: (55) OpenSSL SSL_write: Connection reset by peer, errno 104

Additional context

Can also be reproduced in the browser.

Our deployment exmaples are using HTTP/2 because we use Traefik as reverse proxy, that does HTTP/2

butonic commented 1 year ago

We should not allow disabling TLS. Http/2, as implemented by all browsers requires it. HTTP/2 without TLS is called H2C and is used eg by grpc.WithInsecure(). So, while not being without it's use, a proxy like traefik likely does not support H2C anyway (I did not check). See also the explanation by the mailgun team: https://www.mailgun.com/blog/dev-life/http-2-cleartext-h2c-client-example-go/

Traefik can be configured to trust self signed certificates: https://doc.traefik.io/traefik/routing/overview/#insecureskipverify

The correct solution would be to generate proper certificates and tell traefik how to trust it.

Finally, TLS connection negotiation overhead only occurs once, as HTTP/2 then reuses the connection. Which happens less for internal reverse proxy connections.

dragotin commented 1 year ago

@aduffeck has looked into this

aduffeck commented 1 year ago

jfyi the experimental branches from back then live at https://github.com/aduffeck/reva/commits/http2 and https://github.com/aduffeck/ocis/commits/http2.

They use an internal CA for signing and verifying the certificates so there's no need to skip verification. They also turn the remaining internal HTTP traffic into encrypted HTTPS traffic. Unfortunately that decreases overall performance a little, despite the fact that existing HTTPS traffic is HTTP/2 now.

dragonchaser commented 9 months ago

@tbsbdr && @micbar is this still a requirement to support http/2?