Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions changelog/tls-1.3-ciphersuites.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
category: changed
title: Pass TLS 1.3 cipher suites to Envoy via proxy metadata
description: |
Allows passing TLS 1.3 cipher suites to envoy on OpenShift by passing
the env var `OPENSSL_TLS1_3_CIPHERSUITES` through proxy metadata. Syncs
this with the APIServer TLS settings.
31 changes: 25 additions & 6 deletions pkg/istiovalues/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,32 @@ func ApplyTLSConfig(tlsConfig *config.TLSConfig, istioVersion string, values *v1

// Configure the Ecdhcurves if they are available on Openshift configuration. Normalize before
// copying the names, given Openshift allows a different naming from NIST
if tlsConfig.OpenShift != nil && len(tlsConfig.OpenShift.TLSProfileSpec.Groups) > 0 {
ecdhCurves := copyECDHCurvesToConfig(tlsConfig.OpenShift.TLSProfileSpec.Groups)
if len(values.MeshConfig.TlsDefaults.EcdhCurves) == 0 {
values.MeshConfig.TlsDefaults.EcdhCurves = ecdhCurves
if tlsConfig.OpenShift != nil {
if len(tlsConfig.OpenShift.TLSProfileSpec.Groups) > 0 {
ecdhCurves := copyECDHCurvesToConfig(tlsConfig.OpenShift.TLSProfileSpec.Groups)
if len(values.MeshConfig.TlsDefaults.EcdhCurves) == 0 {
values.MeshConfig.TlsDefaults.EcdhCurves = ecdhCurves
}
// TODO: MeshMTLS does not support setting ecdhCurves and this will break Gateway provisioning.
// we should take care of ecdhCurves for mesh as a second step
}

// Envoy does not support setting TLS ciphers for TLS 1.3 BUT the openssl
// backend does allow you to customize these. On openshift the envoy image has a custom openssl
// config file baked in that will populate the tls1.3 cipher suites through an env var.
// Also important to note is that all non-FIPS approved ciphers will be silently dropped by
// openssl, even if they are specified in the openssl config. So we do not need to filter out
// FIPS ciphers here. We can pass them to the conf and openssl will drop them automatically on
// a FIPS enabled cluster.
if values.MeshConfig.DefaultConfig == nil {
values.MeshConfig.DefaultConfig = &v1.MeshConfigProxyConfig{}
}
if values.MeshConfig.DefaultConfig.ProxyMetadata == nil {
values.MeshConfig.DefaultConfig.ProxyMetadata = map[string]string{}
}
if _, ok := values.MeshConfig.DefaultConfig.ProxyMetadata["OPENSSL_TLS1_3_CIPHERSUITES"]; !ok {
values.MeshConfig.DefaultConfig.ProxyMetadata["OPENSSL_TLS1_3_CIPHERSUITES"] = strings.Join(cipherNames, ":")
}
// TODO: MeshMTLS does not support setting ecdhCurves and this will break Gateway provisioning.
// we should take care of ecdhCurves for mesh as a second step
}

if values.Pilot == nil {
Expand Down
161 changes: 161 additions & 0 deletions pkg/istiovalues/tls_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,134 @@ func TestApplyTLSConfig(t *testing.T) {
MinProtocolVersion: v1.MeshConfigTLSConfigTLSProtocolTlsv13,
EcdhCurves: []string{"X25519MLKEM768", "X25519", "P-256", "P-384"},
},
DefaultConfig: &v1.MeshConfigProxyConfig{
ProxyMetadata: map[string]string{
"OPENSSL_TLS1_3_CIPHERSUITES": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
},
},
},
Pilot: &v1.PilotConfig{
ExtraContainerArgs: []string{
"--tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"--tls-min-version=1.3",
},
},
},
},
{
name: "does not override existing OPENSSL_TLS1_3_CIPHERSUITES in proxyMetadata",
tlsConfig: &config.TLSConfig{
CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
MinVersion: tls.VersionTLS13,
OpenShift: &config.OpenShiftTLS{},
},
istioVersion: "1.30.0",
inputValues: &v1.Values{
MeshConfig: &v1.MeshConfig{
DefaultConfig: &v1.MeshConfigProxyConfig{
ProxyMetadata: map[string]string{
"OPENSSL_TLS1_3_CIPHERSUITES": "TLS_AES_256_GCM_SHA384",
},
},
},
},
wantValues: &v1.Values{
MeshConfig: &v1.MeshConfig{
MeshMTLS: &v1.MeshConfigTLSConfig{
CipherSuites: nil,
MinProtocolVersion: v1.MeshConfigTLSConfigTLSProtocolTlsv13,
},
TlsDefaults: &v1.MeshConfigTLSConfig{
CipherSuites: nil,
MinProtocolVersion: v1.MeshConfigTLSConfigTLSProtocolTlsv13,
},
DefaultConfig: &v1.MeshConfigProxyConfig{
ProxyMetadata: map[string]string{
"OPENSSL_TLS1_3_CIPHERSUITES": "TLS_AES_256_GCM_SHA384",
},
},
},
Pilot: &v1.PilotConfig{
ExtraContainerArgs: []string{
"--tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"--tls-min-version=1.3",
},
},
},
},
{
name: "preserves existing proxyMetadata keys when adding OPENSSL_TLS1_3_CIPHERSUITES",
tlsConfig: &config.TLSConfig{
CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
MinVersion: tls.VersionTLS13,
OpenShift: &config.OpenShiftTLS{},
},
istioVersion: "1.30.0",
inputValues: &v1.Values{
MeshConfig: &v1.MeshConfig{
DefaultConfig: &v1.MeshConfigProxyConfig{
ProxyMetadata: map[string]string{
"ISTIO_DUAL_STACK": "true",
},
},
},
},
wantValues: &v1.Values{
MeshConfig: &v1.MeshConfig{
MeshMTLS: &v1.MeshConfigTLSConfig{
CipherSuites: nil,
MinProtocolVersion: v1.MeshConfigTLSConfigTLSProtocolTlsv13,
},
TlsDefaults: &v1.MeshConfigTLSConfig{
CipherSuites: nil,
MinProtocolVersion: v1.MeshConfigTLSConfigTLSProtocolTlsv13,
},
DefaultConfig: &v1.MeshConfigProxyConfig{
ProxyMetadata: map[string]string{
"ISTIO_DUAL_STACK": "true",
"OPENSSL_TLS1_3_CIPHERSUITES": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
},
},
},
Pilot: &v1.PilotConfig{
ExtraContainerArgs: []string{
"--tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"--tls-min-version=1.3",
},
},
},
},
{
name: "preserves existing defaultConfig fields when adding proxyMetadata",
tlsConfig: &config.TLSConfig{
CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
MinVersion: tls.VersionTLS13,
OpenShift: &config.OpenShiftTLS{},
},
istioVersion: "1.30.0",
inputValues: &v1.Values{
MeshConfig: &v1.MeshConfig{
DefaultConfig: &v1.MeshConfigProxyConfig{
DiscoveryAddress: new("istiod.custom-ns.svc:15012"),
},
},
},
wantValues: &v1.Values{
MeshConfig: &v1.MeshConfig{
MeshMTLS: &v1.MeshConfigTLSConfig{
CipherSuites: nil,
MinProtocolVersion: v1.MeshConfigTLSConfigTLSProtocolTlsv13,
},
TlsDefaults: &v1.MeshConfigTLSConfig{
CipherSuites: nil,
MinProtocolVersion: v1.MeshConfigTLSConfigTLSProtocolTlsv13,
},
DefaultConfig: &v1.MeshConfigProxyConfig{
DiscoveryAddress: new("istiod.custom-ns.svc:15012"),
ProxyMetadata: map[string]string{
"OPENSSL_TLS1_3_CIPHERSUITES": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
},
},
},
Pilot: &v1.PilotConfig{
ExtraContainerArgs: []string{
Expand All @@ -298,6 +426,39 @@ func TestApplyTLSConfig(t *testing.T) {
},
},
},
{
name: "sets OPENSSL_TLS1_3_CIPHERSUITES on OpenShift even when MinVersion is not 1.3",
tlsConfig: &config.TLSConfig{
CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
MinVersion: tls.VersionTLS12,
OpenShift: &config.OpenShiftTLS{},
},
istioVersion: "1.30.0",
inputValues: &v1.Values{},
wantValues: &v1.Values{
MeshConfig: &v1.MeshConfig{
MeshMTLS: &v1.MeshConfigTLSConfig{
CipherSuites: []string{"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"},
MinProtocolVersion: v1.MeshConfigTLSConfigTLSProtocolTlsv12,
},
TlsDefaults: &v1.MeshConfigTLSConfig{
CipherSuites: []string{"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"},
MinProtocolVersion: v1.MeshConfigTLSConfigTLSProtocolTlsv12,
},
DefaultConfig: &v1.MeshConfigProxyConfig{
ProxyMetadata: map[string]string{
"OPENSSL_TLS1_3_CIPHERSUITES": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
},
},
},
Pilot: &v1.PilotConfig{
ExtraContainerArgs: []string{
"--tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"--tls-min-version=1.2",
},
},
},
},
}

for _, tt := range tests {
Expand Down
Loading
Loading