Open thomas-kaltenbach opened 3 years ago
My initial thoughts:
Given the discussion in golang/go#32763, it seems like it will be difficult to get RFC 8441 support for Gorouter any time soon (let me know if I'm missing something that would make it possible 🙂).
Based on that, it seems like the next best option would be to make HAProxy (and other clients) use HTTP/1.X for websockets requests. We already impose some Load Balancer configuration requirements for supporting websockets on CF: https://docs.cloudfoundry.org/adminguide/supporting-websockets.html#config.
Doing a little digging, I found https://github.com/haproxy/haproxy/commit/befeae88e8c7e2cbc19a63420bfa7d67ec176342, though I'm not sure how it impacts HAProxy's backend connections.
I applied haproxy/haproxy@befeae8 as a patch to the existing HAProxy release and configured h2-workaround-bogus-websocket-clients
. It did not seem to have any effect on HAProxy's communication with backends.
I was able to hack together a HAProxy config that appears to work for websockets:
Relevant excerpts:
# HTTPS Frontend {{{
frontend https-in
mode http
bind :443 ssl crt /var/vcap/jobs/haproxy/config/ssl alpn h2,http/1.1
http-request del-header X-Forwarded-Client-Cert
http-request del-header X-SSL-Client
http-request del-header X-SSL-Client-Session-ID
http-request del-header X-SSL-Client-Verify
http-request del-header X-SSL-Client-Subject-DN
http-request del-header X-SSL-Client-Subject-CN
http-request del-header X-SSL-Client-Issuer-DN
http-request del-header X-SSL-Client-NotBefore
http-request del-header X-SSL-Client-NotAfter
capture request header Host len 256
default_backend http-routers
acl xfp_exists hdr_cnt(X-Forwarded-Proto) gt 0
acl is_websocket hdr(Upgrade) -i WebSocket # Add is_websocket ACL looking for upgrade header
acl is_websocket hdr_beg(Host) -i ws # is_websocket ACL also looks for ws* scheme
use_backend http-routers-ws if is_websocket # If request matches ACL, route to http-routers-ws backend instead
http-request add-header X-Forwarded-Proto "https" if ! xfp_exists
# }}}
# Default Backend {{{
backend http-routers
mode http
balance roundrobin
errorfile 503 /var/vcap/jobs/haproxy/errorfiles/custom503.http
server node0 10.244.0.34:443 check inter 1000 ssl verify required ca-file /var/vcap/jobs/haproxy/config/backend-ca-certs.pem alpn h2,http/1.1
# }}}
backend http-routers-ws # New backend, identical to http-routers, except without alpn
mode http
balance roundrobin
errorfile 503 /var/vcap/jobs/haproxy/errorfiles/custom503.http
server node0 10.244.0.34:443 check inter 1000 ssl verify required ca-file /var/vcap/jobs/haproxy/config/backend-ca-certs.pem
@thomas-kaltenbach Given the changes introduced in cloudfoundry/haproxy-boshrelease#263, is there any remaining work for this issue?
Hi @Gerg, note that Thomas moved within our Org, taking over.
In https://github.com/cloudfoundry/haproxy-boshrelease/pull/263 we downgrade all websockets to h/1 even though h/2 is configured. Accordingly, this is still an issue and this workaround should not remain for ever. Seems to depend on https://github.com/golang/go/issues/32763.
Hi @plowin ,
Checking in on this issue. Is there any further work at this point or is it safe to close this out?
Hi @MarcPaquette , thx for re-assigning.
I prefer keeping it open in state blocked
. At some point in the far future, all traffic might be H/2 and we need support for it in gorouter. Keeping an eye on https://github.com/golang/go/issues/32763
Is this a security vulnerability?
no
Issue
Gorouter is not able to handle HTTP/2 Websockets requests (RFC 8441).
Affected Versions
latest version when http2 is enabled
Context
We are testing currently the http/2 feature and we noticed that websockets over http/2 are not working. Gorouter is closing the connection without any http response. After activating golang verbose logging (
GODEBUG=http2debug=2
) you can see the followed log entries:Traffic Diagram
Steps to Reproduce
I could also reproduce the issue with the followed nodejs client
Steps to run it:
npm install ws http2-wrapper
node <filename> https://<url_gorouter>
Expected result
One of the following behaviors would be acceptable:
Current result
HAproxy reporting the issue with the termination state
SH--
in the accesslog.nodejs client reports followed error:
Possible Fix
Root cause of the problem is the followed check: https://github.com/golang/go/blob/e180e2c27c3c3f06a4df6352386efedc15a1e38c/src/net/http/h2_bundle.go#L2770
I also found followed issue https://github.com/golang/go/issues/32763
I don't know if gorouter can workaround the problem or at least return a proper http response.