Kubelet Only Makes Use Of Strong Cryptographic Ciphers
More Info:
Restricting tlsCipherSuites to strong ciphers prevents the kubelet from negotiating weak or deprecated cryptographic algorithms. This hardens the confidentiality of kubelet TLS connections.
Risk Level
Medium
Address
Security
Compliance Standards
- CIS Kubernetes
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
On every worker node, back up the existing kubelet config and (if present) the systemd drop-in:
sudo cp -a /var/lib/kubelet/config.yaml /var/lib/kubelet/config.yaml.bak.$(date +%s) || truesudo cp -a /etc/systemd/system/kubelet.service.d/10-kubeadm.conf /etc/systemd/system/kubelet.service.d/10-kubeadm.conf.bak.$(date +%s) 2>/dev/null || true -
On every worker node, edit
/var/lib/kubelet/config.yamlto define strong ciphers in the Kubelet config file (create or replace thetlsCipherSuitessection as needed):sudo sed -i '/^tlsCipherSuites:/,$d' /var/lib/kubelet/config.yamlsudo tee -a /var/lib/kubelet/config.yaml >/dev/null <<'EOF'
tlsCipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 EOF
3. On every worker node, if the kubelet is configured via flags, ensure `--tls-cipher-suites` is set in the systemd drop-in (adjust this file only if your kubelet actually uses it):
```bash
if [ -f /etc/systemd/system/kubelet.service.d/10-kubeadm.conf ]; then
sudo sed -i '/--tls-cipher-suites=/d' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
sudo sed -i 's#^\(ExecStart=.*kubelet\b\)\(.*\)$#\1\2 --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384#' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
fi
-
On every worker node, reload systemd and restart the kubelet (this will disrupt kubelet on the node briefly, so do this node by node):
sudo systemctl daemon-reloadsudo systemctl restart kubelet.service -
On every worker node, confirm the kubelet process is running with the desired cipher suites flag (if you use flags) and that it has restarted successfully:
/bin/ps -fC kubeletsudo systemctl status kubelet.service --no-pager -
Optionally, on every worker node, confirm that either the config file or the flag now specifies only strong ciphers:
grep -A10 '^tlsCipherSuites:' /var/lib/kubelet/config.yaml || true/bin/ps -fC kubelet | grep -- '--tls-cipher-suites' || true
Using kubectl
kubectl cannot modify kubelet host-level configuration such as /var/lib/kubelet/config.yaml or systemd units on worker nodes. To remediate this finding, you must change the kubelet configuration directly on each worker node; follow the guidance in the Manual Steps section.
Automation
#!/usr/bin/env bash
#
# Harden kubelet TLS cipher suites on every worker node.
# Usage: run as root on each worker node (or via SSH/Ansible).
#
set -euo pipefail
CIPHERS="TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
KUBELET_CONFIG_FILE="/var/lib/kubelet/config.yaml"
KUBELET_SYSTEMD_DROPIN="/etc/systemd/system/kubelet.service.d/10-kubeadm.conf"
echo "==> Hardening kubelet TLS cipher suites on node: $(hostname)"
# Ensure jq and yq are available if needed
need_cmd() {
command -v "$1" >/dev/null 2>&1 || {
echo "ERROR: required command '$1' not found in PATH" >&2
exit 1
}
}
# Prefer config file if it exists; otherwise fall back to systemd flag
if [ -f "$KUBELET_CONFIG_FILE" ]; then
echo "==> Detected kubelet config file at $KUBELET_CONFIG_FILE"
need_cmd yq
# Backup once per run if not already backed up in this session
BACKUP="${KUBELET_CONFIG_FILE}.$(date +%Y%m%d%H%M%S).bak"
cp -p "$KUBELET_CONFIG_FILE" "$BACKUP"
echo " Backup created: $BACKUP"
# Idempotently set tlsCipherSuites
TMP_FILE="$(mktemp)"
yq -y ".tlsCipherSuites = [\"${CIPHERS//,/\",\"}\"]" "$KUBELET_CONFIG_FILE" > "$TMP_FILE"
chmod --reference="$KUBELET_CONFIG_FILE" "$TMP_FILE"
mv "$TMP_FILE" "$KUBELET_CONFIG_FILE"
echo " Updated tlsCipherSuites in $KUBELET_CONFIG_FILE"
else
echo "==> No kubelet config file at $KUBELET_CONFIG_FILE, using systemd flags"
if [ ! -f "$KUBELET_SYSTEMD_DROPIN" ]; then
echo "ERROR: $KUBELET_SYSTEMD_DROPIN not found; cannot set --tls-cipher-suites flag automatically." >&2
echo "Create the file and define kubelet ExecStart with the desired --tls-cipher-suites." >&2
exit 1
fi
# Backup
BACKUP="${KUBELET_SYSTEMD_DROPIN}.$(date +%Y%m%d%H%M%S).bak"
cp -p "$KUBELET_SYSTEMD_DROPIN" "$BACKUP"
echo " Backup created: $BACKUP"
# Idempotently ensure --tls-cipher-suites flag is present with desired value
TMP_FILE="$(mktemp)"
# For simplicity and safety, replace any existing --tls-cipher-suites=... with the desired value,
# or append it if missing, only on the ExecStart line.
awk -v ciphers="$CIPHERS" '
/^ExecStart=/ {
# Remove existing --tls-cipher-suites=... occurrences
gsub(/--tls-cipher-suites=[^ ]+/, "")
# Ensure a single space before appending the flag
sub(/[[:space:]]*$/,"")
print $0 " --tls-cipher-suites=" ciphers
next
}
{ print }
' "$KUBELET_SYSTEMD_DROPIN" > "$TMP_FILE"
chmod --reference="$KUBELET_SYSTEMD_DROPIN" "$TMP_FILE"
mv "$TMP_FILE" "$KUBELET_SYSTEMD_DROPIN"
echo " Updated --tls-cipher-suites in $KUBELET_SYSTEMD_DROPIN"
fi
echo "==> Restarting kubelet (this will briefly disrupt workloads on this node)"
systemctl daemon-reload
systemctl restart kubelet.service
sleep 3
echo "==> Verification: kubelet process and configuration"
# 1) Show kubelet process (as per audit command)
echo "---- kubelet process (ps -fC kubelet) ----"
if ! /bin/ps -fC kubelet; then
echo "ERROR: kubelet process not found after restart." >&2
exit 1
fi
# 2) Verify effective setting depending on method
if [ -f "$KUBELET_CONFIG_FILE" ]; then
need_cmd yq
echo "---- tlsCipherSuites from $KUBELET_CONFIG_FILE ----"
yq '.tlsCipherSuites' "$KUBELET_CONFIG_FILE"
else
echo "---- ExecStart from $KUBELET_SYSTEMD_DROPIN ----"
sed -n 's/^ExecStart=/ExecStart=/p' "$KUBELET_SYSTEMD_DROPIN"
fi
echo "==> Completed on node: $(hostname)"