Hi Sean, On Tue, Dec 11, 2018 at 04:22:53PM -0700, Sean Reifschneider wrote: > I've been trying to convert my haproxy setup (1.8.14) to by adding "alpn > h2,http/1.1" to my "bind" line in the frontend. My haproxy config is north > of 300 lines, so I'll hold off on attaching it. > > My frontend selects backends using something like: > > acl aerial_acl hdr(host) -m reg -i ^aerial[1-4].example.com > acl aerial_acl ssl_fc_sni -m reg -i ^aerial[1-4].example.com > use_backend aerial if aerial_acl > > acl wwwl_acl hdr(host) -m reg -i ^www.example.com > acl www_acl ssl_fc_sni -m reg -i ^www.example.com > use_backend www if www_acl > > default_backend www > > And I have a bunch of those selecting different backends. > > The base haproxy config is quite battle-tested, it has been running on my > staging environment with H2 for ~6 months. The production config is a > refinement (based off staging) that has been running for a few years in > production. > > But, when I enable H2 some small number of requests seem to be going to the > wrong backend. I see something like a bunch of requests for map tiles on > one connection, then that connection gets a request that should be going to > the main web server, it has a header of "www.example.com" instead of " > aerial1.example.com", the backend server logs that the Host header was " > www.example.com", but it is the aerial backend. > > This happens infrequently, and if I take the "alpn h2,http/1.1" off the > "bind" line it does not seem to happen. I have only small periods of time > when I've run it so I can't give an exhaustive list of user-agents, but I > definitely saw it happening with Chrome 70 on Windows 10, Chrome 71 on > Windows 7, Chrome 69 on Windows 10, Safari 12 on iOS 12.1, Chrome 68 on > Android... > > So, in summary: > > - Works fine without "alpn h2,http/1.1". > - Only some requests are mis-routed. > - It seems to be a keep-alive connection that opens to get map tiles, then > a few seconds or minutes later try to get something from the web server. > - The host header in the request seems to be correct, the backend is > logging it correct. > - The aerial tile and web servers have the same external IP address and are > routed based on the "Host" sent with the request.
Do you log the host header on haproxy ? I'm asking because in 1.8, H2 first translates the request to H1, then processes it and passes it to the server. Thus if the server sees the correct host, haproxy should as well. And if haproxy fails to see the correct host header when using H2, it should also fail to see it in H1. Oh, wait a minute, you're using SNI to route the request. This is incorrect, you must always use the Host header for this. SNI is only used to tell the server (haproxy in this case) what certificate to present. But for a given connection, the client can send different requests for various hosts, which are indicated in the Host header. One example I have in mind would be when the server presents a certificate with alt-names (or a wildcard certificate) indicating to the client that the connection is still authoritative for other names. In this case nothing prevents the client from reusing the same connection for various hosts compatible with this cert. So you must absolutely rely exclusively on the Host header for all HTTP routing. Regards, Willy

