zoukankan      html  css  js  c++  java
  • Istio安全-证书管理(istio 系列六)

    Istio安全-证书管理

    插入现有CA证书

    本节展示了管理员如何使用现有的根证书来授权istio证书,签发证书和密钥。

    默认情况下,istio的CA会生成一个自签的根证书和密钥,并使用它们签发负载证书。istio的CA也会使用管理员指定的证书和密钥,以及管理员指定的根证书来签发负载证书。本节展示如何将这些证书和密钥插入Istio的CA。

    插入现有证书和密钥

    假设istio的CA需要使用现有的签名证书ca-cert.pem和密钥ca-key.pem,其中 root-cert.pem签发了证书ca-cert.pem,使用 root-cert.pem作为istio负载的根证书。

    在下面的例子中,istio的CA证书(ca-cert.pem)与根证书(root-cert.pem)不同,因此负载无法通过根证书验证工作负载证书,需要使用一个cert-chain.pem来指定信任的证书链,该证书链包含负载和根CA之间的所有中间CA,在此例子中,它包含了istio的CA签名证书,因此cert-chain.pemca-cert.pem相同的。注意,如果ca-cert.pemroot-cert.pem相同,那么ca-chain.pem文件应该是空的。

    这些文件位于samples/certs/目录。

    默认的istio CA安装根据如下命令(如名为cacerts的secret,名为root-cert.pem文件中的根证书,ca-key.pem文件中的istio CA等)预先定义的密钥和文件名,必须使用这些指定的secret和文件名,或在部署istio的时候重新配置istio的CA。

    下面步骤将证书和密钥插入kubernetes的secret中,后续会被istio的CA读取:

    1. 创建一个secret cacerts,包含所有的输入文件ca-cert.pem, ca-key.pem, root-cert.pemcert-chain.pem:

      $ kubectl create namespace istio-system
      $ kubectl create secret generic cacerts -n istio-system --from-file=samples/certs/ca-cert.pem 
          --from-file=samples/certs/ca-key.pem --from-file=samples/certs/root-cert.pem 
          --from-file=samples/certs/cert-chain.pem
      
    2. 使用demo profile部署istio。istio的CA会从挂载的secret文件中读取证书和密钥

      $ istioctl install --set profile=demo
      

    配置示例services

    1. 部署httpbin和sleep示例services

      $ kubectl create ns foo
      $ kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n foo
      $ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n foo
      
    2. 部署一个策略,使得foo命名空间的负载仅接受mutual TLS流量

      $ kubectl apply -n foo -f - <<EOF
      apiVersion: "security.istio.io/v1beta1"
      kind: "PeerAuthentication"
      metadata:
        name: "default"
      spec:
        mtls:
          mode: STRICT
      EOF
      

    校验证书

    本节中会校验插入到CA中的证书是否签发了负载证书。

    1. sleep 20s,等待mTLS检索httpbin的证书链生效。由于CA证书是自签的,因此openssl命令会返回verify error:num=19:self signed certificate in certificate chain错误。

      $ sleep 20; kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c istio-proxy -n foo -- openssl s_client -showcerts -connect httpbin.foo:8000 > httpbin-proxy-cert.txt
      
    2. 解析证书链中的证书

      $ sed -n '/-----BEGIN CERTIFICATE-----/{:start /-----END CERTIFICATE-----/!{N;b start};/.*/p}' httpbin-proxy-cert.txt > certs.pem
      $ awk 'BEGIN {counter=0;} /BEGIN CERT/{counter++} { print > "proxy-cert-" counter ".pem"}' < certs.pem
      
    3. 校验根证书与管理员指定的证书相同

      $ openssl x509 -in samples/certs/root-cert.pem -text -noout > /tmp/root-cert.crt.txt
      $ openssl x509 -in ./proxy-cert-3.pem -text -noout > /tmp/pod-root-cert.crt.txt
      $ diff -s /tmp/root-cert.crt.txt /tmp/pod-root-cert.crt.txt
      Files /tmp/root-cert.crt.txt and /tmp/pod-root-cert.crt.txt are identical
      
    4. 校验CA证书与管理员指定的相同

      $ openssl x509 -in samples/certs/ca-cert.pem -text -noout > /tmp/ca-cert.crt.txt
      $ openssl x509 -in ./proxy-cert-2.pem -text -noout > /tmp/pod-cert-chain-ca.crt.txt
      $ diff -s /tmp/ca-cert.crt.txt /tmp/pod-cert-chain-ca.crt.txt
      Files /tmp/ca-cert.crt.txt and /tmp/pod-cert-chain-ca.crt.txt are identical
      
    5. 校验证书链从根证书到负载证书

      $ openssl verify -CAfile <(cat samples/certs/ca-cert.pem samples/certs/root-cert.pem) ./proxy-cert-1.pem
      ./proxy-cert-1.pem: OK
      

    卸载

    卸载证书cacertfoo以及istio-system命名空间

    $ kubectl delete secret cacerts -n istio-system
    $ kubectl delete ns foo istio-system
    

    Istio的DNS证书管理

    本节展示如何使用 Chiron提供和管理DNS证书,Chiron是一个与istiod相连的轻量型组件,它使用kubernetes的CA API签发证书,无需管理私钥。有如下优势:

    • 与isitod不同,这种方式无需维护签发的私钥,增强了安全性
    • 简化了将根证书分发到TLS客户端。客户端不再需要等到istiod生成并分发其CA证书

    首先使用istioctl安装istio,并配置DNS证书,当istiod启动后会读取该配置

    $ cat <<EOF > ./istio.yaml
    apiVersion: install.istio.io/v1alpha1
    kind: IstioOperator
    spec:
      values:
        global:
          certificates:
            - secretName: dns.example1-service-account
              dnsNames: [example1.istio-system.svc, example1.istio-system]
            - secretName: dns.example2-service-account
              dnsNames: [example2.istio-system.svc, example2.istio-system]
    EOF
    $ istioctl install -f ./istio.yaml
    

    注:使用openshift4.3并没有生成预期的kubernetes secret,参见该issue

    DNS证书的提供和管理

    istio根据用户的配置为DNS证书提供了DNS名字和secret名称。DNS证书由kubernetes CA签发,并根据配置保存到secret中。istio也管理着DNS证书的生命周期,包括证书滚动和重新生成。

    配置DNS证书

    可以在 istioctl install 命令中使用IstioControlPlane用户资源对istio进行配置。dnsNames字段用于设定证书中的DNS名称,secretName字段指定保存证书和密钥的kubernetes secret的名称。

    检查提供的DNS证书

    在配置istio生成DNS证书并保存到secret后,需要校验提供的证书是否能够正确运行。

    为了校验istio前面例子中生成的dns.example1-service-account的DNS证书,以及校验该证书是否包含配置的DNS名称,需要获取kubernetes的secret,解析并对其解码,查看其具体内容:

    $ kubectl get secret dns.example1-service-account -n istio-system -o jsonpath="{.data['cert-chain.pem']}" | base64 --decode | openssl x509 -in /dev/stdin -text -noout
    

    输出的文本包括:

    X509v3 Subject Alternative Name:
        DNS:example1.istio-system.svc, DNS:example1.istio-system
    

    重新生成DNS证书

    istio可以在DNS证书被错删的情况下重新生成证书。

    1. 删除前面保存的DNS证书

      $ kubectl delete secret dns.example1-service-account -n istio-system
      
    2. 校验istio重新生成了删除的DNS证书,且证书包含配置的DNS名称。需要从kubernetes获取secret,解析并对其解码,获取其内容:

      $sleep 10; kubectl get secret dns.example1-service-account -n istio-system -o jsonpath="{.data['cert-chain.pem']}" | base64 --decode | openssl x509 -in /dev/stdin -text -noout
      

    输出包括

    X509v3 Subject Alternative Name:
        DNS:example1.istio-system.svc, DNS:example1.istio-system
    

    卸载

    $ kubectl delete ns istio-system
    
  • 相关阅读:
    leetcode 63 简单题
    leetcode 712
    500 问的数学基础
    转载一份kaggle的特征工程:经纬度、特征构造、转化率
    散度
    在线学习在CTR上应用的综述
    广告的计费方式
    矩阵2范数与向量2范数的关系
    text_CNN笔记
    F1
  • 原文地址:https://www.cnblogs.com/charlieroro/p/13299942.html
Copyright © 2011-2022 走看看