Skip to content

Enable HTTP/2 support in the router#216

Merged
helgi merged 1 commit into
deis:masterfrom
felixbuenemann:http2-support
Jul 13, 2016
Merged

Enable HTTP/2 support in the router#216
helgi merged 1 commit into
deis:masterfrom
felixbuenemann:http2-support

Conversation

@felixbuenemann
Copy link
Copy Markdown
Contributor

@felixbuenemann felixbuenemann commented Jul 9, 2016

This enables HTTP/2 over TLS in the DEIS Workflow router.

The config change is all that's needed, because NGINX is already compiled with the http_v2 module and ALPN support (provided by openssl 1.0.2+).

This fixes #204.

You can pull image docker.io/felixbuenemann/router:canary for manual testing.

@deis-admin
Copy link
Copy Markdown

Thanks for the contribution! Please ensure your commits follow our style guide. This code will be tested once a Deis maintainer reviews it.

@deis-bot
Copy link
Copy Markdown

deis-bot commented Jul 9, 2016

@krancour and @helgi are potential reviewers of this pull request based on my analysis of git blame information. Thanks @felixbuenemann!

@codecov-io
Copy link
Copy Markdown

codecov-io commented Jul 9, 2016

Current coverage is 45.24%

Merging #216 into master will not change coverage

@@             master       #216   diff @@
==========================================
  Files             3          3          
  Lines           305        305          
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
  Hits            138        138          
  Misses          162        162          
  Partials          5          5          

Powered by Codecov. Last updated by af5c258...d7209bb

@felixbuenemann
Copy link
Copy Markdown
Contributor Author

A simple commandline test that http2 with ALPN is working can be achieved using:

openssl s_client -connect deis.example.com:443 -alpn 'h2'
…
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
ALPN protocol: h2
…

To test older NPN negotiation:

openssl s_client -connect deis.example.com:443 -nextprotoneg 'h2'
…
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
Next protocol: (1) h2
No ALPN negotiated
…

@arschles
Copy link
Copy Markdown
Member

I'm ok with this change. I'd like @krancour to also take a look at this patch (if available), but I'm LGTM1ing it

@arschles arschles added the LGTM1 label Jul 13, 2016
@helgi helgi merged commit 4024db4 into deis:master Jul 13, 2016
@felixbuenemann felixbuenemann deleted the http2-support branch July 14, 2016 00:12
@krancour
Copy link
Copy Markdown
Contributor

I'm a little late to the game here, but this does not exclude the use of HTTP 1.1, correct?

@helgi
Copy link
Copy Markdown
Contributor

helgi commented Jul 14, 2016

Nope

@krancour
Copy link
Copy Markdown
Contributor

@felixbuenemann thank you very much for this contribution!

@felixbuenemann
Copy link
Copy Markdown
Contributor Author

@krancour If you enable http2 in nginx on a listen ssl port, it wil use the TLS NPN and ALPN extensions for negotiating a supported protocol with the client. If the client does not support either NPN or ALPN it will simply speak HTTP/1.1, HTTP/1.0 or HTTP/0.9.

If you however put http2 on a non-ssl port in nginx, that port will only speak HTTP/2, so you will need a load balancer like haproxy in front of it, which handles ssl termination and protocol negotiation and sends traffic to different ports based on the negotiated protocol.

@krancour
Copy link
Copy Markdown
Contributor

If you however put http2 on a non-ssl port in nginx, that port will only speak HTTP/2

I feel a little concerned by that statement. Our preference is any load balancer in front of the router is TCP-based and not HTTP-based.

@felixbuenemann
Copy link
Copy Markdown
Contributor Author

felixbuenemann commented Jul 14, 2016

@krancour No need to be concerned.

This is fine:

listen 443 ssl http2;

In this case port 443 speaks both HTTP/1.1 and HTTP/2. If the client does support neither NPN nor ALPN it will use whatever non HTTP/2 protocol it chooses to speak. NGINX supports HTTP/0.9, HTTP/1.0 and HTTP/1.1 in this case. If the client supports NPN or ALPN it will negotiate with NGINX to use either HTTP/2 (h2) or HTTP/1.1.

This is not fine:

listen 80 http2;

That would switch port 80 to only speak http2 and break all clients, because there is no way to negotiate wether a client wants to speak http or http/2.

So to get a working setup you would need something like:

listen 80 proxy_protocol;
listen 81 http2 proxy_protocol;

And slap a HAProxy in front of it which terminates SSL (not HTTPS), negotiates HTTP/2 over ALPN and forwards the traffic to the right port, 80 for http and 81 for http/2.

We're only using http/2 on the ssl port, so none of the above is needed.

Did I make myself sufficiently clear this time?

@krancour
Copy link
Copy Markdown
Contributor

We're only using http/2 on the ssl port

That's the part I overlooked. Thanks.

@codyaray
Copy link
Copy Markdown

codyaray commented Nov 7, 2016

If I understand correctly, this router terminates the HTTP/2 connection and opens an HTTP/1.1 connection to the app rather than proxy/passthrough the HTTP/2 connection. If we want to proxy the HTTP/2 all the way to the backend, can Deis route/load balance TCP connections?

@bacongobbler
Copy link
Copy Markdown
Member

@codyaray you are indeed correct, according to the source. Feel like hacking up a PR to proxy http/2 connections all the way to the backend?

@bacongobbler
Copy link
Copy Markdown
Member

Or at the very least filing a new issue to track that

@felixbuenemann
Copy link
Copy Markdown
Contributor Author

I don't think nginx can do ssl vhosts in tcp mode, let alone mixing tcp and https vhosts. The only tool I know that can route to multiple tcp backends based on the SNI header is HAProxy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add http2 listen support.

9 participants