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

# Verify Read Only Port Argument Is Set 0

### More Info:

Disable the read-only port.

### 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 worker node, check how kubelet is configured (file vs flags):
           ```bash theme={null}
           ps -fC kubelet
           ```
           Inspect the command line: if you see `--config=/var/lib/kubelet/config.yaml` it is using the config file; if you see `--read-only-port=` it is using flags.

        2. If using the kubelet config file, edit it to disable the read-only port:
           ```bash theme={null}
           sudo sed -i 's/^[[:space:]]*readOnlyPort:.*/readOnlyPort: 0/' /var/lib/kubelet/config.yaml
           ```
           If there is no `readOnlyPort` line, add it under the top-level `kubeletConfiguration` block, for example:
           ```bash theme={null}
           sudo sh -c 'printf "\nreadOnlyPort: 0\n" >> /var/lib/kubelet/config.yaml'
           ```

        3. If using command-line arguments, edit the kubelet systemd drop-in on each worker node:
           ```bash theme={null}
           sudo sed -i 's/--read-only-port=[0-9]\+/--read-only-port=0/' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
           ```
           If `--read-only-port` is missing, add it to the `KUBELET_SYSTEM_PODS_ARGS` (or the line with other `--` flags), for example:
           ```bash theme={null}
           sudo sed -i 's#^\(.*KUBELET_SYSTEM_PODS_ARGS=.*\)"#\1 --read-only-port=0"#' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
           ```

        4. On every worker node, reload systemd and restart kubelet (this will restart the kubelet and may briefly impact pod scheduling/health reporting on that node):
           ```bash theme={null}
           sudo systemctl daemon-reload
           sudo systemctl restart kubelet.service
           ```

        5. Verify on every worker node that kubelet is running with the read-only port disabled:
           ```bash theme={null}
           ps -fC kubelet
           ```
           Confirm either that:
           * the kubelet command line contains `--read-only-port=0`, or
           * kubelet is using `/var/lib/kubelet/config.yaml` and that file contains `readOnlyPort: 0`.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot modify kubelet process flags or its config file on worker nodes; this setting must be changed directly on each node’s `/var/lib/kubelet/config.yaml` or in the kubelet systemd unit. Refer to the Manual Steps section for the exact on-node configuration and restart instructions.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Fix: Ensure kubelet read-only port is disabled (readOnlyPort: 0)
        # Scope: every worker node
        #
        # Usage:
        #   Run as root on each worker node:
        #     bash ./fix-kubelet-readonlyport.sh
        #
        # Idempotent: safe to re-run.

        set -euo pipefail

        KUBELET_CONFIG="/var/lib/kubelet/config.yaml"
        SYSTEMD_DROPIN="/etc/systemd/system/kubelet.service.d/10-kubeadm.conf"
        BACKUP_SUFFIX=".$(date +%Y%m%d%H%M%S).bak"

        log() { printf '[%s] %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$*"; }

        require_root() {
          if [ "$(id -u)" -ne 0 ]; then
            log "ERROR: This script must be run as root."
            exit 1
          fi
        }

        backup_file() {
          local f="$1"
          if [ -f "$f" ]; then
            cp -p "$f" "$f$BACKUP_SUFFIX"
            log "Backup created: $f$BACKUP_SUFFIX"
          fi
        }

        ensure_readonlyport_in_config() {
          if [ ! -f "$KUBELET_CONFIG" ]; then
            log "Kubelet config file not found at $KUBELET_CONFIG, skipping file-based config."
            return 1
          fi

          backup_file "$KUBELET_CONFIG"

          if grep -qE '^\s*readOnlyPort:' "$KUBELET_CONFIG"; then
            # Replace existing key
            sed -i 's/^\(\s*readOnlyPort:\).*/\1 0/' "$KUBELET_CONFIG"
            log "Updated existing readOnlyPort entry to 0 in $KUBELET_CONFIG"
          else
            # Append key at top-level (2 space indent is acceptable for this scalar)
            printf '\nreadOnlyPort: 0\n' >> "$KUBELET_CONFIG"
            log "Appended readOnlyPort: 0 to $KUBELET_CONFIG"
          fi

          return 0
        }

        ensure_readonlyport_in_systemd() {
          if [ ! -f "$SYSTEMD_DROPIN" ]; then
            log "Systemd drop-in not found at $SYSTEMD_DROPIN, skipping CLI-arg config."
            return 1
          fi

          backup_file "$SYSTEMD_DROPIN"

          # Ensure KUBELET_SYSTEM_PODS_ARGS exists in Environment line
          if grep -q 'KUBELET_SYSTEM_PODS_ARGS' "$SYSTEMD_DROPIN"; then
            :
          else
            # Add an Environment line if missing
            echo 'Environment="KUBELET_SYSTEM_PODS_ARGS="' >> "$SYSTEMD_DROPIN"
            log "Added KUBELET_SYSTEM_PODS_ARGS environment definition to $SYSTEMD_DROPIN"
          fi

          # Remove any existing --read-only-port flag
          sed -i 's/--read-only-port=[^" ]*//g' "$SYSTEMD_DROPIN"

          # Add --read-only-port=0 into KUBELET_SYSTEM_PODS_ARGS
          # If the var is empty, just set this flag; otherwise append.
          perl -0777 -pi -e '
            s/(Environment="[^"]*KUBELET_SYSTEM_PODS_ARGS=)([^"]*)"/
              my $prefix = $1; my $val = $2;
              $val =~ s/\s+$//;
              if ($val =~ /--read-only-port=0\b/) { $prefix.$val."\"" }
              elsif ($val eq "") { $prefix."--read-only-port=0\"" }
              else { $prefix.$val." --read-only-port=0\"" }
            /eg
          ' "$SYSTEMD_DROPIN"

          log "Ensured --read-only-port=0 is present in KUBELET_SYSTEM_PODS_ARGS in $SYSTEMD_DROPIN"
          return 0
        }

        restart_kubelet() {
          log "Reloading systemd and restarting kubelet (this will restart the kubelet process)..."
          systemctl daemon-reload
          systemctl restart kubelet.service
          log "kubelet restarted."
        }

        verify() {
          log "Verifying kubelet read-only port is disabled..."

          # Check via ps flags
          if /bin/ps -fC kubelet 2>/dev/null | grep -q -- '--read-only-port=0'; then
            log "Verification: kubelet process has --read-only-port=0 flag."
          else
            log "WARNING: kubelet process does not show --read-only-port=0 flag in ps output."
          fi

          # If config file exists, also verify its content
          if [ -f "$KUBELET_CONFIG" ]; then
            if grep -qE '^\s*readOnlyPort:\s*0\b' "$KUBELET_CONFIG"; then
              log "Verification: $KUBELET_CONFIG contains readOnlyPort: 0"
            else
              log "WARNING: $KUBELET_CONFIG does not contain readOnlyPort: 0"
            fi
          fi

          # Final display of kubelet command line for manual confirmation
          log "Current kubelet command line:"
          /bin/ps -fC kubelet || true
        }

        main() {
          require_root

          local cfg_ok=1
          local sysd_ok=1

          if ensure_readonlyport_in_config; then
            cfg_ok=0
          fi

          if ensure_readonlyport_in_systemd; then
            sysd_ok=0
          fi

          if [ "$cfg_ok" -ne 0 ] && [ "$sysd_ok" -ne 0 ]; then
            log "ERROR: Neither $KUBELET_CONFIG nor $SYSTEMD_DROPIN could be updated. Please review manually."
            exit 1
          fi

          restart_kubelet
          verify
        }

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

### Additional Reading:

* [https://kubernetes.io/docs/admin/kubelet/](https://kubernetes.io/docs/admin/kubelet/)
