Skip to main content

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​

Remediation​

Manual Steps
  1. On every control plane node, determine the etcd data directory:

    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):

    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):

    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:

    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:

    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:

    etcd:etcd
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.

Automation
#!/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

Additional Reading:​