Skip to main content
logoTetrate Istio SubscriptionVersion: Next

Configure TID in Strict FIPS Mode

This document describes how to configure the FIPS version of Tetrate Istio Distribution (TID) to operate in a strict FIPS-compliant mode. To be strictly FIPS compliant, it is a requirement to only support TLS 1.2 connections inside and outside the mesh. This is because FIPS TID uses Google’s BoringCrypto project to perform its cryptographic functions, and the Security Policy only covers TLS 1.2.

warning

Restricting TLS configuration may cause other applications to experience connection issues. Always validate that clients who need to communicate with your applications and gateways can support TLS 1.2 connections before proceeding.

Using COMPLIANCE_POLICY

Istio 1.21 introduces a new environment variable called COMPLIANCE_POLICY to Istio components for enforcing TLS restriction for compliance with FIPS. This change has been backported to Istio 1.20.x and 1.19.x releases, available from the 1.20.4 and 1.19.8 releases respectively.

When COMPLIANCE_POLICY is set to fips-140-2 on the Istiod container, the Istio Proxy container, and all other Istio components, TLS version is restricted to v1.2, the cipher suites to a subset of ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-RSA-AES128-GCM-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-RSA-AES256-GCM-SHA384, and ECDH curves to P-256. Please refer to the Istio 1.21 release notes for more details.

Using EnvoyFilter

To exclude TLS 1.3 for Istio versions lacking COMPLIANCE_POLICY support, it is necessary to use an EnvoyFilter to provide fine-grained control over TLS settings. The following sections describe how to configure the internal mTLS and the Gateway TLS to only support TLS 1.2.

Configuring Internal mTLS

Here is an example filter that you can use to configure the internal mTLS to only support TLS 1.2:

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: tls-v1-2-only
# Root namespace: https://istio.io/latest/docs/reference/config/istio.mesh.v1alpha1/#MeshConfig-root_namespace.
namespace: <MESH-CONFIG-ROOT-NAMESPACE>
spec:
configPatches:
- applyTo: CLUSTER
match:
context: ANY
patch:
operation: MERGE
value:
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
common_tls_context:
tls_params:
tls_maximum_protocol_version: TLSv1_2
tls_minimum_protocol_version: TLSv1_2
cipher_suites:
- ECDHE-ECDSA-AES128-GCM-SHA256
- ECDHE-RSA-AES128-GCM-SHA256
- ECDHE-ECDSA-AES256-GCM-SHA384
- ECDHE-RSA-AES256-GCM-SHA384

- applyTo: FILTER_CHAIN
match:
context: ANY
patch:
operation: MERGE
value:
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_params:
tls_maximum_protocol_version: TLSv1_2
tls_minimum_protocol_version: TLSv1_2
cipher_suites:
- ECDHE-ECDSA-AES128-GCM-SHA256
- ECDHE-RSA-AES128-GCM-SHA256
- ECDHE-ECDSA-AES256-GCM-SHA384
- ECDHE-RSA-AES256-GCM-SHA384

Validation

To validate the config you can connect to a workload by using OpenSSL CLI within the cluster.

Deploy an image that contains the OpenSSL CLI (for example, nginx)

kubectl create deployment checker --image=nginx

Try to connect to a workload from within the pod:

kubectl exec -ti <POD-NAME> -- openssl s_client -connect <WORKLOAD-IP:PORT> -tls1_3

When the configuration above is in effect, the connection will fail

CONNECTED(00000003)
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 225 bytes

When the configuration above is somewhat failed to be applied, the connection succeeds

New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384

Configuring Gateway TLS

You can configure Istio Gateways to accept only TLS 1.2 with the following configuration:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: my-istio-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "*"
tls:
mode: SIMPLE # Or PASSTHROUGH
credentialName: <CREDENTIAL-NAME> # for SIMPLE
minProtocolVersion: TLSV1_2
maxProtocolVersion: TLSV1_2
cipherSuites:
- ECDHE-ECDSA-AES128-GCM-SHA256
- ECDHE-RSA-AES128-GCM-SHA256
- ECDHE-ECDSA-AES256-GCM-SHA384
- ECDHE-RSA-AES256-GCM-SHA384

Validation

You can use OpenSSL CLI to validate the gateway, similar to the way we validate the internal mTLS:

Try to connect to a gateway:

openssl s_client -connect <GATEWAY-IP:PORT> -tls1_3

When the configuration above is in effect, the connection will fail

CONNECTED(00000003)
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 225 bytes

When the configuration above is somewhat failed to be applied, the connection succeeds

New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384