From c379fcfba2f2c21841fba569f5793534cc4e329a Mon Sep 17 00:00:00 2001 From: Helene Durand Date: Fri, 25 Oct 2024 12:15:54 +0200 Subject: [PATCH] MEDIUM: use unix socket when mixing ssl passthrough and offloading --- .aspell.yml | 3 ++ pkg/controller/builder.go | 9 ++-- pkg/controller/constants/const.go | 9 +++- pkg/handler/https.go | 78 +++++++++++++++++++------------ 4 files changed, 64 insertions(+), 35 deletions(-) diff --git a/.aspell.yml b/.aspell.yml index 0571a787..d5184030 100644 --- a/.aspell.yml +++ b/.aspell.yml @@ -28,3 +28,6 @@ allowed: - linters - tls - lifecycle + - passthrough + - ssl + - unix diff --git a/pkg/controller/builder.go b/pkg/controller/builder.go index ccd55e7e..30dda516 100644 --- a/pkg/controller/builder.go +++ b/pkg/controller/builder.go @@ -28,6 +28,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "github.com/haproxytech/kubernetes-ingress/pkg/annotations" + "github.com/haproxytech/kubernetes-ingress/pkg/controller/constants" gateway "github.com/haproxytech/kubernetes-ingress/pkg/gateways" "github.com/haproxytech/kubernetes-ingress/pkg/handler" "github.com/haproxytech/kubernetes-ingress/pkg/haproxy" @@ -67,10 +68,10 @@ var defaultEnv = env.Env{ RuntimeDir: "/var/run", StateDir: "/var/state/haproxy/", Proxies: env.Proxies{ - FrontHTTP: "http", - FrontHTTPS: "https", - FrontSSL: "ssl", - BackSSL: "ssl", + FrontHTTP: constants.HTTP_FRONTEND, + FrontHTTPS: constants.HTTPS_FRONTEND, + FrontSSL: constants.SSL_FRONTEND, + BackSSL: constants.SSL_BACKEND, }, } diff --git a/pkg/controller/constants/const.go b/pkg/controller/constants/const.go index c9ec8ace..a12234c3 100644 --- a/pkg/controller/constants/const.go +++ b/pkg/controller/constants/const.go @@ -14,4 +14,11 @@ package constants -const DefaultsSectionName = "haproxytech" +//nolint:golint, stylecheck +const ( + DefaultsSectionName = "haproxytech" + SSL_FRONTEND = "ssl" + SSL_BACKEND = "ssl" + HTTP_FRONTEND = "http" + HTTPS_FRONTEND = "https" +) diff --git a/pkg/handler/https.go b/pkg/handler/https.go index 913b6341..574c43f6 100644 --- a/pkg/handler/https.go +++ b/pkg/handler/https.go @@ -17,6 +17,7 @@ package handler import ( "errors" "fmt" + "path" "github.com/haproxytech/client-native/v5/models" @@ -45,42 +46,31 @@ type HTTPS struct { } //nolint:golint, stylecheck -const HTTPS_PORT_SSLPASSTHROUGH int64 = 8444 +const ( + HTTPS_PORT_SSLPASSTHROUGH int64 = 8444 + BIND_UNIX_SOCKET = "unixsock" + BIND_IP_V4 = "v4" + BIND_IP_V6 = "v6" +) -func (handler HTTPS) bindList(passhthrough bool) (binds []models.Bind) { +func (handler HTTPS) bindList(h haproxy.HAProxy) (binds []models.Bind) { if handler.IPv4 { binds = append(binds, models.Bind{ Address: handler.AddrIPv4, - Port: func() *int64 { - if passhthrough { - return utils.PtrInt64(HTTPS_PORT_SSLPASSTHROUGH) - } - return utils.PtrInt64(handler.Port) - }(), + Port: utils.PtrInt64(handler.Port), BindParams: models.BindParams{ - Name: "v4", - AcceptProxy: passhthrough, + Name: BIND_IP_V4, + AcceptProxy: false, }, }) } if handler.IPv6 { binds = append(binds, models.Bind{ - Address: func() (addr string) { - addr = handler.AddrIPv6 - if passhthrough { - addr = "::" - } - return - }(), - Port: func() *int64 { - if passhthrough { - return utils.PtrInt64(HTTPS_PORT_SSLPASSTHROUGH) - } - return utils.PtrInt64(handler.Port) - }(), + Address: handler.AddrIPv6, + Port: utils.PtrInt64(handler.Port), BindParams: models.BindParams{ - AcceptProxy: passhthrough, - Name: "v6", + AcceptProxy: false, + Name: BIND_IP_V6, V4v6: true, }, }) @@ -88,6 +78,21 @@ func (handler HTTPS) bindList(passhthrough bool) (binds []models.Bind) { return binds } +func (handler HTTPS) bindListPassthrough(h haproxy.HAProxy) (binds []models.Bind) { + binds = append(binds, models.Bind{ + Address: "unix@" + handler.unixSocketPath(h), + BindParams: models.BindParams{ + Name: BIND_UNIX_SOCKET, + AcceptProxy: true, + }, + }) + return binds +} + +func (handler HTTPS) unixSocketPath(h haproxy.HAProxy) string { + return path.Join(h.Env.RuntimeDir, "ssl-frontend.sock") +} + func (handler HTTPS) handleClientTLSAuth(k store.K8s, h haproxy.HAProxy) (err error) { // Parsing var caFile string @@ -211,7 +216,7 @@ func (handler HTTPS) enableSSLPassthrough(h haproxy.HAProxy) (err error) { if err != nil { return err } - for _, b := range handler.bindList(false) { + for _, b := range handler.bindList(h) { if err = h.FrontendBindCreate(h.FrontSSL, b); err != nil { return fmt.Errorf("cannot create bind for SSL Passthrough: %w", err) } @@ -226,8 +231,7 @@ func (handler HTTPS) enableSSLPassthrough(h haproxy.HAProxy) (err error) { }), h.BackendServerCreate(h.BackSSL, models.Server{ Name: h.FrontHTTPS, - Address: "127.0.0.1", - Port: utils.PtrInt64(HTTPS_PORT_SSLPASSTHROUGH), + Address: "unix@" + handler.unixSocketPath(h), ServerParams: models.ServerParams{SendProxyV2: "enabled"}, }), h.BackendSwitchingRuleCreate(h.FrontSSL, models.BackendSwitchingRule{ @@ -255,8 +259,13 @@ func (handler HTTPS) disableSSLPassthrough(h haproxy.HAProxy) (err error) { } func (handler HTTPS) toggleSSLPassthrough(passthrough bool, h haproxy.HAProxy) (err error) { - for _, bind := range handler.bindList(passthrough) { - if err = h.FrontendBindEdit(h.FrontHTTPS, bind); err != nil { + handler.deleteHTTPSFrontendBinds(h) + bindListFunc := handler.bindList + if passthrough { + bindListFunc = handler.bindListPassthrough + } + for _, bind := range bindListFunc(h) { + if err = h.FrontendBindCreate(h.FrontHTTPS, bind); err != nil { return err } } @@ -266,6 +275,15 @@ func (handler HTTPS) toggleSSLPassthrough(passthrough bool, h haproxy.HAProxy) ( return nil } +func (handler HTTPS) deleteHTTPSFrontendBinds(h haproxy.HAProxy) { + bindsToDelete := []string{BIND_IP_V4, BIND_IP_V6, BIND_UNIX_SOCKET} + for _, bind := range bindsToDelete { + if err := h.FrontendBindDelete(h.FrontHTTPS, bind); err != nil { + logger.Tracef("cannot delete bind %s: %s", bind, err) + } + } +} + func (handler HTTPS) sslPassthroughRules(k store.K8s, h haproxy.HAProxy, a annotations.Annotations) error { inspectTimeout, err := a.Timeout("timeout-client", k.ConfigMaps.Main.Annotations) if inspectTimeout == nil {