插入外部 CA 密钥和证书

本任务展示运维人员如何使用现有根证书配置 Citadel 进行证书以及密钥的签发。

缺省情况下 Citadel 生成自签署的根证书和密钥,用于给工作负载签署证书。Citadel 还可以使用运维人员指定的根证书、证书和密钥进行工作负载的证书颁发。该任务所演示了向 Citadel 插入外部证书和密钥的方法。

开始之前

  • 根据 quick start 内容,安装 Istio 并启用双向 TLS:
  1. $ kubectl apply -f install/kubernetes/istio-demo-auth.yaml

或者

使用 Helm 并设置 global.mtls.enabledtrue.

从 Istio 0.7 开始,可以使用认证策略来给命名空间中全部/部分服务配置双向 TLS 功能。(在所有命名空间中重复此操作,就相当于全局配置了)。这部分内容可参考认证策略任务

插入现有密钥和证书

假设我们想让 Citadel 使用现有的 ca-cert.pem 证书和 ca-key.pem,其中 ca-cert.pem 是由 root-cert.pem 根证书签发的,我们也准备使用 root-cert.pem 作为 Istio 工作负载的根证书。

下面的例子中,Citadel 的签署(CA)证书(root-cert.pem)不同于根证书(root-cert.pem),因此工作负载无法使用根证书进行证书校验。工作负载需要一个 cert-chain.pem 文件作为信任链,其中需要包含所有从根证书到工作负载证书之间的中间 CA。在我们的例子中,他包含了 Citadel 的签署证书,所以 cert-chain.pemca-cert.pem 是一致的。注意如果你的 ca-cert.pemca-cert.pem 是一致的,那么 cert-chain.pem 就是个空文件了。

这些文件都会在 samples/certs/ 目录中准备就绪提供使用。

下面的步骤在 Citadel 中插入了证书和密钥:

  • 创建一个名为 cacert 的 secret,其中包含所有输入文件 ca-cert.pemca-key.pemroot-cert.pem 以及 cert-chain.pem
  1. $ kubectl create secret generic cacerts -n istio-system --from-file=samples/certs/ca-cert.pem \
  2. --from-file=samples/certs/ca-key.pem --from-file=samples/certs/root-cert.pem \
  3. --from-file=samples/certs/cert-chain.pem
  • 使用 Helm 重新部署 Citadel,其中 global.mtls.enabled 设置为 truesecurity.selfSigned 设置为 false 。Citadel 将从 secret-mount 文件中读取证书和密钥。
  1. $ helm template install/kubernetes/helm/istio --name istio --namespace istio-system -x charts/security/templates/deployment.yaml \
  2. --set global.mtls.enabled=true --set security.selfSigned=false > $HOME/citadel-plugin-cert.yaml
  3. $ kubectl apply -f $HOME/citadel-plugin-cert.yaml
  • 为了确定工作负载获取了正确的证书,删除 Citadel 生成的 Secret(命名为 istio.*)。在本例中就是 istio.default。Citadel 会签发新的证书给工作负载。
  1. $ kubectl delete secret istio.default

检查新证书

本节中,我们要校验新的工作负载证书以及根证书是否正确传播。需要在本机安装 openssl

  • 根据部署文档安装 Bookinfo 应用。

  • 获取已加载的证书。下面我们使用 ratings pod 作为例子,检查这个 Pod 上加载的证书。

用变量 RATINGSPOD 保存 Pod 名称:

  1. $ RATINGSPOD=`kubectl get pods -l app=ratings -o jsonpath='{.items[0].metadata.name}'`

运行下列命令,获取 proxy 容器中加载的证书:

  1. $ kubectl exec -it $RATINGSPOD -c istio-proxy -- /bin/cat /etc/certs/root-cert.pem > /tmp/pod-root-cert.pem

/tmp/pod-root-cert.pem 文件中包含传播到 Pod 中的根证书。

  1. $ kubectl exec -it $RATINGSPOD -c istio-proxy -- /bin/cat /etc/certs/cert-chain.pem > /tmp/pod-cert-chain.pem

/tmp/pod-cert-chain.pem 这个文件则包含了工作负载证书以及传播到 Pod 中的 CA 证书

  • 检查根证书和运维人员指定的证书是否一致:

Zip

  1. $ openssl x509 -in @samples/certs/root-cert.pem@ -text -noout > /tmp/root-cert.crt.txt
  2. $ openssl x509 -in /tmp/pod-root-cert.pem -text -noout > /tmp/pod-root-cert.crt.txt
  3. $ diff /tmp/root-cert.crt.txt /tmp/pod-root-cert.crt.txt

输出为空代表符合预期。

  • 检查 CA 证书和运维人员指定的是否一致

Zip

  1. $ tail -n 22 /tmp/pod-cert-chain.pem > /tmp/pod-cert-chain-ca.pem
  2. $ openssl x509 -in @samples/certs/ca-cert.pem@ -text -noout > /tmp/ca-cert.crt.txt
  3. $ openssl x509 -in /tmp/pod-cert-chain-ca.pem -text -noout > /tmp/pod-cert-chain-ca.crt.txt
  4. $ diff /tmp/ca-cert.crt.txt /tmp/pod-cert-chain-ca.crt.txt

输出为空代表符合预期。

  • 检查从根证书到工作负载证书的证书链:

ZipZip

  1. $ head -n 21 /tmp/pod-cert-chain.pem > /tmp/pod-cert-chain-workload.pem
  2. $ openssl verify -CAfile <(cat @samples/certs/ca-cert.pem@ @samples/certs/root-cert.pem@) /tmp/pod-cert-chain-workload.pem
  3. /tmp/pod-cert-chain-workload.pem: OK

清理

  • 移除 secret cacerts:
  1. $ kubectl delete secret cacerts -n istio-system
  • 移除 Istio 组件:
  1. $ kubectl delete -f install/kubernetes/istio-demo-auth.yaml

相关内容

基于 Istio 的 Micro-Segmentation 授权

描述 Istio 的授权功能以及如何在各种用例中使用它。

Citadel 的健康检查

如何在 Kubernetes 中启用 Citadel 的健康检查。

HTTP 服务的访问控制

展示为 HTTP 服务设置基于角色的访问控制方法。

Istio Service 健康检查

展示如何对 Istio service 进行健康检查。

Istio Vault CA 集成

有关如何整合 Vault CA 到 Istio 中颁发证书的教程。

TCP 服务的访问控制

展示如何为 TCP 服务设置基于角色的访问控制。