> ## 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.

# Kubelet Rotate Server Certificates Argument Set To True

### More Info:

The kubelet --rotate-server-certificates argument should be set to true so the kubelet automatically requests and rotates its serving certificates. Disabling this increases exposure to expired or compromised server certificates.

### Risk Level

High

### Address

Security

### Compliance Standards

* CIS OKE

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. On every worker node, open the kubelet systemd drop-in config for editing:
           ```bash theme={null}
           sudo vi /etc/systemd/system/kubelet.service.d/00-default.conf
           ```

        2. In the `ExecStart=` line, ensure the kubelet is started with `--rotate-server-certificates=true`. Add it if missing, or change `false` to `true`, for example:
           ```ini theme={null}
           ExecStart=/usr/bin/kubelet \
             ... \
             --rotate-server-certificates=true
           ```

        3. If the kubelet also uses a config file (e.g. `/etc/kubernetes/kubelet-config.json`), check it for a conflicting setting and remove or align it. For example, if present, update this key to `true` or delete it so the flag above is authoritative:
           ```bash theme={null}
           sudo vi /etc/kubernetes/kubelet-config.json
           ```
           Ensure either this field is set true or absent:
           ```json theme={null}
           "rotateServerCertificate": true
           ```

        4. Reload systemd and restart kubelet on the same worker node:
           ```bash theme={null}
           sudo systemctl daemon-reload
           sudo systemctl restart kubelet.service
           ```

        5. Confirm kubelet is healthy on the worker node:
           ```bash theme={null}
           sudo systemctl status kubelet -l
           ```

        6. Verify the argument is now set to true on the worker node (repeat on all workers):
           ```bash theme={null}
           /bin/ps -fC kubelet | grep -- --rotate-server-certificates
           ```
           The output must include `--rotate-server-certificates=true`.
      </Accordion>

      <Accordion title="Using kubectl">
        `kubectl` cannot modify kubelet process flags or host-level config files such as `/etc/systemd/system/kubelet.service.d/00-default.conf` or `/etc/kubernetes/kubelet-config.json` on worker nodes. To enable `--rotate-server-certificates=true`, make the change directly on each worker node as described in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Enable kubelet --rotate-server-certificates=true on every worker node.
        # Usage:
        #   1) Populate NODES with worker node hostnames/IPs reachable via SSH.
        #   2) Ensure passwordless sudo and SSH access.
        #   3) Run this script from any admin machine: ./enable-kubelet-rotate-server-certs.sh
        #
        # Idempotent: safe to re-run.

        set -euo pipefail

        # EDIT THIS: list of worker nodes
        NODES=(
          worker-node-1
          worker-node-2
        )

        SSH_OPTS="-o BatchMode=yes -o StrictHostKeyChecking=accept-new"

        remote_run() {
          local node="$1"; shift
          ssh ${SSH_OPTS} "root@${node}" "$@"
        }

        for node in "${NODES[@]}"; do
          echo "=== Processing node: ${node} ==="

          remote_run "${node}" bash -s << 'EOF'
        set -euo pipefail

        UNIT_DIR="/etc/systemd/system/kubelet.service.d"
        UNIT_FILE="${UNIT_DIR}/00-default.conf"

        if [ ! -f "${UNIT_FILE}" ]; then
          echo "ERROR: ${UNIT_FILE} not found; kubelet may be managed differently on this node."
          exit 1
        fi

        echo "Current ${UNIT_FILE}:"
        sed -n '1,160p' "${UNIT_FILE}" || true

        # Ensure the drop-in has an [Service] section; if not, add one.
        if ! grep -q '^\[Service\]' "${UNIT_FILE}"; then
          printf '\n[Service]\n' >> "${UNIT_FILE}"
        fi

        # Make a backup once per run
        BACKUP="${UNIT_FILE}.$(date +%Y%m%d%H%M%S).bak"
        cp "${UNIT_FILE}" "${BACKUP}"
        echo "Backup created at ${BACKUP}"

        # Normalize into a single Environment line for editing
        # (handles the common case where KUBELET_KUBECONFIG_ARGS etc. are defined)
        if ! grep -q 'KUBELET_EXTRA_ARGS' "${UNIT_FILE}"; then
          # If there's no extra args line, append one
          cat << 'EOL' >> "${UNIT_FILE}"
        Environment="KUBELET_EXTRA_ARGS="
        EOL
        fi

        # Edit KUBELET_EXTRA_ARGS to ensure --rotate-server-certificates=true
        tmpfile="$(mktemp)"
        while IFS= read -r line; do
          if [[ "${line}" =~ ^Environment= ]]; then
            # Only touch lines with KUBELET_EXTRA_ARGS
            if [[ "${line}" == *"KUBELET_EXTRA_ARGS"* ]]; then
              # Remove any existing --rotate-server-certificates flags
              cleaned="$(printf '%s\n' "${line}" | sed -E 's_--rotate-server-certificates(=[^" ]*)?__g')"
              # Collapse multiple spaces
              cleaned="$(printf '%s\n' "${cleaned}" | sed -E 's/  +/ /g')"
              # Ensure it ends before final quote, then append desired flag
              if [[ "${cleaned}" =~ \"$ ]]; then
                cleaned="${cleaned%\"} --rotate-server-certificates=true\""
              else
                cleaned="${cleaned} --rotate-server-certificates=true"
              fi
              echo "${cleaned}" >> "${tmpfile}"
            else
              echo "${line}" >> "${tmpfile}"
            fi
          else
            echo "${line}" >> "${tmpfile}"
          fi
        done < "${UNIT_FILE}"

        mv "${tmpfile}" "${UNIT_FILE}"

        echo "Updated ${UNIT_FILE}:"
        sed -n '1,160p' "${UNIT_FILE}" || true

        echo "Reloading systemd and restarting kubelet (this restarts the kubelet process)..."
        systemctl daemon-reload
        systemctl restart kubelet.service

        echo "Verifying kubelet status..."
        systemctl status kubelet -l --no-pager || {
          echo "ERROR: kubelet service not healthy after restart."
          exit 1
        }

        echo "Verifying kubelet process has --rotate-server-certificates=true..."
        if /bin/ps -fC kubelet | grep -q -- '--rotate-server-certificates=true'; then
          echo "OK: kubelet is running with --rotate-server-certificates=true"
        else
          echo "ERROR: kubelet is not running with --rotate-server-certificates=true"
          /bin/ps -fC kubelet || true
          exit 1
        fi

        EOF

          echo "=== Node ${node} done ==="
        done

        echo "All nodes processed."
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
