From 60cf2ba0ad3d07f00ababe510dd962beabd115be Mon Sep 17 00:00:00 2001 From: Evgeny Slutsky Date: Mon, 4 May 2026 16:44:25 +0200 Subject: [PATCH 1/3] NO-ISSUE: Add FIPS detection for ingress controller Introduce detectFIPS() to check whether the cluster is running in FIPS mode via the FIPS_ENABLED env var or /proc/sys/crypto/fips_enabled. The result is stored in the package-level isFIPSEnabled variable for use by subsequent FIPS-aware configuration logic. Co-Authored-By: Claude Opus 4.6 --- pkg/components/controllers.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/pkg/components/controllers.go b/pkg/components/controllers.go index e9bdf7af50..208774c83a 100644 --- a/pkg/components/controllers.go +++ b/pkg/components/controllers.go @@ -27,6 +27,9 @@ const ( haproxyMaxTimeoutMilliseconds = 2147483647 * time.Millisecond ) +// isFIPSEnabled reports whether the cluster has FIPS enabled. +var isFIPSEnabled = detectFIPS() + var ( tlsVersion13Ciphers = sets.NewString( "TLS_AES_128_GCM_SHA256", @@ -37,6 +40,34 @@ var ( ) ) +// detectFIPS reports whether the cluster is operating in FIPS +// mode by checking the FIPS_ENABLED environment variable if set or +// the /proc/sys/crypto/fips_enabled file otherwise. +func detectFIPS() bool { + if v, ok := os.LookupEnv("FIPS_ENABLED"); ok { + if result, err := strconv.ParseBool(v); err != nil { + klog.Warningf("Failed to parse FIPS_ENABLED environment variable: %v; falling back to procfs", err) + } else { + klog.Infof("Found FIPS_ENABLED environment variable: value=%s, result=%v", v, result) + return result + } + } + + result := false + data, err := os.ReadFile("/proc/sys/crypto/fips_enabled") + if err != nil { + klog.Warningf("Failed to read /proc/sys/crypto/fips_enabled: %v; assuming FIPS is not enabled", err) + return result + } + if len(data) == 0 { + klog.Warningf("Got empty /proc/sys/crypto/fips_enabled; assuming FIPS is not enabled") + return result + } + result = data[0] == '1' + klog.Infof("Read /proc/sys/crypto/fips_enabled: data=%s, result=%v", string(data), result) + return result +} + func startServiceCAController(ctx context.Context, cfg *config.Config, kubeconfigPath string) error { var ( //TODO: fix the rolebinding and sa From d65e6234ec38debcf1886c231da6ece17e7287f4 Mon Sep 17 00:00:00 2001 From: Evgeny Slutsky Date: Mon, 4 May 2026 16:44:58 +0200 Subject: [PATCH 2/3] NO-ISSUE: Filter non-FIPS TLS 1.3 ciphers in ingress router On FIPS-enabled clusters, remove non-FIPS-compliant TLS 1.3 cipher suites (e.g. TLS_CHACHA20_POLY1305_SHA256) from ROUTER_CIPHERSUITES. HAProxy would fail TLS handshakes when a client offers a non-FIPS cipher that is listed in ssl-default-bind-ciphersuites but excluded by the OS FIPS policy. Co-Authored-By: Claude Opus 4.6 --- pkg/components/controllers.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pkg/components/controllers.go b/pkg/components/controllers.go index 208774c83a..dccd784adc 100644 --- a/pkg/components/controllers.go +++ b/pkg/components/controllers.go @@ -38,6 +38,11 @@ var ( "TLS_AES_128_CCM_SHA256", "TLS_AES_128_CCM_8_SHA256", ) + + fipsApprovedTLS13Ciphers = sets.NewString( + "TLS_AES_128_GCM_SHA256", + "TLS_AES_256_GCM_SHA384", + ) ) // detectFIPS reports whether the cluster is operating in FIPS @@ -503,6 +508,20 @@ func generateIngressParams(cfg *config.Config) (assets.RenderParams, error) { } } + // On FIPS-enabled clusters, remove non-FIPS-compliant TLS 1.3 cipher + // suites (e.g. TLS_CHACHA20_POLY1305_SHA256). HAProxy would fail TLS + // handshakes when a client offers a non-FIPS cipher first if that cipher + // is listed in ssl-default-bind-ciphersuites but excluded by the OS FIPS policy. + if isFIPSEnabled { + fipsCiphers := tls13Ciphers[:0] + for _, c := range tls13Ciphers { + if fipsApprovedTLS13Ciphers.Has(c) { + fipsCiphers = append(fipsCiphers, c) + } + } + tls13Ciphers = fipsCiphers + } + RouterCiphers := strings.Join(otherCiphers, ":") RouterCiphersSuites := "" if len(tls13Ciphers) != 0 { From 08527714cd7da329856b60e5b391469a6c681a42 Mon Sep 17 00:00:00 2001 From: Evgeny Slutsky Date: Mon, 4 May 2026 16:45:20 +0200 Subject: [PATCH 3/3] NO-ISSUE: Configure TLS curves based on FIPS mode for PQC readiness Set ROUTER_CURVES on the ingress router deployment to configure TLS supportedGroups. Non-FIPS clusters use X25519MLKEM768:X25519:P-256:P-384:P-521 (including post-quantum ML-KEM). FIPS clusters use P-256:P-384:P-521 only, since ML-KEM and X25519 are not supported by OpenSSL FIPS 140-3. Co-Authored-By: Claude Opus 4.6 --- assets/components/openshift-router/deployment.yaml | 2 ++ pkg/components/controllers.go | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/assets/components/openshift-router/deployment.yaml b/assets/components/openshift-router/deployment.yaml index af1f48f67f..cb2c7b5f31 100644 --- a/assets/components/openshift-router/deployment.yaml +++ b/assets/components/openshift-router/deployment.yaml @@ -58,6 +58,8 @@ spec: value: '{{ .ThreadCount }}' - name: SSL_MIN_VERSION value: '{{ .RouterSSLMinVersion }}' + - name: ROUTER_CURVES + value: '{{ .RouterTLSCurves }}' - name: ROUTER_USE_PROXY_PROTOCOL value: "false" - name: GRACEFUL_SHUTDOWN_DELAY diff --git a/pkg/components/controllers.go b/pkg/components/controllers.go index dccd784adc..290b7a16b2 100644 --- a/pkg/components/controllers.go +++ b/pkg/components/controllers.go @@ -528,6 +528,14 @@ func generateIngressParams(cfg *config.Config) (assets.RenderParams, error) { RouterCiphersSuites = strings.Join(tls13Ciphers, ":") } + // Default TLS supportedGroups (curves) include X25519MLKEM768 for + // post-quantum readiness. In FIPS mode, ML-KEM and X25519 are not + // supported by OpenSSL FIPS 140-3. + tlsCurves := "X25519MLKEM768:X25519:P-256:P-384:P-521" + if isFIPSEnabled { + tlsCurves = "P-256:P-384:P-521" + } + var RouterSSLMinVersion string switch tlsProfileSpec.MinTLSVersion { // TLS 1.0 is not supported, convert to TLS 1.1. @@ -619,6 +627,7 @@ func generateIngressParams(cfg *config.Config) (assets.RenderParams, error) { "RouterCiphers": RouterCiphers, "RouterCiphersSuites": RouterCiphersSuites, "RouterSSLMinVersion": RouterSSLMinVersion, + "RouterTLSCurves": tlsCurves, "RouterAllowWildcardRoutes": RouterAllowWildcardRoutes, "ClientCAMapName": clientCAMapName, "ClientAuthPolicy": clientAuthPolicy,