Issue
I have a tomcat 9.0.2 server supporting HTTP/2 and running on TLS1.2. Below is the connector configuration in server.xml
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
address="0.0.0.0"
maxThreads="150" SSLEnabled="true" asyncTimeout="10000" maxHeaderCount="50"
maxPostSize="1048576" scheme="https" secure="true" compression="force"
compressionMinSize="2048" maxConnections="10000">
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
<SSLHostConfig protocols="TLSv1.2">
<Certificate certificateKeystoreFile="${keystore.file.path}"
certificateKeystorePassword="${keystore.password}"
certificateKeyAlias="${server.cert.alias}"
certificateKeystoreType="${keystore.type}" />
</SSLHostConfig>
</Connector>
I am using HA Proxy 1.8 and configuration is like below
frontend mydomain-ux
mode http
bind <ip>:8080 ssl crt /etc/certs/mydomain.com.cert.pem
http-request set-var(txn.path) path
acl mydomain hdr_end(host) -i mydomain.com
use_backend mydomain_server if mydomain
backend mydomain_server
mode http
server mydomain_backeend_server <server-ip>:8443 ssl
Since, I have multiple backends based on host, I cannot use TCP mode and do pass through HTTP/2 SSL termination
Is there a way I can have HTTP/2 termination in backend mode http ?
Solution
As far as I'm aware HAProxy does not support HTTP/2 on the back end. They only recently announced front end support. (Edit 18th Jan 2019 - since added in v1.9 - https://www.haproxy.com/blog/haproxy-1-9-has-arrived/).
Even without backend HTTP/2 support, it is possible to terminate the front end on HTTPS, and then forward to the back end on TCP (without HTTPS), and it may be possible to use the SNI part of the HTTPS to do the optional routing you want (this is completely untested btw):
frontend mydomain-ux
mode tcp
bind <ip>:8080 ssl crt /etc/certs/mydomain.com.cert.pem alpn h2,http/1.1
use_backend mydomain_server if { ssl_fc_sni mydomain.com}
use_backend mydomain_server2 if { ssl_fc_sni mydomain2.com }
default_backend mydomain_server
backend mydomain_server
mode tcp
server mydomain_backeend_server <server-ip>:8081
This would allow your backend to speak HTTP/2 on port 8081 but without HTTPS (port 8443), and even works on HAProxy before 1.8 (when front end HTTP/2 support was added). However it would mean your Tomcat would need to be setup without SSL.
HAProxy also do not recommend using the SNI host for routing as discussed in this answer and in the the mailing thread it refers to. Plus additionally SNI support is not universal (though to all practical intents it is unless supporting really old browsers like IE8 on XP).
The other question you should ask yourself is if you really need HTTP/2 in the backend or if just supporting this at the HAProxy level is enough?
Answered By - Barry Pollard