Skip to main content

Ensure Etcd Peer-Auto-TLS Argument Is Not Set To True

More Info:

The --peer-auto-tls argument must not be set to true, as it makes etcd use automatically generated self-signed certificates for peer connections. This bypasses proper certificate authentication between etcd nodes.

Risk Level

Critical

Address

Security

Compliance Standards

  • CIS Kubernetes

Triage and Remediation

Remediation

Manual Steps
  1. On every etcd (control plane) node, back up the existing manifest:
sudo cp -p /etc/kubernetes/manifests/etcd.yaml /etc/kubernetes/manifests/etcd.yaml.bak
  1. On every etcd node, open the manifest for editing:
sudo vi /etc/kubernetes/manifests/etcd.yaml
  1. In the spec.containers[].command (or args) section for the etcd container, locate any --peer-auto-tls entry. Either delete that argument line entirely or change it to:
- --peer-auto-tls=false

Save and exit the editor.

  1. Be aware: editing /etc/kubernetes/manifests/etcd.yaml causes the kubelet to restart the etcd static pod on that node. Allow a few moments for the etcd container to restart and stabilize.

  2. On every etcd node, verify etcd was restarted and that --peer-auto-tls is not set to true:

ps -ef | grep etcd | grep -v grep

Confirm that:

  • there is no --peer-auto-tls=true in the process arguments, and
  • if --peer-auto-tls appears, it is --peer-auto-tls=false (or the flag is absent).
Using kubectl

kubectl cannot modify the etcd static pod manifest or its process flags. This finding must be fixed by editing /etc/kubernetes/manifests/etcd.yaml directly on every etcd (control plane) node; see the Manual Steps section for the exact host-level changes and verification.

Automation
#!/usr/bin/env bash
#
# Fix: Ensure etcd --peer-auto-tls argument is not set to true
# Scope: every etcd node (control plane nodes)
# Run on: each control plane node with root privileges
#
# Idempotent: safe to run multiple times
# Note: Editing /etc/kubernetes/manifests/etcd.yaml will restart the etcd static pod via kubelet.

set -euo pipefail

ETCD_MANIFEST="/etc/kubernetes/manifests/etcd.yaml"
BACKUP_DIR="/etc/kubernetes/manifests/backup-peer-auto-tls-$(date +%Y%m%d-%H%M%S)"

echo "[INFO] Starting etcd --peer-auto-tls remediation"

if [[ ! -f "$ETCD_MANIFEST" ]]; then
echo "[ERROR] Etcd manifest not found at $ETCD_MANIFEST"
exit 1
fi

# Create a timestamped backup directory and backup file (only once per run)
mkdir -p "$BACKUP_DIR"
cp -p "$ETCD_MANIFEST" "$BACKUP_DIR/etcd.yaml"
echo "[INFO] Backup of etcd manifest created at $BACKUP_DIR/etcd.yaml"

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

# 1) Remove any explicit --peer-auto-tls (regardless of value)
# 2) Then ensure --peer-auto-tls=false is present exactly once in the etcd container args.
#
# We:
# - delete all occurrences of "--peer-auto-tls=..." from the file
# - then add a single "--peer-auto-tls=false" arg to the etcd container if absent
#
# This approach is line-based and does not depend on a particular YAML key order.

# Step 1: Remove any existing --peer-auto-tls from the manifest
sed -E 's/--peer-auto-tls(=[^" ]*)?//g' "$ETCD_MANIFEST" > "$TMP_FILE"

# Step 2: Ensure a single "--peer-auto-tls=false" in the etcd container args list
#
# We insert it after the first occurrence of "etcd" container command/arg line that
# already has another --peer- flag, or after the "image: etcd" line as a fallback.
#
# This is best-effort while keeping the script pure bash/sed/awk and idempotent.

# Check if the cleaned file already contains --peer-auto-tls=false
if ! grep -q -- '--peer-auto-tls=false' "$TMP_FILE"; then
awk '
# State tracking
/name:[[:space:]]*etcd/ { in_etcd_container=1 }
in_etcd_container && /name:[[:space:]]*[A-Za-z0-9_-]+/ && !/name:[[:space:]]*etcd/ { in_etcd_container=0 }
{
print $0
# Heuristic 1: insert after an args/command line with another --peer- flag
if (in_etcd_container && $0 ~ /--peer-/ && $0 !~ /--peer-auto-tls/) {
# infer indentation from current line
match($0, /^[[:space:]]*/)
indent = substr($0, RSTART, RLENGTH)
print indent "--peer-auto-tls=false"
in_etcd_container=0
}
}
' "$TMP_FILE" > "${TMP_FILE}.2"

# If still not present (heuristic 1 failed), do a simpler injection:
if ! grep -q -- '--peer-auto-tls=false' "${TMP_FILE}.2"; then
awk '
/name:[[:space:]]*etcd/ { in_etcd_container=1 }
in_etcd_container && /image:/ && /etcd/ {
print $0
# add a minimal args list line with --peer-auto-tls=false
# user may refine args ordering later if desired
match($0, /^[[:space:]]*/)
indent = substr($0, RSTART, RLENGTH)
print indent "command:"
print indent "- etcd"
print indent "- --peer-auto-tls=false"
in_etcd_container=0
next
}
{
print $0
}
' "${TMP_FILE}.2" > "${TMP_FILE}.3"
FINAL="${TMP_FILE}.3"
else
FINAL="${TMP_FILE}.2"
fi
else
FINAL="$TMP_FILE"
fi

# Install the modified manifest
cp -p "$FINAL" "$ETCD_MANIFEST"
echo "[INFO] Updated $ETCD_MANIFEST with --peer-auto-tls=false and removed any true values"

echo "[INFO] Waiting 10 seconds for kubelet to reload the static pod manifest and restart etcd if needed..."
sleep 10

# Verification: ensure etcd is not running with --peer-auto-tls=true
echo "[INFO] Verifying that etcd is not running with --peer-auto-tls=true"
if /bin/ps -ef | /bin/grep etcd | /bin/grep -v grep | /bin/grep -q -- '--peer-auto-tls=true'; then
echo "[FAIL] etcd is still running with --peer-auto-tls=true"
/bin/ps -ef | /bin/grep etcd | /bin/grep -v grep
exit 1
fi

# Optional: show current etcd process args for confirmation
/bin/ps -ef | /bin/grep etcd | /bin/grep -v grep || true

echo "[OK] Remediation complete: --peer-auto-tls is not set to true on this node."