---
title: Configuring TLS security profiles
---

# Configuring TLS security profiles {#tls-security-profiles}

To enforce secure cryptographic libraries for the OpenShift Container Platform components, cluster administrators can configure TLS security profiles to control cipher usage when the client connects to the Ingress Controller, the control plane, or the kubelet.

The control plane includes the following components:

- Kubernetes API server
- Kubernetes controller manager
- Kubernetes scheduler
- OpenShift API server
- OpenShift OAuth API server
- OpenShift OAuth server
- etcd
- Machine Config Operator
- Machine Config Server.

## Understanding TLS security profiles {#tls-profiles-understanding_tls-security-profiles}

You can use a TLS (Transport Layer Security) security profile, as described in this section, to define which TLS ciphers are required by various OpenShift Container Platform components.

The OpenShift Container Platform TLS security profiles are based on [Mozilla recommended configurations](https://wiki.mozilla.org/Security/Server_Side_TLS).

You can specify one of the following TLS security profiles for each component:

**TLS security profiles**

<table>
<thead>
<tr>
  <th>Profile</th>
  <th>Description</th>
</tr>
</thead>
<tbody>
<tr>
  <td><code>Old</code></td>
  <td>This profile is intended for use with legacy clients or libraries. The profile is based on the <a href="https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility">Old backward compatibility</a> recommended configuration.<br><br>The <code>Old</code> profile requires a minimum TLS version of 1.0.<br><br><dl class="db-admonition db-admonition-note"><dt>Note</dt><dd>For the Ingress Controller, the minimum TLS version is converted from 1.0 to 1.1.</dd></dl></td>
</tr>
<tr>
  <td><code>Intermediate</code></td>
  <td>This profile is the default TLS security profile for the Ingress Controller, kubelet, and control plane. The profile is based on the <a href="https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29">Intermediate compatibility</a> recommended configuration.<br><br>The <code>Intermediate</code> profile requires a minimum TLS version of 1.2.<br><br><dl class="db-admonition db-admonition-note"><dt>Note</dt><dd>This profile is the recommended configuration for the majority of clients.</dd></dl></td>
</tr>
<tr>
  <td><code>Modern</code></td>
  <td>This profile is intended for use with modern clients that have no need for backwards compatibility. This profile is based on the <a href="https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility">Modern compatibility</a> recommended configuration.<br><br>The <code>Modern</code> profile requires a minimum TLS version of 1.3.</td>
</tr>
<tr>
  <td><code>Custom</code></td>
  <td>This profile allows you to define the TLS version and ciphers to use.<br><br><dl class="db-admonition db-admonition-warning"><dt>Warning</dt><dd>Use caution when using a <code>Custom</code> profile, because invalid configurations can cause problems.</dd></dl></td>
</tr>
</tbody>
</table>

> [!NOTE]
> When using one of the predefined profile types, the effective profile configuration is subject to change between releases. For example, given a specification to use the Intermediate profile deployed on release X.Y.Z, an upgrade to release X.Y.Z+1 might cause a new profile configuration to be applied, resulting in a rollout.

## Viewing TLS security profile details {#tls-profiles-view-details_tls-security-profiles}

To check the minimum TLS version and ciphers that a security profile applies in OpenShift Container Platform, you can inspect the profile configuration for the Ingress Controller, control plane, or kubelet. Use the `oc explain` command to display settings for a predefined or custom profile.

> [!IMPORTANT]
> The effective configuration of minimum TLS version and list of ciphers for a profile might differ between components.

**Procedure**

- View details for a specific TLS security profile:

  ```terminal
  $ oc explain <component>.spec.tlsSecurityProfile.<profile>
  ```
- For `<component>`, specify `ingresscontroller`, `apiserver`, or `kubeletconfig`. For `<profile>`, specify `old`, `intermediate`, or `custom`.

  For example, to check the ciphers included for the `intermediate` profile for the control plane:

  ```terminal
  $ oc explain apiserver.spec.tlsSecurityProfile.intermediate
  ```

  ```terminal {title="Example output"}
  KIND:     APIServer
  VERSION:  config.openshift.io/v1

  DESCRIPTION:
      intermediate is a TLS security profile based on:
      https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29
      and looks like this (yaml):
      ciphers: - TLS_AES_128_GCM_SHA256 - TLS_AES_256_GCM_SHA384 -
      TLS_CHACHA20_POLY1305_SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256 -
      ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384 -
      ECDHE-RSA-AES256-GCM-SHA384 - ECDHE-ECDSA-CHACHA20-POLY1305 -
      ECDHE-RSA-CHACHA20-POLY1305 - DHE-RSA-AES128-GCM-SHA256 -
      DHE-RSA-AES256-GCM-SHA384 minTLSVersion: TLSv1.2
  ```
- View all details for the `tlsSecurityProfile` field of a component:

  ```terminal
  $ oc explain <component>.spec.tlsSecurityProfile
  ```
- For `<component>`, specify `ingresscontroller`, `apiserver`, or `kubeletconfig`.

  For example, to check all details for the `tlsSecurityProfile` field for the Ingress Controller:

  ```terminal
  $ oc explain ingresscontroller.spec.tlsSecurityProfile
  ```

  ```terminal {title="Example output"}
  KIND:     IngressController
  VERSION:  operator.openshift.io/v1

  RESOURCE: tlsSecurityProfile <Object>

  DESCRIPTION:
       ...

  FIELDS:
     custom	<>
       custom is a user-defined TLS security profile. Be extremely careful using a
       custom profile as invalid configurations can be catastrophic. An example
       custom profile looks like this:
       ciphers: - ECDHE-ECDSA-CHACHA20-POLY1305 - ECDHE-RSA-CHACHA20-POLY1305 -
       ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES128-GCM-SHA256 minTLSVersion:
       TLSv1.1

     intermediate	<>
       intermediate is a TLS security profile based on:
       https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29
       and looks like this (yaml):
       (A list of ciphers and the minimum version for the intermediate profile opens here.)

     modern	<>
       modern is a TLS security profile based on:
       https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility and
       looks like this (yaml):
       (A list of ciphers and the minimum version for the modern profile opens here.)
       NOTE: Currently unsupported.

     old	<>
       old is a TLS security profile based on:
       https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility
       and looks like this (yaml):
       (A list of ciphers and the minimum version for the old profile opens here.)

     type	<string>
       ...
  ```

## Configuring the TLS security profile for the Ingress Controller {#tls-profiles-ingress-configuring_tls-security-profiles}

To configure a TLS security profile for an Ingress Controller, edit the `IngressController` custom resource (CR) to specify a predefined or custom TLS security profile.

If a TLS security profile is not configured, the default value is based on the TLS security profile set for the API server, as shown in the following example:

```yaml
apiVersion: operator.openshift.io/v1
kind: IngressController
 ...
spec:
  tlsSecurityProfile:
    old: {}
    type: Old
```

The TLS security profile defines the minimum TLS version and the TLS ciphers for TLS connections for Ingress Controllers.

You can see the ciphers and the minimum TLS version of the configured TLS security profile in the `IngressController` custom resource (CR) under `Status.Tls Profile` and the configured TLS security profile under `Spec.Tls Security Profile`. For the `Custom` TLS security profile, the specific ciphers and minimum TLS version are listed under both parameters.

> [!NOTE]
> The HAProxy Ingress Controller image supports TLS `1.3` and the `Modern` profile.
>
> The Ingress Operator also converts the TLS `1.0` of an `Old` or `Custom` profile to `1.1`.

**Prerequisites**

- You have access to the cluster as a user with the `cluster-admin` role.

**Procedure**

1. Edit the `IngressController` CR in the `openshift-ingress-operator` project to configure the TLS security profile:

   ```terminal
   $ oc edit IngressController default -n openshift-ingress-operator.
   ```
2. Add the `spec.tlsSecurityProfile` field:

   ```yaml {title="Sample IngressController CR for a Custom profile"}
   apiVersion: operator.openshift.io/v1
   kind: IngressController
    ...
   spec:
     tlsSecurityProfile:
       type: Custom
       custom:
         ciphers:
         - ECDHE-ECDSA-CHACHA20-POLY1305
         - ECDHE-RSA-CHACHA20-POLY1305
         - ECDHE-RSA-AES128-GCM-SHA256
         - ECDHE-ECDSA-AES128-GCM-SHA256
         minTLSVersion: VersionTLS11
    ...
   ```

   - Specify the value for the `spec.tlsSecurityProfile` parameter. The TLS security profile types are `Old`, `Intermediate`, or `Custom`. The default type is `Intermediate`.
   - Specify the appropriate field for the selected `spec.tlsSecurityProfile.type`. The fields are `old: {}`, `intermediate: {}`, `modern: {}`, or `custom:`.
   - For the `custom` type, specify a list of TLS ciphers and the minimum accepted TLS version.
3. Save the file to apply the changes.

**Verification**

- Verify that the profile is set in the `IngressController` CR:

  ```terminal
  $ oc describe IngressController default -n openshift-ingress-operator
  ```

  ```terminal {title="Example output"}
  Name:         default
  Namespace:    openshift-ingress-operator
  Labels:       <none>
  Annotations:  <none>
  API Version:  operator.openshift.io/v1
  Kind:         IngressController
   ...
  Spec:
   ...
    Tls Security Profile:
      Custom:
        Ciphers:
          ECDHE-ECDSA-CHACHA20-POLY1305
          ECDHE-RSA-CHACHA20-POLY1305
          ECDHE-RSA-AES128-GCM-SHA256
          ECDHE-ECDSA-AES128-GCM-SHA256
        Min TLS Version:  VersionTLS11
      Type:               Custom
   ...
  ```

## Configuring the TLS security profile for the control plane {#tls-profiles-kubernetes-configuring_tls-security-profiles}

To configure a TLS security profile for the control plane, edit the `APIServer` custom resource (CR) to specify a predefined or custom TLS security profile.

Setting the TLS security profile in the `APIServer` CR propagates the setting to the following control plane components:

- Kubernetes API server
- Kubernetes controller manager
- Kubernetes scheduler
- OpenShift API server
- OpenShift OAuth API server
- OpenShift OAuth server
- etcd
- Machine Config Operator
- Machine Config Server

> [!NOTE]
> The default TLS security profile for the Ingress Controller is based on the TLS security profile set for the API server.

If a TLS security profile is not configured, the default TLS security profile is `Intermediate`.

The following YAML is a sample `APIServer` CR that configures the `Old` TLS security profile.

```yaml
apiVersion: config.openshift.io/v1
kind: APIServer
 ...
spec:
  tlsSecurityProfile:
    old: {}
    type: Old
 ...
```

The TLS security profile defines the minimum TLS version and the TLS ciphers required to communicate with the control plane components.

You can see the configured TLS security profile in the `APIServer` custom resource (CR) under `Spec.Tls Security Profile`. For the `Custom` TLS security profile, the specific ciphers and minimum TLS version are listed.

**Prerequisites**

- You have access to the cluster as a user with the `cluster-admin` role.

**Procedure**

1. Edit the default `APIServer` CR to configure the TLS security profile:

   ```terminal
   $ oc edit APIServer cluster
   ```
2. Add the `spec.tlsSecurityProfile` field:

   ```yaml {title="Sample APIServer CR for a Custom profile"}
   apiVersion: config.openshift.io/v1
   kind: APIServer
   metadata:
     name: cluster
   spec:
     tlsSecurityProfile:
       type: Custom
       custom:
         ciphers:
         - ECDHE-ECDSA-CHACHA20-POLY1305
         - ECDHE-RSA-CHACHA20-POLY1305
         - ECDHE-RSA-AES128-GCM-SHA256
         - ECDHE-ECDSA-AES128-GCM-SHA256
         minTLSVersion: VersionTLS11
   ```

   - Specify the value for the `spec.tlsSecurityProfile.type` parameter. The TLS security profile types are `Old`, `Intermediate`, or `Custom`. The default type is `Intermediate`.
   - Specify the appropriate field for the selected `spec.tlsSecurityProfile`. The fields are `old: {}`, `intermediate: {}`, `modern: {}`, or `custom:`.
   - For the `custom` type, specify a list of TLS ciphers and the minimum accepted TLS version.
3. Save the file to apply the changes.

**Verification**

1. Verify that the TLS security profile is set in the `APIServer` CR:

   ```terminal
   $ oc describe apiserver cluster
   ```

   ```terminal {title="Example output"}
   Name:         cluster
   Namespace:
    ...
   API Version:  config.openshift.io/v1
   Kind:         APIServer
    ...
   Spec:
     Audit:
       Profile:  Default
     Tls Security Profile:
       Custom:
         Ciphers:
           ECDHE-ECDSA-CHACHA20-POLY1305
           ECDHE-RSA-CHACHA20-POLY1305
           ECDHE-RSA-AES128-GCM-SHA256
           ECDHE-ECDSA-AES128-GCM-SHA256
         Min TLS Version:  VersionTLS11
       Type:               Custom
    ...
   ```
2. Verify that the TLS security profile is set in the `etcd` CR:

   ```terminal
   $ oc describe etcd cluster
   ```

   ```terminal {title="Example output"}
   Name:         cluster
   Namespace:
    ...
   API Version:  operator.openshift.io/v1
   Kind:         Etcd
    ...
   Spec:
     Log Level:         Normal
     Management State:  Managed
     Observed Config:
       Serving Info:
         Cipher Suites:
           TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
           TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
           TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
           TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
           TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
           TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
         Min TLS Version:           VersionTLS12
    ...
   ```
3. Verify that the TLS security profile is set in the Machine Config Server pod:

   ```terminal
   $ oc logs machine-config-server-5msdv -n openshift-machine-config-operator
   ```

   ```terminal {title="Example output"}
   # ...
   I0905 13:48:36.968688       1 start.go:51] Launching server with tls min version: VersionTLS12 & cipher suites [TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256]
   # ...
   ```

## Configuring the TLS security profile for the kubelet {#tls-profiles-kubelet-configuring_tls-security-profiles}

To configure TLS ciphers and minimum versions for the kubelet HTTP server in OpenShift Container Platform, apply a predefined or custom TLS security profile through a `KubeletConfig` custom resource (CR). Without a custom profile, the kubelet defaults to the `Intermediate` profile.

- The kubelet uses its HTTP/GRPC server to communicate with the Kubernetes API server, which sends commands to pods, gathers logs, and run exec commands on pods through the kubelet.

```yaml {title="Sample KubeletConfig CR that configures the Old TLS security profile on worker nodes"}
apiVersion: machineconfiguration.openshift.io/v1
kind: KubeletConfig
# ...
spec:
  tlsSecurityProfile:
    old: {}
    type: Old
  machineConfigPoolSelector:
    matchLabels:
      pools.operator.machineconfiguration.openshift.io/worker: ""
# ...
```

You can see the ciphers and the minimum TLS version of the configured TLS security profile in the `kubelet.conf` file on a configured node.

**Prerequisites**

- You are logged in to OpenShift Container Platform as a user with the `cluster-admin` role.

**Procedure**

1. Create a `KubeletConfig` CR to configure the TLS security profile:

   ```yaml {title="Sample KubeletConfig CR for a Custom profile"}
   apiVersion: machineconfiguration.openshift.io/v1
   kind: KubeletConfig
   metadata:
     name: set-kubelet-tls-security-profile
   spec:
     tlsSecurityProfile:
       type: Custom
       custom:
         ciphers:
         - ECDHE-ECDSA-CHACHA20-POLY1305
         - ECDHE-RSA-CHACHA20-POLY1305
         - ECDHE-RSA-AES128-GCM-SHA256
         - ECDHE-ECDSA-AES128-GCM-SHA256
         minTLSVersion: VersionTLS11
     machineConfigPoolSelector:
       matchLabels:
         pools.operator.machineconfiguration.openshift.io/worker: ""
   #...
   ```

   where:

   `spec.tlsSecurityProfile.type`
   :   Specifies the TLS security profile type (`Old`, `Intermediate`, or `Custom`). The default is `Intermediate`.

   `spec.tlsSecurityProfile.type.custom`
   :   Specifies the appropriate field for the selected type: \*   `old: {}` \*   `intermediate: {}` \*   `modern: {}` \*   `custom:`

   `spec.tlsSecurityProfile.type.custom`
   :   For the `custom` type, specifies a list of TLS ciphers and the minimum accepted TLS version.

   `spec.machineConfigPoolSelector.matchLabels.custom`
   :   Specifies the machine config pool label for the nodes you want to apply the TLS security profile. This parameter is optional.
2. Create the `KubeletConfig` object:

   ```terminal
   $ oc create -f <filename>
   ```

   Depending on the number of worker nodes in the cluster, wait for the configured nodes to be rebooted one by one.

**Verification**

To verify that the profile is set,  perform the following steps after the nodes are in the `Ready` state:

1. Start a debug session for a configured node:

   ```terminal
   $ oc debug node/<node_name>
   ```
2. Set `/host` as the root directory within the debug shell:

   ```terminal
   sh-4.4# chroot /host
   ```
3. View the `kubelet.conf` file:

   ```terminal
   sh-4.4# cat /etc/kubernetes/kubelet.conf
   ```

   ```terminal {title="Example output"}
     "kind": "KubeletConfiguration",
     "apiVersion": "kubelet.config.k8s.io/v1beta1",
   #...
     "tlsCipherSuites": [
       "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
       "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
       "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
       "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
       "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
       "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
     ],
     "tlsMinVersion": "VersionTLS12",
   #...
   ```
