【k8s】k8s集群check镜像中jre/jdk证书库

如何check k8s集群中所有pod背后的镜像的jre/jdk证书库中是否导入了CFCA根证书?

#!/bin/bash

# 检查命名空间参数
NAMESPACE="${1:-test}"
if ! kubectl get ns "$NAMESPACE" &> /dev/null; then
  echo "错误: 命名空间 $NAMESPACE 不存在或无法访问"
  exit 1
fi

# 获取所有镜像并去重
echo "正在获取 $NAMESPACE 命名空间中的镜像..."
IMAGES=$(kubectl get pods -n "$NAMESPACE" -o jsonpath='{.items[*].spec.containers[*].image}' | tr ' ' '\n' | sort -u)

if [ -z "$IMAGES" ]; then
  echo "未找到任何镜像"
  exit 2
fi

echo -e "\n发现以下镜像:"
echo "$IMAGES"
echo "========================================"

# 拉取所有镜像
echo "开始拉取镜像..."
for IMAGE in $IMAGES; do
  echo "拉取: $IMAGE"
  if ! docker pull -q "$IMAGE" > /dev/null; then
    echo "警告: 拉取 $IMAGE 失败"
  fi
done
echo "========================================"
echo

# 检查CFCA证书的函数
check_cfca() {
  local IMAGE=$1
  echo "检查镜像: $IMAGE"
  
  # 使用临时容器执行检查
  docker run --rm -i --entrypoint=/bin/sh "$IMAGE" <<'EOF'
#!/bin/sh
set -e

# 获取Java路径
find_java() {
  # 检查JAVA_HOME环境变量
  if [ -n "$JAVA_HOME" ] && [ -x "$JAVA_HOME/bin/java" ]; then
    echo "$JAVA_HOME"
    return 0
  fi
  
  # 检查PATH中的java命令
  if command -v java >/dev/null 2>&1; then
    JAVA_PATH=$(command -v java)
    # 解析符号链接
    while [ -L "$JAVA_PATH" ]; do
      LINK=$(ls -l "$JAVA_PATH" | awk '{print $NF}')
      if [ "${LINK:0:1}" = "/" ]; then
        JAVA_PATH="$LINK"
      else
        JAVA_PATH="$(dirname "$JAVA_PATH")/$LINK"
      fi
    done
    JAVA_HOME=$(dirname "$(dirname "$JAVA_PATH")")
    echo "$JAVA_HOME"
    return 0
  fi
  
  # 尝试常见路径
  for path in /usr/lib/jvm/* /usr/java/*; do
    if [ -x "$path/bin/java" ]; then
      echo "$path"
      return 0
    fi
  done
  
  echo "未找到Java环境" >&2
  return 1
}

# 查找证书库
find_keystore() {
  local JAVA_HOME=$1
  # 尝试常见位置(不使用数组)
  for path in \
    "$JAVA_HOME/lib/security/cacerts" \
    "$JAVA_HOME/jre/lib/security/cacerts" \
    "/etc/ssl/certs/java/cacerts" \
    "/etc/pki/java/cacerts"; do
    if [ -f "$path" ]; then
      echo "$path"
      return 0
    fi
  done
  
  echo "未找到证书库" >&2
  return 2
}

# 主检查逻辑
JAVA_HOME=$(find_java)
if [ $? -ne 0 ]; then
  exit 1
fi

echo "发现JAVA_HOME: $JAVA_HOME"

KEYSTORE=$(find_keystore "$JAVA_HOME")
if [ $? -ne 0 ]; then
  exit 2
fi

echo "使用证书库: $KEYSTORE"

# 检查CFCA证书
if "$JAVA_HOME/bin/keytool" -list -keystore "$KEYSTORE" -storepass changeit 2>/dev/null | grep -q -i "cfca"; then
  exit 0
else
  exit 3
fi
EOF

  # 处理检查结果
  EXIT_CODE=$?
  case $EXIT_CODE in
    0) echo "✅ 结果: CFCA证书存在" ;;
    1) echo "⚠️ 结果: 未找到Java环境" ;;
    2) echo "⚠️ 结果: 未找到证书库" ;;
    3) echo "⚠️ 结果: CFCA证书不存在" ;;
    *) echo "⚠️ 结果: 检查失败 (错误码: $EXIT_CODE)" ;;
  esac
  echo "----------------------------------------"
}

# 检查所有镜像的CFCA证书
echo "开始检查CFCA证书..."
for IMAGE in $IMAGES; do
  check_cfca "$IMAGE"
done

echo "所有操作完成!!!"

注意事项:

  1. 符号链接解析
  • 脚本现在使用更兼容的方法解析符号链接,适用于各种基础镜像
  • 如果遇到多层符号链接,脚本会递归解析直到找到真实路径
  1. 路径检查
  • 脚本会尝试多个可能的证书库位置,即使 JAVA_HOME 设置正确
  • 包含系统级证书库路径作为备选
  1. 错误处理
  • 每个可能失败的点都有明确的退出代码
  • 输出会显示具体的失败原因和位置

这个修复版脚本应该能够避免之前的语法错误,并在各种环境下正确运行,同时保持原有的功能:获取镜像、拉取镜像、检查Java证书库中的CFCA证书。

如何check k8s集群中所有pod的jre/jdk证书库中是否导入了CFCA根根证书?

#!/bin/bash

namespace="test"
log_file="check_cfca_certs.log"

# 清空或创建日志文件
> "$log_file"

# 获取所有 Pod 名称
pods=$(kubectl get pods -n $namespace -o jsonpath='{.items[*].metadata.name}')

# 存储没有 CFCA 证书的 Pod
no_cfca_pods=()

{
for pod in $pods; do
  pod_has_cfca=false
  echo "===== 检查 Pod: $pod ====="
  
  # 获取容器列表(支持多容器 Pod)
  containers=$(kubectl get pod $pod -n $namespace -o jsonpath='{.spec.containers[*].name}')
  
  for container in $containers; do
    echo "--- 容器: $container ---"
    
    # 1. 获取 JAVA_HOME 环境变量
    java_home=$(kubectl exec $pod -n $namespace -c $container -- sh -c 'echo $JAVA_HOME' 2>/dev/null)
    
    # 2. 如果未设置 JAVA_HOME,尝试通过 which java 推导
    if [ -z "$java_home" ]; then
      java_home=$(kubectl exec $pod -n $namespace -c $container -- sh -c \
        'which java >/dev/null 2>&1 && dirname $(dirname $(readlink -f $(which java)))' 2>/dev/null)
    fi

    # 检查是否找到 JAVA_HOME
    if [ -z "$java_home" ]; then
      echo "未找到 JAVA_HOME,跳过检查"
      continue
    fi

    echo "检测到 JAVA_HOME: $java_home"
    
    # 3. 检查证书库
    certstore_paths=(
      "$java_home/jre/lib/security/cacerts"   # JDK 8 及更早版本
      "$java_home/lib/security/cacerts"       # JDK 9 及以上版本
    )
    
    for certstore in "${certstore_paths[@]}"; do
      # 检查证书文件是否存在
      kubectl exec $pod -n $namespace -c $container -- test -f "$certstore" >/dev/null 2>&1
      if [ $? -ne 0 ]; then
        echo "证书库不存在: $certstore"
        continue
      fi
      
      # 执行证书检查
      echo "检查证书库: $certstore"
      result=$(kubectl exec $pod -n $namespace -c $container -- \
        sh -c "keytool -list -keystore '$certstore' -storepass changeit 2>&1 | grep -i 'cfca'" 2>/dev/null)
      
      if [ -n "$result" ]; then
        echo "发现 CFCA 证书"
        pod_has_cfca=true
      else
        echo "未找到 CFCA 证书"
      fi
    done
  done
  
  # 记录没有 CFCA 证书的 Pod
  if ! $pod_has_cfca; then
    no_cfca_pods+=("$pod")
  fi
done

# 输出没有 CFCA 证书的 Pod 列表
echo "===== 没有 CFCA 证书的 Pod ====="
if [ ${#no_cfca_pods[@]} -eq 0 ]; then
  echo "所有 Pod 都包含 CFCA 证书"
else
  for pod in "${no_cfca_pods[@]}"; do
    echo "$pod"
  done
fi
} | tee -a "$log_file"

echo "检查完成,结果已保存到: $log_file  !!!"

参考

全球顶级商业CA机构(市场主导者)
https://blog.51cto.com/u_16555391/14188944

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容