aleph

lepistane 2024-09-10T15:39:44.943649Z

I've been using http2 example as reference and

(def http2-ssl-ctx
  "This creates a self-signed certificate SslContext that supports both HTTP/2
   and HTTP/1.1. The protocol array lists which protocols are acceptable, and
   the order indicates the preference; in this example, HTTP/2 is preferred over
   HTTP/1 if the client supports both.

   NB: Avoid self-signed certs unless you control the clients, too. Browsers
   will not accept them. See aleph.netty/ssl-server-context."
  (netty/self-signed-ssl-context
   "localhost"
   {:application-protocol-config (netty/application-protocol-config [:http2 :http1])}))


(http/start-server #'api-v1 {:port port
                             :http-versions [:http2 :http1]
                             :ssl-context http2-ssl-ctx})
Kinda works for (from browser i get odd certificate warning but that's to be expected) But when i try to do i expected http/1 to be served and yet i get The connection was reset and on the backend
Sep 10, 2024 3:36:34 PM io.netty.handler.ssl.ApplicationProtocolNegotiationHandler handshakeFailure
WARNING: [id: 0xad2fa4cd, L:0.0.0.0/0.0.0.0:8080] TLS handshake failed:
io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record:
Is this to be expected?

2024-09-10T15:42:54.695179Z

Looks like you are trying to do https and http on the same port, which I've never seen done before (http is typically port 80, https is 443, but you are overriding the port in your urls to be 8080 for both)

2024-09-10T15:44:19.222509Z

Neither http or https in the URL have anything to do with http1 vs http2, so I am not sure why changing that in the URL would change how you expect the connection to happen?

lepistane 2024-09-10T15:53:53.464159Z

So there is skill gap here i think. I've just followed example without much deeper thought. I can't have my connection on 433 address is already in use. What i expected to have is http/2 as optional thing that clients may use if they want to but still use http/1 as primary way of connecting to the backend.

2024-09-10T15:54:46.629899Z

Sure, what you have there likely speaks both http1 and http2, it just expects it over tls

2024-09-10T15:55:01.414979Z

Https != Http2

👍 1
lepistane 2024-09-10T15:58:58.945649Z

Is there a way for me to force http/1 connection via browser/curl/postman? to make sure what you said is the case (both are served)

2024-09-10T16:01:47.354989Z

There for sure is a curl command line option, check the man page

👍 1
lepistane 2024-09-10T16:16:33.604239Z

It's quite possible i don't know even how to ask the question... in order to get response i ignored certificate

curl --http1.1 -v  -k

curl --http2 -v  -k
This allowed me to verify that both are supported on the port i specified which is nice. Reason why i was mentioning https is because http2 requires certificate to work with browsers and in production environment i can't be using self signed ssl-context. To make matter little more complicated we are using nginx for reverse proxy and i am not sure and and what kind of config needs to be set in order for nginx to pass http/2 requests to the webserver.

lepistane 2024-09-10T16:19:54.281479Z

Which certificates should be used in prod environment? Is there a way to setup automatic certificate refresh with open ssl?

lepistane 2024-09-10T16:20:26.096509Z

I think i am basically looking for advice on how to use http/2 in production environment

2024-09-10T16:31:12.335449Z

I am pretty sure that the most common way to deploy http2 is to terminate it at the load balancer and have the loader balancer just speak http1 to the backend

👍 1
dergutemoritz 2024-09-13T10:19:37.263909Z

Note that it's also possible to use HTTP/2 over a non-TLS TCP connection (exposed in Aleph via the use-h2c? server option). But I would also recommend the approach suggested by @hiredman

lepistane 2024-10-01T18:45:03.515139Z

Thank you everyone for the context. This proved to be super helpful!

👍 1
Matthew Davidson 2024-09-15T08:30:19.173149Z

> Is there a way for me to force http/1 connection via browser/curl/postman? to make sure what you said is the case (both are served) Curl, yes. Browser, don't think so. Postman, they finally added it in mid-August. Generally, I've found curl to be the best bet for testing advanced HTTP features.

Matthew Davidson 2024-09-15T08:40:19.278599Z

> What i expected to have is http/2 as optional thing that clients may use if they want to but still use http/1 as primary way of connecting to the backend. You can do this via Application-Layer Protocol Negotiation (ALPN), where, in the process of setting up the SSL/TLS connection, the two peers advertise which protocols they support, and the client peer picks one. E.g., setting :application-protocol-config (netty/application-protocol-config [:http2 :http1]) says "I support HTTP1 and HTTP2, and prefer HTTP2". The only catch is, the server can't force the client to choose http1 over http2 while still supporting both, if that's what you want.

Matthew Davidson 2024-09-15T08:45:04.834159Z

(NB: I don't know of a way to do that in a nonsecure way. Generally, HTTP2 doesn't support public-facing cleartext connections for security purposes. Though I'm sure somewhere out there, someone's written a server that examines the first few bytes after forming the TLS connection, and determines whether it's HTTP1 or 2.)

Matthew Davidson 2024-09-15T09:52:27.008919Z

If you're behind a load balancer/reverse proxy, then browser --H2-> proxy --H1--> server will work just fine. Most of HTTP2's advantages are primarily for browsers over the public net, and much less important over internal networks. That being said, there are some disadvantages. H2 traffic is pretty common these days, and the formats are very different from H1 to H2/3, so the proxy will have to convert everything in both directions. On top of which, H2 is smaller and more efficient to parse, so converting adds a bit of CPU and bandwidth overhead to both the proxy and the server. From a security perspective, downgrading makes the connection vulnerable to the union of each protocols' vulnerabilities. And H1 makes it slightly easier/more tempting to use unencrypted traffic internally. Nothing major, though. TBH, I think H2 on the internal side would be just as good a default as H1 these days, but since nginx won't support it (despite already having a gRPC proxy, which requires H2), it's not that common.