diff --git a/images/router/haproxy/conf/haproxy-config.template b/images/router/haproxy/conf/haproxy-config.template index 0a41ca030..2cdecb2a1 100644 --- a/images/router/haproxy/conf/haproxy-config.template +++ b/images/router/haproxy/conf/haproxy-config.template @@ -8,6 +8,7 @@ {{- $defaultDestinationCA := .DefaultDestinationCA }} {{- $dynamicConfigManager := .DynamicConfigManager }} {{- $router_ip_v4_v6_mode := env "ROUTER_IP_V4_V6_MODE" "v4" }} +{{- $router_disable_http2 := env "ROUTER_DISABLE_HTTP2" "false" }} {{- /* A bunch of regular expressions. Each should be wrapped in (?:) so that it is safe to include bare */}} @@ -456,7 +457,9 @@ backend {{genBackendNamePrefix $cfg.TLSTermination}}:{{$cfgIdx}} {{- with $serviceUnit := index $.ServiceUnits $serviceUnitName }} {{- range $idx, $endpoint := processEndpointsForAlias $cfg $serviceUnit (env "ROUTER_BACKEND_PROCESS_ENDPOINTS" "") }} server {{$endpoint.ID}} {{$endpoint.IP}}:{{$endpoint.Port}} cookie {{$endpoint.IdHash}} weight {{$weight}} - {{- if (eq $cfg.TLSTermination "reencrypt") }} alpn h2,http/1.1 ssl + {{- if (eq $cfg.TLSTermination "reencrypt") }} ssl + {{- if not (isTrue $router_disable_http2) }} alpn h2,http/1.1 + {{- end }} {{- if $cfg.VerifyServiceHostname }} verifyhost {{ $serviceUnit.Hostname }} {{- end }} {{- if gt (len (index $cfg.Certificates (printf "%s_pod" $cfg.Host)).Contents) 0 }} verify required ca-file {{ $workingDir }}/router/cacerts/{{$cfgIdx}}.pem diff --git a/pkg/router/template/router.go b/pkg/router/template/router.go index a74decf62..0ccd22fd1 100644 --- a/pkg/router/template/router.go +++ b/pkg/router/template/router.go @@ -10,6 +10,7 @@ import ( "os/exec" "path/filepath" "reflect" + "strconv" "strings" "sync" "text/template" @@ -151,6 +152,8 @@ type templateData struct { BindPorts bool // The dynamic configuration manager if "configured". DynamicConfigManager ConfigManager + // DisableHTTP2 on the frontend and the backend when set "true" + DisableHTTP2 bool } func newTemplateRouter(cfg templateRouterCfg) (*templateRouter, error) { @@ -468,6 +471,8 @@ func (r *templateRouter) writeConfig() error { log.V(4).Info("router certificate manager config committed") + disableHTTP2, _ := strconv.ParseBool(os.Getenv("ROUTER_DISABLE_HTTP2")) + for name, template := range r.templates { filename := filepath.Join(r.dir, name) file, err := os.Create(filename) @@ -486,6 +491,7 @@ func (r *templateRouter) writeConfig() error { StatsPort: r.statsPort, BindPorts: !r.bindPortsAfterSync || r.synced, DynamicConfigManager: r.dynamicConfigManager, + DisableHTTP2: disableHTTP2, } if err := template.Execute(file, data); err != nil { file.Close() diff --git a/pkg/router/template/template_helper.go b/pkg/router/template/template_helper.go index 64e62474b..5ebc3f79b 100644 --- a/pkg/router/template/template_helper.go +++ b/pkg/router/template/template_helper.go @@ -175,7 +175,11 @@ func generateHAProxyCertConfigMap(td templateData) []string { backendConfig := backendConfig(string(k), cfg, hascert) if entry := haproxyutil.GenerateMapEntry(certConfigMap, backendConfig); entry != nil { fqCertPath := path.Join(td.WorkingDir, certDir, entry.Key) - lines = append(lines, strings.Join([]string{fqCertPath, entry.SSLBindConfig, entry.Value}, " ")) + if td.DisableHTTP2 { + lines = append(lines, strings.Join([]string{fqCertPath, entry.Value}, " ")) + } else { + lines = append(lines, strings.Join([]string{fqCertPath, entry.SSLBindConfig, entry.Value}, " ")) + } } } diff --git a/pkg/router/template/template_helper_test.go b/pkg/router/template/template_helper_test.go index 31b61e409..5c4635e37 100644 --- a/pkg/router/template/template_helper_test.go +++ b/pkg/router/template/template_helper_test.go @@ -525,9 +525,30 @@ func TestGenerateHAProxyMap(t *testing.T) { "/path/to/router/certs/dev:admin-route.pem", } - lines = generateHAProxyMap("cert_config.map", td) - if err := checkExpectedOrderPrefixes(lines, certBackendOrder); err != nil { - t.Errorf("TestGenerateHAProxyMap cert_config.map error: %v", err) + for _, tc := range []struct { + DisableHTTP2 bool + ExpectedSSLBinding string + }{ + { + DisableHTTP2: true, + }, + { + DisableHTTP2: false, + ExpectedSSLBinding: "[alpn h2,http/1.1]", + }, + } { + td.DisableHTTP2 = tc.DisableHTTP2 + lines := generateHAProxyMap("cert_config.map", td) + if err := checkExpectedOrderPrefixes(lines, certBackendOrder); err != nil { + t.Errorf("TestGenerateHAProxyMap cert_config.map error: %v", err) + } + if tc.ExpectedSSLBinding != "" { + for _, line := range lines { + if !strings.Contains(line, tc.ExpectedSSLBinding) { + t.Errorf("line %q does not contain expected SSL binding %q", line, tc.ExpectedSSLBinding) + } + } + } } }