> ## 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 Etcd Data Directory Ownership Is Etcd

### More Info:

Ensure that the etcd data directory ownership is set to etcd:etcd

### 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, determine the etcd data directory:
           ```bash theme={null}
           ps -ef | grep '[e]tcd' | grep -- --data-dir
           ```
           From the output, note the value of `--data-dir` (for example `/var/lib/etcd` or `/var/lib/etcd/default.etcd`).

        2. On the same control plane node, confirm that directory exists (substitute the actual path you found):
           ```bash theme={null}
           ls -ld /var/lib/etcd
           ```
           If the directory is different, replace `/var/lib/etcd` in the command above with your actual data directory path.

        3. On the same control plane node, change ownership of the etcd data directory to `etcd:etcd` (substitute the actual path you found):
           ```bash theme={null}
           sudo chown -R etcd:etcd /var/lib/etcd
           ```

        4. If your etcd data directory is not explicitly set via `--data-dir` and does not exist, create the default directory and set ownership:
           ```bash theme={null}
           sudo mkdir -p /var/lib/etcd/default.etcd
           sudo chown -R etcd:etcd /var/lib/etcd/default.etcd
           ```

        5. On the same control plane node, verify ownership using a command derived from the audit:
           ```bash theme={null}
           DATA_DIR=''
           for d in $(ps -ef | grep etcd | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%'); do
             if test -d "$d"; then DATA_DIR="$d"; fi
           done
           if ! test -d "$DATA_DIR"; then DATA_DIR=/var/lib/etcd/default.etcd; fi
           stat -c %U:%G "$DATA_DIR"
           ```
           Ensure the output is:
           ```text theme={null}
           etcd:etcd
           ```
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot modify ownership of the etcd data directory or edit `/etc/kubernetes/manifests/etcd.yaml`, because these are host-level files managed directly on each control plane node. To remediate this finding, follow the instructions in the **Manual Steps** section on every control plane node.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Remediation: Ensure the etcd data directory ownership is set to etcd:etcd
        # Scope: Run on every control plane node
        # Usage: sudo bash fix-etcd-data-dir-ownership.sh
        set -euo pipefail

        echo "[INFO] Detecting etcd data directory..."

        DATA_DIR=''
        # Discover the etcd --data-dir from the running process
        for d in $(ps -ef | grep '[e]tcd' | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%'); do
          if [ -d "$d" ]; then
            DATA_DIR="$d"
          fi
        done

        # Fallback used by the audit command if no directory could be discovered
        if [ -z "${DATA_DIR}" ]; then
          DATA_DIR="/var/lib/etcd/default.etcd"
        fi

        if [ ! -d "${DATA_DIR}" ]; then
          echo "[ERROR] Detected etcd data directory '${DATA_DIR}' does not exist."
          echo "[ERROR] Check the etcd manifest at /etc/kubernetes/manifests/etcd.yaml for the correct --data-dir value."
          exit 1
        fi

        echo "[INFO] Etcd data directory resolved to: ${DATA_DIR}"

        # Ensure etcd user and group exist
        if ! id etcd >/dev/null 2>&1; then
          echo "[ERROR] User 'etcd' does not exist on this node. Create it before running this script."
          exit 1
        fi
        if ! getent group etcd >/dev/null 2>&1; then
          echo "[ERROR] Group 'etcd' does not exist on this node. Create it before running this script."
          exit 1
        fi

        CURRENT_OWNER="$(stat -c '%U:%G' "${DATA_DIR}")"
        echo "[INFO] Current ownership of ${DATA_DIR}: ${CURRENT_OWNER}"

        if [ "${CURRENT_OWNER}" = "etcd:etcd" ]; then
          echo "[INFO] Ownership already set to etcd:etcd. No change needed."
        else
          echo "[INFO] Updating ownership of ${DATA_DIR} to etcd:etcd (recursive)..."
          chown -R etcd:etcd "${DATA_DIR}"
        fi

        echo "[INFO] Verifying ownership after remediation..."
        FINAL_OWNER="$(stat -c '%U:%G' "${DATA_DIR}")"
        echo "[INFO] Final ownership of ${DATA_DIR}: ${FINAL_OWNER}"

        if [ "${FINAL_OWNER}" != "etcd:etcd" ]; then
          echo "[ERROR] Ownership is still not etcd:etcd. Manual investigation required."
          exit 1
        fi

        echo "[INFO] Verification successful. Etcd data directory ownership is correctly set to etcd:etcd."
        exit 0
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://coreos.com/etcd/docs/latest/op-guide/configuration.html#data-dir](https://coreos.com/etcd/docs/latest/op-guide/configuration.html#data-dir)
