> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ensure API Server Only Uses Strong Cryptographic Ciphers

### More Info:

Ensure that the API server is configured to only use strong cryptographic ciphers.

### Risk Level

Medium

### Address

Security

### Compliance Standards

* CIS Kubernetes

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. On every control plane node, back up the API server manifest before editing:
           ```bash theme={null}
           sudo cp -a /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml.bak
           ```

        2. Edit the manifest on every control plane node:
           ```bash theme={null}
           sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
           ```
           Locate the `command:` or `- kube-apiserver` args list and either add or replace the existing `--tls-cipher-suites` argument with a single, comma-separated value line like this (each item exactly as shown, no spaces):
           ```yaml theme={null}
           - --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
           ```

        3. Save the file and exit the editor. The kubelet will automatically detect the manifest change and restart the kube-apiserver static pod; expect a brief control-plane disruption while it restarts.

        4. Wait for the kube-apiserver pod to become Ready again (on any machine with `kubectl` access):
           ```bash theme={null}
           kubectl get pods -n kube-system -l component=kube-apiserver -o wide
           ```

        5. On every control plane node, verify the running process has the correct cipher suites configured:
           ```bash theme={null}
           /bin/ps -ef | grep kube-apiserver | grep -v grep | grep -- '--tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256'
           ```
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot modify the kube-apiserver static pod manifest or its process flags, so this finding cannot be remediated through the Kubernetes API. To fix it, you must edit `/etc/kubernetes/manifests/kube-apiserver.yaml` directly on every control plane node as described in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Harden kube-apiserver TLS cipher suites on all control plane nodes.
        #
        # USAGE:
        #   1) Put this script on each control plane node.
        #   2) Run as root:  ./harden-apiserver-ciphers.sh
        #
        # This edits /etc/kubernetes/manifests/kube-apiserver.yaml.
        # Changing this file will cause the kube-apiserver static pod to restart.

        set -euo pipefail

        APISERVER_MANIFEST="/etc/kubernetes/manifests/kube-apiserver.yaml"

        REQUIRED_CIPHERS="TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"

        backup_manifest() {
          local src="$1"
          local ts
          ts="$(date +%Y%m%d-%H%M%S)"
          cp -p "$src" "${src}.bak-${ts}"
          echo "Backup created: ${src}.bak-${ts}"
        }

        ensure_manifest_exists() {
          if [ ! -f "$APISERVER_MANIFEST" ]; then
            echo "ERROR: $APISERVER_MANIFEST not found on this node. Run this only on control plane nodes."
            exit 1
          fi
        }

        configure_tls_cipher_suites() {
          local file="$APISERVER_MANIFEST"

          # If flag already present with the required value, do nothing (idempotent).
          if grep -q -- "--tls-cipher-suites=${REQUIRED_CIPHERS}" "$file"; then
            echo "Flag --tls-cipher-suites already set to required value; no changes needed."
            return 0
          fi

          backup_manifest "$file"

          if grep -q -- "--tls-cipher-suites=" "$file"; then
            # Replace any existing tls-cipher-suites line with the required value.
            sed -i 's#^\(\s*-\s*--tls-cipher-suites=\).*#\1'"${REQUIRED_CIPHERS}"'#' "$file"
            echo "Updated existing --tls-cipher-suites flag."
          else
            # Insert the flag under the kube-apiserver command list.
            # This assumes a typical kubeadm-style manifest with a 'command:' list.
            # Append as a new '- --tls-cipher-suites=...' line after the last existing flag line.
            # Safer approach: add near other --tls-* options if present.
            if grep -q "command:" "$file"; then
              # Add the flag after the 'command:' block start.
              awk -v ciphers="$REQUIRED_CIPHERS" '
                /command:/ && in_cmd==0 {
                  print $0
                  in_cmd=1
                  next
                }
                in_cmd==1 && $1 ~ /^-/ {
                  print $0
                  last_flag_line=NR
                  next
                }
                in_cmd==1 && $1 !~ /^-/ {
                  if (inserted==0) {
                    print "    - --tls-cipher-suites=" ciphers
                    inserted=1
                  }
                  in_cmd=0
                  print $0
                  next
                }
                {
                  print $0
                }
                END {
                  if (in_cmd==1 && inserted==0) {
                    print "    - --tls-cipher-suites=" ciphers
                  }
                }
              ' "$file" > "${file}.tmp"
              mv "${file}.tmp" "$file"
              echo "Inserted new --tls-cipher-suites flag under command section."
            else
              echo "ERROR: Could not locate 'command:' section in $file to insert --tls-cipher-suites flag."
              echo "Please edit the manifest manually to add:"
              echo "  - --tls-cipher-suites=${REQUIRED_CIPHERS}"
              exit 1
            fi
          fi

          echo "NOTE: kubelet will automatically restart the kube-apiserver static pod due to manifest change."
        }

        verify_apiserver_process() {
          echo "Waiting for kube-apiserver to restart with new flags (up to 120 seconds)..."

          # Wait loop for process containing the desired flag.
          for i in $(seq 1 24); do
            if /bin/ps -ef | grep kube-apiserver | grep -v grep | grep -q -- "--tls-cipher-suites=${REQUIRED_CIPHERS}"; then
              echo "Verification succeeded: kube-apiserver is running with the required --tls-cipher-suites flag."
              /bin/ps -ef | grep kube-apiserver | grep -v grep
              return 0
            fi
            sleep 5
          done

          echo "WARNING: kube-apiserver process not yet showing the required --tls-cipher-suites flag."
          echo "Current kube-apiserver processes:"
          /bin/ps -ef | grep kube-apiserver | grep -v grep || true
          exit 1
        }

        main() {
          ensure_manifest_exists
          configure_tls_cipher_suites
          verify_apiserver_process
        }

        main "$@"
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://github.com/ssllabs/research/wiki/SSL-and-TLS-Deployment-Best-Practices#23-use-secure-cipher-suites](https://github.com/ssllabs/research/wiki/SSL-and-TLS-Deployment-Best-Practices#23-use-secure-cipher-suites)
