• 十二张图:从0开始理解对称/非对称加密、CA认证、以及K8S各组件颁发证书原由


    一、对称加密

    对称加密的过程类似下图中,通信的双方约定好使用统一的加密解密算法,以及一个salt盐作为唯一标识,发送数据前先试用加密算法和salt经过加密函数处理得到密文,接受方收到密文后使用解密算法+salt对密文解密得到明文再处理。

    二、对称加密-不安全

    对称加密的缺陷如黑客可能会枚举出对称加密算法,而且salt是唯一的,不会为不同的服务创建不同的salt。

    一旦出现信息泄漏,很可能出现如下情况:客户端和服务端之间的数据被黑客窃取并篡改,再将篡改后的数据发给服务端,因为黑客知道完整的加解密方法和salt,所以他能瞒天过海。

    三、非对称加密

    非对称加密涉及到了:公钥和私钥

    特点是:

    • 特性1:使用公钥加密的数据只有私钥才能解密,公钥自己是解密不了的。
    • 特性2:使用私钥加密的数据只有公钥才能解密,私钥自己是解密不了的。
    • 服务端同时持有公钥和私钥(不会给任何人)。
    • 服务端要跟谁通信就把自己的公钥给它。

    使用非对称加密的交互的过程如下:客户端先拿到服务端的公钥,然后使用这个公钥加密数据,再把加密后的数据发送给服务端,由于上面说的特性1、2,这时只有服务端才能正确的解密出数据。

    四、非对称加密-不安全

    如下红色部分,服务端发送给客户端的数据如果使用公钥加密,那么客户端肯定解密不了,看起来它只能使用私钥加密,这时客户端可以使用之前获取到的公钥解密。

    但是问题是所有人都能获取到服务端的公钥,包括黑客。所以黑客也能解密出服务端发送过来的数据。

    五、对称加密和非对称加密结合

    两者结合的方式如下,客户端先获取到服务端的公钥,然后自己生成一个唯一的随机密钥A,使用公钥加密随机密钥A,这时只有服务端的私钥才能解密出随机密钥A,所以即便被加密的随机密钥A被黑客截获它也解密不出啥。

    服务端拿到随机密钥A之后,服务端和客户端双方约定从此之后双方的交互使用随机密钥A做对车加密的salt,全球只有他俩知道,所以很安全。

    六、对称加密和非对称加密结合-不安全

    如下图这样,假设黑客很厉害他有自己的公钥和私钥,而且从一开始就截取了客户端的请求,然后自己冒充服务端,在客户端和服务端的交互过程中全程充当一个代理的存在,这样黑客依然能获取到双方交互的所有数据。

    简而言之这个问题就出在:客户端太信任他拿到的公钥了

    七、Https的做法-引入CA机构

    为了解决上面说到的:客户端太信任他拿到的公钥问题,引入了第三方的CA机构。

    CA机构出现之后,所有人就约定:我们只相信被CA机构信任的公钥(也就是下面说到的证书)

    可以直接看上图,CA机构有自己的公钥和私钥,大家绝对信任CA认证机构,让他做安全方面的背书。

    这时黑客再想插进入比如偷偷替换服务端的公钥,那不好意思,客户端只相信权威机构的公钥能解析的证书。即便黑客自己也有CA机构颁发给他自己的证书,客户端也不会认,因为证书是和域名绑定的,而域名是唯一的。

    八、乘胜追击理解K8S的中的证书

    为了大家更好的理解,我特意化了下面这张图。

    相信很多小伙伴自己安装K8S集群的时候,莫名其妙的就得为各个组件安装一大堆不知所然

    这个问题不是很复杂,那我们随便唠叨几句。

    你看上图:ApiServer、Controller Manager、Scheduler有一对自己的公钥(CA给签发的证书/自签证书)和私钥,而像kubelet这种只要有CA认证机构的公钥匙证书就行。

    原因是kubelet作为一个客户端、ApiServer作为服务端,他们之间的关系和校权差不多可以按下面这张图理解(看图是不是很好理解??)

    然后我们实践一下这个过程,首先是证书是有CA认证机构签发的,是要花钱买的,为了不破费,一般我们自己玩K8S都是使用cfssl做自签证书。

    • Step1:所以第一步下载cfssl工具,借助它的能力模拟CA机构的能力
    wget "https://pkg.cfssl.org/R1.2/cfssl_linux-amd64" -O /usr/local/bin/cfssl
    wget "https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64" -O /usr/local/bin/cfssljson
    chmod +x /usr/local/bin/cfssl /usr/local/bin/cfssljson
    
    • Step2:初始化我们的根证书
    $ cfssl gencert -initca ca-csr.json | cfssljson -bare /etc/kubernetes/pki/ca
    
    # ca-csr.json文件长下面这样(里面有过期时间,签发机构的基础信息)
    {
      "CN": "kubernetes",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "names": [
        {
          "C": "CN",
          "ST": "Beijing",
          "L": "Beijing",
          "O": "Kubernetes",
          "OU": "Kubernetes-manual"
        }
      ],
      "ca": {
        "expiry": "876000h"
      }
    }
    

    这一步相当于我们家自己开了个CA签发公司,经过如上的命令我们能得到下面的三个证书文件,分别是

    ca-key.pem:可以理解成CA签发机构的私钥(绝对不能泄漏,不然CA机构将毫无存在的意义)

    ca.pem:可以理解成CA签发机构的公钥,可以给任何人

    ca.csr:证书请求文件

    • Step3:给ApiServer颁发证书

    首先给ApiServer颁发证书并不难理解,本质上就是ApiServer提供给CA机构一个公钥,然后CA机构用自己的私钥对ApiServer的公钥进行加密,得到一个证书文件。

    其次是我们为啥要给ApiServer颁发证书?

    原因是在启动apiserver的时候启动参数需要如下:(要自己的公私钥和ca机构的公钥)

    然后就是对于ApiServer来说,他想让CA机构给他颁发证书,它得提供一个csr证书请求文件,一般长下面这样

    #  apiserver-csr.json 这里面描述了加密算法、请求者机构基础信息
    {
      "CN": "kube-apiserver",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "names": [
        {
          "C": "CN",
          "ST": "Beijing",
          "L": "Beijing",
          "O": "Kubernetes",
          "OU": "Kubernetes-manual"
        },
       "hosts": [
            "127.0.0.1",
            "192.168.0.1",
            "kubernetes.default",
            "kubernetes.default.svc",
            "kubernetes.default.svc.cluster",
            "kubernetes.default.svc.cluster.local",
            "10.10.10.12",
            "10.10.10.13",
            "10.10.10.14",
            "10.10.10.15"
        ],
      ]
    }
    
    • Step4:然后CA机构为ApiServer颁发证书

    对于我们自己家开的CA机构来说,执行如下命令即可完成证书的颁发

    cfssl gencert   \ 
          -ca=/etc/kubernetes/pki/ca.pem  \
          -ca-key=/etc/kubernetes/pki/ca-key.pem   \
          -config=ca-config.json   \
          -profile=kubernetes  \
          apiserver-csr.json | cfssljson -bare /etc/kubernetes/pki/apiserver
    

    然后我们解析一个各参数的含义

    1. apiserver-csr.json:是有step3中提到的,谁想让CA机构给他颁发证书,谁就得提供csr文件
    2. ca:我们自己家CA机构的公钥,step2中生成了。
    3. ca-key:我们自己家CA机构的私钥,step2中生成了。
    4. profile:指定使用config中的哪个usage。
    5. config:一版长下面这样,里面定义了证书的有效时间、还有一些usage
    {
      "signing": {
        "default": {
          "expiry": "876000h"
        },
        "profiles": {
          "kubernetes": {
            "usages": [
                "signing",
                "key encipherment",
                "server auth", # 表示client可以用该 CA 对server提供的证书进行验证;
                "client auth"  # 表示server可以用该CA对client提供的证书进行验证;
            ],
            "expiry": "876000h"
          }
        }
      }
    }
    

    命令执行之后我们就能得到为apiserver的颁发的证书了

    同样的,对与ApiServer来说,它的公钥证书apiserver.pem可以给任何人,但是它的私钥apiserver-key.pem只有自己持有。

    九、文末

    本文到这里就行将结束了,欢迎大家关注~

    公众号首发:https://mp.weixin.qq.com/s/RbvonLcS_mHza87bPkNdsQ
    公众号首发:https://mp.weixin.qq.com/s/RbvonLcS_mHza87bPkNdsQ
    公众号首发:https://mp.weixin.qq.com/s/RbvonLcS_mHza87bPkNdsQ

    参考:https://cloud.tencent.com/developer/article/1802714

  • 相关阅读:
    ThinkPHP 3.2.2 实现持久登录 ( 记住我 )
    Java实现 LeetCode 20 有效的括号
    Java实现 LeetCode 20 有效的括号
    Java实现 LeetCode 19删除链表的倒数第N个节点
    Java实现 LeetCode 19删除链表的倒数第N个节点
    Java实现 LeetCode 19删除链表的倒数第N个节点
    Java实现 LeetCode 18 四数之和
    Java实现 LeetCode 18 四数之和
    Java实现 LeetCode 18 四数之和
    Java实现 LeetCode 17 电话号码的字母组合
  • 原文地址:https://www.cnblogs.com/ZhuChangwu/p/16345050.html
Copyright © 2020-2023  润新知