Etcd Data Directory Ownership Should Be etcd:etcd
More Info:
Verifies that the etcd data directory is owned by etcd:etcd so only the etcd service account can access the cluster datastore.
Risk Level
Medium
Address
Security
Compliance Standards
- CIS Kubernetes
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
On every control plane node, identify the etcd data directory:
ps -ef | grep '[e]tcd' | grep -- --data-dirFrom the output, note the value passed to
--data-dir. If no--data-diris present, use/var/lib/etcd/default.etcdas the directory. -
On every control plane node, confirm the directory exists (replace the path if different):
ls -ld /var/lib/etcdIf your
--data-dirwas different, substitute that exact path in place of/var/lib/etcd. -
On every control plane node, ensure the
etcduser and group exist:id etcdIf this command fails, create them according to your OS standards before proceeding.
-
On every control plane node, change ownership of the etcd data directory (substitute the actual data-dir path if different):
chown -R etcd:etcd /var/lib/etcd -
On every control plane node, verify the ownership is now correct for the etcd data directory (replace the path with your actual data-dir if needed):
stat -c %U:%G /var/lib/etcdThe output must be:
etcd:etcd
Using kubectl
kubectl cannot modify host-level file ownership such as the etcd data directory on control plane nodes; this must be corrected directly on each control plane node’s filesystem (for example with chown on /var/lib/etcd). See the Manual Steps section for the exact commands to run on the nodes.
Automation
#!/usr/bin/env bash
#
# Remediation for: CISKubernetes 1.1.12
# Ensure that the etcd data directory ownership is set to etcd:etcd
#
# Run this script on every control plane node.
# It is safe to re-run; it will only change ownership when needed.
set -euo pipefail
echo "=== [CIS 1.1.12] Fix etcd data directory ownership to etcd:etcd ==="
# 1. Detect etcd data directory (mirrors the audit logic)
DATA_DIR=''
while read -r line; do
dir=$(printf '%s\n' "$line" | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%')
if [ -n "$dir" ] && [ -d "$dir" ]; then
DATA_DIR="$dir"
fi
done < <(ps -ef | grep etcd | grep -- --data-dir || true)
if [ -z "$DATA_DIR" ]; then
# Fallback per audit command
DATA_DIR="/var/lib/etcd/default.etcd"
fi
if [ ! -d "$DATA_DIR" ]; then
echo "ERROR: etcd data directory '$DATA_DIR' does not exist on this node."
exit 1
fi
echo "Detected etcd data directory: $DATA_DIR"
# 2. Ensure etcd user and group exist
if ! id -u etcd >/dev/null 2>&1; then
echo "ERROR: user 'etcd' does not exist. Create the etcd user/group before running this script."
exit 1
fi
if ! getent group etcd >/dev/null 2>&1; then
echo "ERROR: group 'etcd' does not exist. Create the etcd group before running this script."
exit 1
fi
# 3. Check current ownership
CURRENT_OWNER=$(stat -c %U:%G "$DATA_DIR")
echo "Current ownership of $DATA_DIR: $CURRENT_OWNER"
if [ "$CURRENT_OWNER" = "etcd:etcd" ]; then
echo "Ownership already set to etcd:etcd. No change required."
else
echo "Changing ownership of $DATA_DIR to etcd:etcd (recursive)..."
chown -R etcd:etcd "$DATA_DIR"
echo "Ownership change complete."
fi
# 4. Verification (mirrors the audit command)
echo "Verifying ownership..."
VERIFY_DATA_DIR=''
for d in $(ps -ef | grep etcd | grep -- --data-dir | sed 's%.*data-dir[= ]\([^ ]*\).*%\1%'); do
if [ -d "$d" ]; then VERIFY_DATA_DIR="$d"; fi
done
if [ -z "$VERIFY_DATA_DIR" ]; then
VERIFY_DATA_DIR="/var/lib/etcd/default.etcd"
fi
if [ ! -d "$VERIFY_DATA_DIR" ]; then
echo "ERROR: verification failed, directory '$VERIFY_DATA_DIR' does not exist."
exit 1
fi
VERIFY_OWNER=$(stat -c %U:%G "$VERIFY_DATA_DIR")
echo "Verified ownership of $VERIFY_DATA_DIR: $VERIFY_OWNER"
if [ "$VERIFY_OWNER" != "etcd:etcd" ]; then
echo "ERROR: etcd data directory ownership is NOT etcd:etcd after remediation."
exit 1
fi
echo "SUCCESS: etcd data directory ownership is correctly set to etcd:etcd on this control plane node."