> ## 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 Secure Port Argument Is Not Set 0

### More Info:

Do not disable the secure port.

### Risk Level

Critical

### 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 current manifest before editing:

        ```bash theme={null}
        sudo cp /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml.bak
        ```

        2. On every control plane node, edit the API server manifest to remove or change the `--secure-port` flag. For example, to set it to 6443:

        ```bash theme={null}
        sudo sed -i 's/--secure-port=0/--secure-port=6443/' /etc/kubernetes/manifests/kube-apiserver.yaml
        ```

        If the flag appears in another form, open the file and edit manually:

        ```bash theme={null}
        sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
        ```

        and either delete the `--secure-port=0` line or change `0` to your desired non‑zero port.

        3. Wait for the kubelet on each control plane node to automatically restart the `kube-apiserver` static pod due to the manifest change (typically within \~1 minute). Be aware this restarts the API server and may briefly impact API availability.

        4. On any machine with SSH access to each control plane node, verify the new `kube-apiserver` process is running with a non‑zero secure port:

        ```bash theme={null}
        ssh <control-plane-node> "/bin/ps -ef | grep kube-apiserver | grep -v grep"
        ```

        Confirm there is no `--secure-port=0` argument in the output; if `--secure-port` appears, it must be set to a non‑zero port (for example `--secure-port=6443`).
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot modify the kube-apiserver static pod manifest or its process flags. This finding must be fixed directly on every control plane node by editing `/etc/kubernetes/manifests/kube-apiserver.yaml`; see the Manual Steps section for the exact procedure.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Fix CISKubernetes 1.2.17: Ensure --secure-port is not set to 0 for kube-apiserver
        #
        # Run on: every control plane node (as root)
        #
        # Behavior:
        # - Backs up /etc/kubernetes/manifests/kube-apiserver.yaml once
        # - Ensures --secure-port is either absent or set to a non-zero port (default: 6443)
        # - Idempotent: safe to re-run
        # - Verifies by inspecting running kube-apiserver process

        set -euo pipefail

        API_SERVER_MANIFEST="/etc/kubernetes/manifests/kube-apiserver.yaml"
        BACKUP_SUFFIX=".pre_cis_1_2_17_backup"
        DESIRED_SECURE_PORT="6443"   # change this if you use a non-default secure port

        echo "[INFO] Starting remediation for kube-apiserver --secure-port on control plane node: $(hostname)"

        if [[ $EUID -ne 0 ]]; then
          echo "[ERROR] This script must be run as root."
          exit 1
        fi

        if [[ ! -f "${API_SERVER_MANIFEST}" ]]; then
          echo "[ERROR] Manifest ${API_SERVER_MANIFEST} not found. Nothing to do on this node."
          exit 1
        fi

        # Backup manifest once
        if [[ ! -f "${API_SERVER_MANIFEST}${BACKUP_SUFFIX}" ]]; then
          echo "[INFO] Creating backup: ${API_SERVER_MANIFEST}${BACKUP_SUFFIX}"
          cp -p "${API_SERVER_MANIFEST}" "${API_SERVER_MANIFEST}${BACKUP_SUFFIX}"
        else
          echo "[INFO] Backup already exists: ${API_SERVER_MANIFEST}${BACKUP_SUFFIX}"
        fi

        # Determine current --secure-port settings in manifest
        CURRENT_SECURE_PORT_LINES=$(grep -E -- '--secure-port(=|[[:space:]]+)' "${API_SERVER_MANIFEST}" || true)

        if [[ -z "${CURRENT_SECURE_PORT_LINES}" ]]; then
          echo "[INFO] No --secure-port found in manifest; nothing to change in file."
        else
          echo "[INFO] Existing --secure-port entries in manifest:"
          echo "${CURRENT_SECURE_PORT_LINES}"
        fi

        TMP_FILE="$(mktemp)"
        trap 'rm -f "${TMP_FILE}"' EXIT

        # Normalize --secure-port:
        # - Remove any occurrences with value 0
        # - Ensure at most one occurrence with DESIRED_SECURE_PORT
        #
        # Handles both:
        #   - --secure-port=0 / --secure-port=6443
        #   - ["--secure-port","0"] (rare but seen in some generator tools)

        cp "${API_SERVER_MANIFEST}" "${TMP_FILE}"

        # Remove any --secure-port explicitly set to 0 (various formatting styles)
        sed -i -E \
          -e 's/--secure-port=0[[:space:]]*//g' \
          -e 's/--secure-port[[:space:]]+0[[:space:]]*//g' \
          -e 's/"--secure-port","0"[[:space:]]*//g' \
          -e 's/"--secure-port", "0"[[:space:]]*//g' \
          "${TMP_FILE}"

        # If there is still a non-zero --secure-port defined, leave it as is (admin-chosen port)
        if grep -qE -- '--secure-port(=|[[:space:]]+)[1-9][0-9]*' "${TMP_FILE}"; then
          echo "[INFO] Non-zero --secure-port already configured in manifest; not overriding."
        else
          # No non-zero secure-port found; we ensure one is present with DESIRED_SECURE_PORT
          echo "[INFO] No non-zero --secure-port found; ensuring --secure-port=${DESIRED_SECURE_PORT} is set."

          # Try to append to an existing --secure-port line if one exists (without value),
          # else add a new argument entry under kube-apiserver container args.
          if grep -q -- '--secure-port' "${TMP_FILE}"; then
            # There is a bare --secure-port; normalize to desired value
            sed -i -E \
              -e "s/--secure-port([[:space:]]+|=)[^[:space:]\"]*/--secure-port=${DESIRED_SECURE_PORT}/g" \
              "${TMP_FILE}"
          else
            # Need to inject a new arg; attempt to place it alongside other args.
            # We look for a line under spec.containers[*].command or .args that has other flags.

            if grep -q 'kube-apiserver' "${TMP_FILE}" && grep -q '\-\-advertise-address' "${TMP_FILE}"; then
              # Common case: flags listed one-per-line; add a new line after --advertise-address
              sed -i -E \
                '/--advertise-address/ a\        - --secure-port='"${DESIRED_SECURE_PORT}" \
                "${TMP_FILE}" || true
            else
              # Fallback: append at end of args list if we can find one
              if grep -q 'args:' "${TMP_FILE}"; then
                # Add as a new element to args
                sed -i -E \
                  '/args:/,/image:/ {
                    /args:/!{
                      /-/!{
                        s/(args:[[:space:]]*)/\1\n        - --secure-port='"${DESIRED_SECURE_PORT}"'/
                      }
                    }
                  }' "${TMP_FILE}" || true
              fi
            fi

            # If still not present, append at end of file as a last resort (admin may refine manually)
            if ! grep -qE -- '--secure-port(=|[[:space:]]+)'"${DESIRED_SECURE_PORT}" "${TMP_FILE}"; then
              echo "[WARN] Could not safely inject --secure-port into existing args; appending at end of manifest."
              {
                echo "        # Added by CIS 1.2.17 remediation script"
                echo "        - --secure-port=${DESIRED_SECURE_PORT}"
              } >> "${TMP_FILE}"
            fi
          fi
        fi

        # If no change, avoid unnecessary restart
        if cmp -s "${API_SERVER_MANIFEST}" "${TMP_FILE}"; then
          echo "[INFO] Manifest already compliant; no changes applied."
        else
          echo "[INFO] Updating ${API_SERVER_MANIFEST} (this will restart kube-apiserver static pod)."
          cp "${TMP_FILE}" "${API_SERVER_MANIFEST}"
        fi

        # Allow static pod controller time to restart kube-apiserver if needed
        echo "[INFO] Waiting up to 60 seconds for kube-apiserver to restart (if changed)..."
        sleep 60 || true

        # Verification: ensure kube-apiserver process is not using --secure-port=0
        echo "[INFO] Verifying running kube-apiserver process arguments..."
        PS_OUT="$(/bin/ps -ef | grep kube-apiserver | grep -v grep || true)"

        if [[ -z "${PS_OUT}" ]]; then
          echo "[ERROR] kube-apiserver process not found after change. Check kubelet and pod logs."
          exit 2
        fi

        echo "${PS_OUT}"

        if echo "${PS_OUT}" | grep -q -- '--secure-port=0'; then
          echo "[ERROR] kube-apiserver is still running with --secure-port=0."
          exit 3
        fi

        if echo "${PS_OUT}" | grep -q -- '--secure-port'; then
          CURRENT_RUNNING_PORT="$(echo "${PS_OUT}" | sed -nE 's/.*--secure-port=([0-9]+).*/\1/p' | head -n1 || true)"
          if [[ -n "${CURRENT_RUNNING_PORT}" ]]; then
            echo "[INFO] kube-apiserver is running with secure port: ${CURRENT_RUNNING_PORT}"
          else
            echo "[INFO] kube-apiserver uses --secure-port (non-zero) but port parsing failed; review args above."
          fi
        else
          echo "[INFO] kube-apiserver is running with default secure port (argument not set explicitly)."
        fi

        echo "[INFO] Remediation for CISKubernetes 1.2.17 completed on node: $(hostname)"
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://kubernetes.io/docs/admin/kube-apiserver/](https://kubernetes.io/docs/admin/kube-apiserver/)
