Istio安全-证书管理

注:本章更新至1.8版本

插入现有CA证书

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

默认情况下,istio的CA会生成一个自签的根证书和密钥,并使用它们签发负载证书。istio的CA也可以使用管理员指定的证书和密钥,以及管理员指定的根证书来签发负载证书。

根CA是网格中所有负载信任的根证书。每个Istio CA会使用一个中间CA来签发密钥和证书,该CA由根CA签发。当一个网格中存在多个Istio CA时,会在CA之间建立起信任层级。

本节展示如何将这些证书和密钥插入Istio的CA。

插入现有证书和密钥

在istio的samples/certs目录下有一套证书,可以比较好地解释istio的证书交互原理。

  • root-cert.pem: root CA certificate.
  • ca-[cert|key].pem: Citadel intermediate certificate and corresponding private key.
  • cert-chain.pem: certificate trust chain.
  • workload-foo-[cert|key].pem: workload certificate and key for URI SAN spiffe://trust-domain-foo/ns/foo/sa/foo signed by ca-cert.key.
  • workload-bar-[cert|key].pem: workload certificate and key for URI SAN spiffe://trust-domain-bar/ns/bar/sa/bar signed by ca-cert.key.

假如希望使用现有的CA证书ca-cert.pemca-key.pem(root-cert.pem签发了ca-cert.pem,因此root-cert.pem作为所有负载的根证书)。由于ca-cert.pem不同于root-cert.pem,因此无法直接通过根证书进行校验,此时需要通过一个cert-chain.pem来指定信任链,包含负载到根CA的所有中间CAs。在上述例子中,仅包含了istio的CA签名证书,因此cert-chain.pemca-cert.pem相同。注意:如果 ca-cert.pemroot-cert.pem是相同的,那么 cert-chain.pem文件应该是空的。

上述证书例子中的证书链为:root-cert.pem-->cert-chain.pem(含ca-cert.pem)-->workload-foo-cert.pem/workload-bar-cert.pem,可以使用如下方式进行校验:

# openssl verify -CAfile <(cat ca-cert.pem root-cert.pem) workload-bar-cert.pem
workload-bar-cert.pem: OK

对于生产环境,最好在一台离线机器上执行如下步骤,确保将根密钥暴露给尽可能少的人

  1. 创建一个保存证书和密钥的目录

    $ mkdir -p certs
    $ pushd certs
  2. 生成根证书和密钥

    $ make -f ../tools/certs/Makefile.selfsigned.mk root-ca

    上述命令将生成如下文件:

    • root-cert.pem: 根证书
    • root-key.pem: 根密钥
    • root-ca.conf: openssl 使用该配置来生成根证书
    • root-cert.csr: 为根证书生成的CSR
  3. 生成中间证书和密钥

    $ make -f ../tools/certs/Makefile.selfsigned.mk cluster1-cacerts

    执行如上命令会生成一个名为cluster1的目录,包含如下文件,root-cert.pem签发了ca-cert.pem

    • ca-cert.pem: 中间证书
    • ca-key.pem: 中间密钥
    • cert-chain.pem: Istiod使用的证书链
    • root-cert.pem: 根证书
    • intermediate.conf: openssl 使用该配置来生成中间证书
    • cluster-ca.csr: 为中间证书生成的CSR

    可以将cluster1替换为任何字符串。例如make mycluster-certs将会生成名为mycluster的目录

    为了配置其他Istio CA,可以重复执行上述步骤来生成不同名称的证书目录

  4. 创建一个cacerts secret,包含如下输入文件ca-cert.pem, ca-key.pem, root-cert.pemcert-chain.pem。需要注意的是创建出来的secret的名称必须是cacerts,这样才能被istio正确挂载。

    $ kubectl create namespace istio-system
    $ kubectl create secret generic cacerts -n istio-system \
    --from-file=cluster1/ca-cert.pem \
    --from-file=cluster1/ca-key.pem \
    --from-file=cluster1/root-cert.pem \
    --from-file=cluster1/cert-chain.pem
  5. 返回Istio安装的顶层目录

    $ popd

部署Istio

使用demo profile,Istio会从挂载的secret文件中读取证书

$ istioctl install --set profile=demo

在下面的例子中,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文件应该是空的。

配置示例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:
meshConfig:
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

可以看到在istio-system下生成了两个secret:

# kubectl get secret -n istio-system |grep dns
dns.example1-service-account istio.io/dns-key-and-cert 3 81s
dns.example2-service-account istio.io/dns-key-and-cert 3 81s

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

Istio安全-证书管理(实操一)的更多相关文章

  1. Istio的流量管理(实操一)(istio 系列三)

    Istio的流量管理(实操一)(istio 系列三) 使用官方的Bookinfo应用进行测试.涵盖官方文档Traffic Management章节中的请求路由,故障注入,流量迁移,TCP流量迁移,请求 ...

  2. Istio的流量管理(实操二)(istio 系列四)

    Istio的流量管理(实操二)(istio 系列四) 涵盖官方文档Traffic Management章节中的inrgess部分. 目录 Istio的流量管理(实操二)(istio 系列四) Ingr ...

  3. Istio的流量管理(实操三)

    Istio的流量管理(实操三) 涵盖官方文档Traffic Management章节中的egress部分.其中有一小部分问题(已在下文标注)待官方解决. 目录 Istio的流量管理(实操三) 访问外部 ...

  4. Istio安全-授权(实操三)

    Istio安全-授权 目录 Istio安全-授权 授权HTTP流量 为使用HTTP流量的负载配置访问控制 卸载 授权TCP流量 部署 配置TCP负载的访问控制 卸载 使用JWT进行授权 部署 使用有效 ...

  5. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  6. 号外号外:9月13号《Speed-BI云平台案例实操--十分钟做报表》开讲了

    引言:如何快速分析纷繁复杂的数据?如何快速做出老板满意的报表?如何快速将Speed-BI云平台运用到实际场景中?         本课程将通过各行各业案例背景,将Speed-BI云平台运用到实际场景中 ...

  7. Mysql MHA(GTID)配置(实操)

    实现环境 centos6.7 MYSQL5.6.36 主:192.168.1.191 从1:192.168.1.145 从2:192.168.1.146 监测:放在从2上 192.168.1.146 ...

  8. Selenium之unittest测试框架详谈及实操

    申明:本文是基于python3.x及selenium3.x. unittest,也可以称为PyUnit,可以用来创建全面的测试套件,可以用于单元自动化测试(模块).功能自动化测试(UI)等等. 官方文 ...

  9. unittest测试框架详谈及实操(二)

    类级别的setUp()方法与tearDown()方法 在实操(一)的例子中,通过setUp()方法为每个测试方法都创建了一个Chrome实例,并且在每个测试方法执行结束后要关闭实例.是不是觉得有个多余 ...

随机推荐

  1. CSS3 Animation & linear-gradient & css3 var & @keyframes

    CSS3 Animation & linear-gradient & css3 var & @keyframes https://www.zhangxinxu.com/word ...

  2. taro external-class

    taro external-class https://nervjs.github.io/taro/docs/component-style.html externalClasses child co ...

  3. Techme INC:红光和近红外光疗法有效加速肌肉恢复,美国橄榄球队已采用

    Techme INC创始人兼董事长MADELEINE VAUGHAN表示:在运动结束后,肌肉纤维因为细微损伤造成酸痛情形,即是延迟性肌肉酸痛-DOMS.这类酸痛发生时,需要适度的恢复,避免造成肌肉拉伤 ...

  4. 离场定高转弯DF与CF的对比

    也许是刚学会CAD的缘故,配合风螺旋插件,画图的感觉真是蛮爽的,忍不住画了一张又一张. 接着昨天的离场保护区,我们来聊一下PBN指定高度转弯保护区的画法.指定高度转弯的计算本身没有太多复杂的地方,真正 ...

  5. ImageCombiner - Java服务端图片合成的工具包,好用!

    自己的第一个也是唯一一个开源项目,因为平时比较懒,很少做宣传,今天刚好突破160个star,发到园子里推荐给大家,算是庆祝一下,哈. 项目地址:https://gitee.com/opensource ...

  6. 无情面试官之包含min函数的栈

    0 我是一个无情的面试官. 面人无数,挂人无数. 若想过我的面试,标准只有一个,那就是公司很缺人. 招新人,填旧坑. 1 今天是我的第1001次当面试官,要求却不是千里挑一,而是一击必中. 因为我招聘 ...

  7. 如何在Pycharm中自动添加时间日期、作者等信息

    参考下面的内容 #_author_='Lucky';#date: ${DATE}

  8. nginx判断状态脚本

    A是nginx行数 为0则启动nginx 启动失败则杀死keepalived进程

  9. css中a元素放长英文字母或者数字自动换行的解决

    在做链接分享页面的时候遇到a元素中的下载链接长英文溢出不换行的问题 在给他以及他父元素设置宽度依然没有解决这个问题 最后解决办法给元素加上word-wrap:break-word 解释:使用break ...

  10. Bitter.NotifyOpenPaltform : HTTP 异步消息接收调度中心--开源贡献 之 一:简介

    现在互联网的系统越来越趋向于复杂,从单体系统到现在的微服务体系演变.公司与公司的分工也越来越明确. 大数据公司提供了大数据服务 人脸识别公司提供了人脸识别服务 OCR 公司提供了专业的OCR 服务 车 ...