Skip to main content

5.2.2.5. Verification

This section covers the verification of the correctness of created certificates and keys, as well as the correspondence between them. This is important for eliminating errors before launching Kubernetes components.

Certificate block verification

● Optional

After configuring the certificates, it is recommended to verify their correctness using Kubeadm

Working directory

mkdir -p /etc/kubernetes/openssl

Script creation instructions

Script creation instructions
cat <<'EOF' > /etc/kubernetes/openssl/cert-report.sh
#!/usr/bin/env bash
set -euo pipefail

TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT

declare -A CN_TO_CA_NAME
declare -A PROCESSED_FINGERPRINTS
CERT_ROWS=()
CA_ROWS=()

CERT_HEADER=$(printf "%-28s %-25s %-15s %-24s %-20s" \
"CERTIFICATE" "EXPIRES" "RESIDUAL TIME" "CERTIFICATE AUTHORITY" "EXTERNALLY MANAGED")
CA_HEADER=$(printf "%-24s %-25s %-15s %-20s" \
"CERTIFICATE AUTHORITY" "EXPIRES" "RESIDUAL TIME" "EXTERNALLY MANAGED")

CERT_PATH="${1:-}"

if [ -n "$CERT_PATH" ]; then
FILES=("$CERT_PATH")
else
mapfile -t FILES < <(
find /etc/kubernetes/ \
-type d -name openssl -prune -o \
-type f \( -name "*.crt" -o -name "*.pem" -o -name "*.conf" \) -print 2>/dev/null
)
fi

extract_cert() {
local file="$1"
local out="$2"
if grep -q "client-certificate-data:" "$file"; then
awk '/client-certificate-data:/ {print $2}' "$file" | base64 -d > "$out"
else
cp "$file" "$out"
fi
}

cert_lifetime() {
local end="$1"
local end_ts now_ts days years
end_ts=$(date -d "$end" +%s)
now_ts=$(date +%s)
(( end_ts < now_ts )) && echo "expired" && return
days=$(( (end_ts - now_ts) / 86400 ))
years=$(( days / 365 ))
(( years > 0 )) && echo "${years}y" || echo "${days}d"
}

cert_name() {
local path="$1"
local base
base=$(basename "$path" | sed 's/\.\(crt\|pem\|conf\)$//')
case "$path" in
*/etcd/*) echo "etcd-$base" ;;
*/front-proxy/*) echo "front-proxy-$base" ;;
*) echo "$base" ;;
esac
}

for file in "${FILES[@]}"; do
crt="$TMPDIR/ca.crt"
extract_cert "$file" "$crt" || continue
openssl x509 -in "$crt" -noout -text 2>/dev/null | grep -A1 "Key Usage" | grep -q "Certificate Sign" || continue
cn=$(openssl x509 -in "$crt" -noout -subject 2>/dev/null | sed -n 's/.*CN *= *\([^,\/]*\).*/\1/p')
[[ -n "$cn" ]] && CN_TO_CA_NAME["$cn"]="$(cert_name "$file")"
done

for file in "${FILES[@]}"; do
crt="$TMPDIR/cert.crt"
extract_cert "$file" "$crt" || continue
openssl x509 -in "$crt" -noout >/dev/null 2>&1 || continue

fp=$(openssl x509 -in "$crt" -noout -fingerprint -sha256 | cut -d= -f2)
[[ -n "${PROCESSED_FINGERPRINTS[$fp]+x}" ]] && continue
PROCESSED_FINGERPRINTS[$fp]=1

name=$(cert_name "$file")
end_raw=$(openssl x509 -in "$crt" -noout -enddate | cut -d= -f2)
expires=$(date -d "$end_raw" "+%b %d, %Y %H:%M UTC")
residual=$(cert_lifetime "$end_raw")

if openssl x509 -in "$crt" -noout -text | grep -A1 "Key Usage" | grep -q "Certificate Sign"; then
CA_ROWS+=("$(printf "%-24s %-25s %-15s %-20s" "$name" "$expires" "$residual" "no")")
else
issuer_cn=$(openssl x509 -in "$crt" -noout -issuer | sed -n 's/.*CN *= *\([^,\/]*\).*/\1/p')
ca_name="${CN_TO_CA_NAME[$issuer_cn]:-$issuer_cn}"
CERT_ROWS+=("$(printf "%-28s %-25s %-15s %-24s %-20s" "$name" "$expires" "$residual" "$ca_name" "no")")
fi
done

echo
echo "$CERT_HEADER"
printf "%s\n" "${CERT_ROWS[@]}" | sort
echo
echo "$CA_HEADER"
printf "%s\n" "${CA_ROWS[@]}" | sort
EOF

Setting permissions

chmod +x /etc/kubernetes/openssl/cert-report.sh

Running the script for all certificates/kubeconfigs

/etc/kubernetes/openssl/cert-report.sh
Note
CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
admin.conf Oct 22, 2025 22:06 UTC 364d ca no
apiserver Oct 22, 2025 22:06 UTC 364d ca no
apiserver-etcd-client Oct 22, 2025 22:06 UTC 364d etcd-ca no
apiserver-kubelet-client Oct 22, 2025 22:06 UTC 364d ca no
controller-manager.conf Oct 22, 2025 22:06 UTC 364d ca no
etcd-healthcheck-client Oct 22, 2025 22:06 UTC 364d etcd-ca no
etcd-peer Oct 22, 2025 22:06 UTC 364d etcd-ca no
etcd-server Oct 22, 2025 22:06 UTC 364d etcd-ca no
front-proxy-client Oct 22, 2025 22:06 UTC 364d front-proxy-ca no
scheduler.conf Oct 22, 2025 22:06 UTC 364d ca no
super-admin.conf Oct 22, 2025 22:06 UTC 364d ca no

CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED
ca Oct 20, 2034 22:04 UTC 9y no
etcd-ca Oct 20, 2034 22:04 UTC 9y no
front-proxy-ca Oct 20, 2034 22:04 UTC 9y no

Running the script for a single certificate/kubeconfig

/etc/kubernetes/openssl/cert-report.sh /etc/kubernetes/pki/ca.crt
Note
CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED


CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED
ca Oct 20, 2034 22:04 UTC 9y no