巧用 CFSSL 管理 Kubernetes 集群证书

系统 Linux
HTTP 是一个网络协议,是专门用来传输 Web 内容,大部分网站都是通过 HTTP 协议来传输 Web 页面、以及 Web 页面上包含的各种东东(图片、CSS 样式、JS 脚本)。

 

熟悉HTTP、HTTPS、SSL、TLS

HTTP 是一个网络协议,是专门用来传输 Web 内容,大部分网站都是通过 HTTP 协议来传输 Web 页面、以及 Web 页面上包含的各种东东(图片、CSS 样式、JS 脚本)。

SSL 是Secure Sockets Layer的缩写,中文叫做“安全套接层”。它是在上世纪90年代中期,由网景公司设计的。(顺便插一句,网景公司不光发明了 SSL,还发明了很多 Web 的基础设施——比如CSS 样式表和JS 脚本),为啥要发明 SSL 这个协议捏?因为原先互联网上使用的 HTTP 协议是明文的,存在很多缺点——比如传输内容会被偷窥(嗅探)和篡改。发明 SSL 协议,就是为了解决这些问题。

TLS是 SSL的 标准化,SSL标准化之后的名称改为 TLS(是Transport Layer Security的缩写),中文叫做传输层安全协议。很多相关的文章都把这两者并列称呼(SSL/TLS),因为这两者可以视作同一个东西的不同阶段。

HTTPS 协议,说白了就是“HTTP 协议”和“SSL/TLS 协议”的组合。你可以把 HTTPS 大致理解为——HTTP over SSL或HTTP over TLS。

CA认证的原理

通过下面介绍信的描述介绍CA的原理

◇ 普通的介绍信

想必大伙儿都听说过介绍信的例子吧?假设 A 公司的张三先生要到 B 公司去拜访,但是 B 公司的所有人都不认识他,他咋办捏?常用的办法是带公司开的一张介绍信,在信中说:兹有张三先生前往贵公司办理业务,请给予接洽......云云。然后在信上敲上A公司的公章。

张三先生到了 B 公司后,把介绍信递给 B 公司的前台李四小姐。李小姐一看介绍信上有 A 公司的公章,而且 A 公司是经常和 B 公司有业务往来的,这位李小姐就相信张先生不是歹人了。

这里,A公司就是CA证书

◇ 引入中介机构的介绍信

好,回到刚才的话题。如果和 B 公司有业务往来的公司很多,每个公司的公章都不同,那前台就要懂得分辨各种公章,非常滴麻烦。所以,有某个中介公司 C,发现了这个商机。C公司专门开设了一项“代理公章”的业务。

今后,A 公司的业务员去 B 公司,需要带2个介绍信:

介绍信1:含有 C 公司的公章及 A 公司的公章。并且特地注明:C 公司信任 A 公司。

介绍信2:仅含有 A 公司的公章,然后写上:兹有张三先生前往贵公司办理业务,请给予接洽......云云。

某些不开窍的同学会问了,这样不是增加麻烦了吗?有啥好处捏?

主要的好处在于,对于接待公司的前台,就不需要记住各个公司的公章分别是啥样子的;他/她只要记住中介公司 C 的公章即可。当他/她拿到两份介绍信之后,先对介绍信1的 C 公章,验明正身;确认无误之后,再比对介绍信1和介绍信2的两个 A 公章是否一致。如果是一样的,那就可以证明介绍信2是可以信任的了。

公钥基础设施PKI

CA(Certification Authority)证书,指的是权威机构给我们颁发的证书。

密钥就是用来加解密用的文件或者字符串。密钥在非对称加密的领域里,指的是私钥和公钥,他们总是成对出现,其主要作用是加密和解密。常用的加密强度是2048bit。

RSA即非对称加密算法。非对称加密有两个不一样的密码,一个叫私钥,另一个叫公钥,用其中一个加密的数据只能用另一个密码解开,用自己的都解不了,也就是说用公钥加密的数据只能由私钥解开。

证书的编码格式

PEM(Privacy Enhanced Mail),通常用于数字证书认证机构(Certificate Authorities,CA),扩展名为.pem, .crt, .cer, 和 .key。内容为Base64编码的ASCII码文件,有类似的头尾标记服务器认证证书。 

  1. "-----BEGIN CERTIFICATE-----"  
  2. "-----END CERTIFICATE-----" 

中级认证证书和私钥都可以储存为PEM格式(认证证书其实就是公钥)。Apache 和 Nginx 等类似的服务器使用PEM格式证书。

DER(Distinguished Encoding Rules),与 PEM 不同之处在于其使用二进制而不是 Base64 编码的 ASCII。扩展名为.der,但也经常使用.cer用作扩展名,所有类型的认证证书和私钥都可以存储为 DER 格式。Java 使其典型使用平台。

证书签名请求 CSR

CSR(Certificate Signing Request),它是向 CA 机构申请数字 ××× 书时使用的请求文件。在生成请求文件前,我们需要准备一对对称密钥。私钥信息自己保存,请求中会附上公钥信息以及国家,城市,域名,Email 等信息,CSR 中还会附上签名信息。当我们准备好 CSR 文件后就可以提交给CA机构,等待他们给我们签名,签好名后我们会收到 crt 文件,即证书。

注意:CSR 并不是证书。而是向权威证书颁发机构获得签名证书的申请。

把 CSR 交给权威证书颁发机构,权威证书颁发机构对此进行签名,完成。保留好CSR,当权威证书颁发机构颁发的证书过期的时候,你还可以用同样的CSR来申请新的证书, Key 保持不变.

数字签名

数字签名就是"非对称加密+摘要算法",其目的不是为了加密,而是用来防止他人篡改数据。

其核心思想是:比如A要给B发送数据,A先用摘要算法得到数据的指纹,然后用A的私钥加密指纹,加密后的指纹就是A的签名,B收到数据和A的签名后,也用同样的摘要算法计算指纹,然后用A公开的公钥解密签名,比较两个指纹,如果相同,说明数据没有被篡改,确实是A发过来的数据。假设C想改A发给B的数据来欺骗B,因为篡改数据后指纹会变,要想跟A的签名里面的指纹一致,就得改签名,但由于没有A的私钥,所以改不了,如果C用自己的私钥生成一个新的签名,B收到数据后用A的公钥根本就解不开。

常用的摘要算法有MD5、SHA1、SHA256。

使用私钥对需要传输的文本的摘要进行加密,得到的密文即被称为该次传输过程的签名。

数字证书和公钥

数字证书则是由证书认证机构(CA)对证书申请者真实身份验证之后,用CA的根证书对申请人的一些基本信息以及申请人的公钥进行签名(相当于加盖发证书机 构的公章)后形成的一个数字文件。实际上,数字证书就是经过CA认证过的公钥,除了公钥,还有其他的信息,比如Email,国家,城市,域名等。

CFSSL安装及基础知识

cfssl是CloudFlare开源的一款PKI/TLS工具。CFSSL 包含一个命令行工具和一个用于签名、验证并且捆绑TLS证书的HTTP API 服务。使用Go语言编写。

CFSSL包括:

  •   一组用于生成自定义 TLS PKI 的工具
  •  cfssl程序,是cfssl的命令行工具
  •  multirootca程序是可以使用多个签名密钥的证书颁发机构服务器
  •  mkbundle程序用于构建证书池
  •  cfssljson程序,从cfssl和multirootca程序获取JSON输出,并将证书,密钥,CSR和bundle写入磁盘

PKI借助数字证书和公钥加密技术提供可信任的网络身份。通常,证书就是一个包含如下身份信息的文件:

  •  证书所有组织的信息
  •  公钥
  •  证书颁发组织的信息
  •  证书颁发组织授予的权限,如证书有效期、适用的主机名、用途等
  •  使用证书颁发组织私钥创建的数字签名

安装 cfssl

这里我们只用到cfssl工具和cfssljson工具 

  1. # curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl  
  2. # curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson  
  3. # curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o /usr/local/bin/cfssl-certinfo  
  4. # chmod +x /usr/local/bin/cfssl* 

cfssl 常用子命令介绍 

  1. bundle: 创建包含客户端证书的证书包  
  2. genkey: 生成一个key(私钥)和CSR(证书签名请求)  
  3. scan: 扫描主机问题  
  4. revoke: 吊销证书  
  5. certinfo: 输出给定证书的证书信息, 跟cfssl-certinfo 工具作用一样  
  6. gencrl: 生成新的证书吊销列表  
  7. selfsign: 生成一个新的自签名密钥和 签名证书  
  8. print-defaults: 打印默认配置,这个默认配置可以用作模板  
  9. serve: 启动一个HTTP API服务  
  10. gencert: 生成新的key(密钥)和签名证书  
  11.  -ca:指明ca的证书  
  12.  -ca-key:指明ca的私钥文件  
  13.  -config:指明请求证书的json文件  
  14.  -profile:与-config中的profile对应,是指根据config中的profile段来生成证书的相关信息  
  15. ocspdump: 从cert db 中的所有 OCSP 响应中生成一系列连贯的 OCSP 响应,供 ocspserve 使用  
  16. ocspsign: 为给定的CA、Cert和状态签署OCSP响应。返回一个base64编码的OCSP响应  
  17. info: 获取有关远程签名者的信息  
  18. sign: 签名一个客户端证书,通过给定的CA和CA密钥,和主机名  
  19. ocsprefresh: 用所有已知未过期证书的新OCSP响应刷新ocsp_responses表。  
  20. ocspserve: 设置一个HTTP服务器,处理来自文件或直接来自数据库的OCSP请求(见RFC 5019)。 

常用命令 

  1. $ cfssl gencert -initca ca-csr.json | cfssljson -bare ca ## 初始化ca  
  2. $ cfssl gencert -initca -ca-key key.pem ca-csr.json | cfssljson -bare ca ## 使用现有私钥, 重新生成  
  3. $ cfssl certinfo -cert ca.pem  
  4. $ cfssl certinfo -csr ca.csr 

使用 CFSSL 创建 CA 认证步骤

创建认证中心(CA)

cfssl 可以创建一个获取和操作证书的内部认证中心。运行认证中心需要一个 CA 证书和相应的 CA 私钥。任何知道私钥的人都可以充当CA来颁发证书。因此,私钥的保护至关重要,这里我们以 k8s 所需的证书来实践一下: 

  1. $ cfssl print-defaults config > config.json # 默认证书策略配置模板  
  2. $ cfssl print-defaults csr > csr.json #默认csr请求模板 

结合自身的要求,修改证书请求文件csr.json,证书10年 

  1.  
  2.   "CN": "kubernetes",  
  3.   "key": {  
  4.     "algo": "rsa",  
  5.     "size": 2048  
  6.   },  
  7.   "names": [  
  8.     {  
  9.       "C": "CN",  
  10.       "ST": "BeiJing",  
  11.       "L": "BeiJing",  
  12.       "O": "k8s",  
  13.       "OU": "System"  
  14.     }  
  15.    ],  
  16.    "ca": {  
  17.     "expiry": "87600h"  
  18.   }  

知识点 :

  •  "CN":Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name)
  •  "O":Organization,kube-apiserver从证书中提取该字段作为请求用户所属的组 (Group)
  •  C: Country, 国家
  •  L: Locality,地区,城市
  •  O: Organization Name,组织名称,公司名称
  •  OU: Organization Unit Name,组织单位名称,公司部门
  •  ST: State,州,省

证书配置模板文件ca-config.json 

  1.  
  2.   "signing": {  
  3.       "default": {  
  4.         "expiry": "87600h"  
  5.    },  
  6.   "profiles": {  
  7.     "kubernetes": {  
  8.       "usages": [  
  9.         "signing",  
  10.         "key encipherment",  
  11.         "server auth",  
  12.         "client auth"  
  13.       ],  
  14.       "expiry": "87600h"  
  15.     }  
  16.    }  
  17.   }  

知识点:

  •  config.json:可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个 profile;此实例只有一个kubernetes模板。
  •  signing:表示该证书可用于签名其它证书;生成的 ca.pem 证书中CA=TRUE
  •  server auth:表示client可以用该 CA 对server提供的证书进行验证;
  •  client auth:表示server可以用该CA对client提供的证书进行验证;
  •  注意标点符号,最后一个字段一般是没有逗号的。

初始化创建CA认证中心,将会生成ca-key.pem(私钥)和ca.pem(公钥) 

  1. $ cfssl gencert -initca ca-csr.json | cfssljson -bare ca 

创建 Kubernetes 证书

创建kubernetes-csr.json证书请求文件 

  1.  
  2.     "CN": "kubernetes",  
  3.     "hosts": [  
  4.         "127.0.0.1",  
  5.         "10.1.20.129",  
  6.         "10.1.20.128",  
  7.         "10.1.20.126",  
  8.         "10.1.20.127",  
  9.         "10.254.0.1",  
  10.         "*.kubernetes.master",  
  11.         "localhost",  
  12.         "kubernetes",  
  13.         "kubernetes.default",  
  14.         "kubernetes.default.svc",  
  15.         "kubernetes.default.svc.cluster",  
  16.         "kubernetes.default.svc.cluster.local" 
  17.     ],  
  18.     "key": {  
  19.         "algo": "rsa",  
  20.         "size": 2048  
  21.     },  
  22.     "names": [  
  23.         {  
  24.             "C": "CN",  
  25.             "ST": "BeiJing",  
  26.             "L": "BeiJing",  
  27.             "O": "k8s",  
  28.             "OU": "System"  
  29.         }  
  30.     ]  

知识点:

  •  这个证书目前专属于 apiserver,加了一个 *.kubernetes.master域名以便内部私有 DNS 解析使用(可删除);至于很多人问过 kubernetes 这几个能不能删掉,答案是不可以的;因为当集群创建好后,default namespace 下会创建一个叫 kubenretes 的svc,有一些组件会直接连接这个 svc 来跟 api 通信的,证书如果不包含可能会出现无法连接的情况;其他几个 kubernetes 开头的域名作用相同
  •  hosts包含的是授权范围,不在此范围的的节点或者服务使用此证书就会报证书不匹配错误。10.254.0.1是指kube-apiserver 指定的 service-cluster-ip-range 网段的第一个IP。

生成 Kubernetes 证书和私钥 

  1. $ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes 

知识点:

  •  -config 引用的是模板中的默认配置文件,
  •  -profiles是指定特定的使用场景,比如config.json中的kubernetes区域

创建 admin 证书

创建 admin 证书请求文件admin-csr.json 

  1.  {  
  2.     "CN": "admin",  
  3.     "hosts": [],  
  4.     "key": {  
  5.     "algo": "rsa",  
  6.     "size": 2048  
  7.     },  
  8.     "names": [  
  9.     {  
  10.         "C": "CN",  
  11.         "ST": "BeiJing",  
  12.         "L": "BeiJing",  
  13.         "O": "system:masters",  
  14.         "OU": "System"  
  15.     }  
  16.     ]  

生成 admin 证书和私钥 

  1. $ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin 

知识点: 这个admin 证书,是将来生成管理员用的kubeconfig 配置文件用的,现在我们一般建议使用RBAC 来对kubernetes 进行角色权限控制, kubernetes 将证书中的CN字段作为User, O 字段作为 Group。

同样,我们也可以按照同样的方式来创建 Kubernetes 中 etcd 集群的证书

创建 etcd 集群证书

    1.  证书签署请求文件ca-csr.json 

  1.  
  2.     "CN": "etcd CA",  
  3.     "key": {  
  4.         "algo": "rsa",  
  5.         "size": 2048  
  6.     },  
  7.     "names": [  
  8.         {  
  9.             "C": "CN",  
  10.             "L": "Beijing",  
  11.             "ST": "Beijing"  
  12.         }  
  13.     ]  

    2.  为节点创建服务证书请求文件,指定授权的主机节点etcd-server-csr.json 

  1.  
  2.     "CN": "etcd",  
  3.     "hosts": [  
  4.         "10.1.20.129",  
  5.         "10.1.20.126",  
  6.         "10.1.20.128"  
  7.         ],  
  8.     "key": {  
  9.         "algo": "rsa", 
  10.         "size": 2048 
  11.     },  
  12.     "names": [  
  13.         {  
  14.             "C": "CN",  
  15.             "L": "BeiJing",  
  16.             "ST": "BeiJing"  
  17.         }  
  18.     ]  

    3.  证书配置模板文件ca-config.json 

  1.  
  2.   "signing": {  
  3.     "default": {  
  4.       "expiry": "87600h"  
  5.     },  
  6.     "profiles": {  
  7.       "etcd": {  
  8.          "expiry": "87600h",  
  9.          "usages": [  
  10.             "signing",  
  11.             "key encipherment",  
  12.             "server auth",  
  13.             "client auth"  
  14.         ]  
  15.       }  
  16.     }  
  17.   }  

    4.  生成 etcd 集群所需的证书与私钥 

  1. $ cfssl gencert -initca ca-csr.json | cfssljson -bare ca -  
  2. $ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd etcd-server-csr.json | cfssljson -bare server 

这样就完成 etcd 所需证书的申请,同时了解了 cfssl 工具的强大,写到这里,本次的实验就结束了。 

 

责任编辑:庞桂玉 来源: 奇妙的Linux世界
相关推荐

2020-07-08 08:03:37

KubernetesLens集群

2022-05-24 09:00:00

云计算Kubernetes安全

2021-02-07 08:00:00

Kubernetes集群云原生

2014-12-24 09:35:29

Docker集群管理kubernetes

2019-08-23 13:10:39

美团点评Kubernetes集群管理

2022-08-09 09:10:43

Kubernetes容器

2021-11-22 16:21:28

Kubernetes 运维开源

2020-07-27 18:52:34

Kubernetes集群工具

2020-09-09 07:00:00

Kubernetes集群容器

2021-12-30 07:42:13

Kubernetes集群架构

2021-02-18 09:28:32

Kubernetes开源SaaS

2023-03-21 15:26:02

Kubernetes容器开发

2021-07-27 08:25:41

KubernetesBotKube监控

2021-08-31 07:00:26

Kubernetes Clusternet开源

2022-02-22 10:30:49

Kubernetes集群

2022-08-14 20:48:41

KubernetesArgoCD

2021-10-25 06:25:22

红帽KubernetesOpenShift 4

2015-12-30 14:50:45

Kubernetes容器技术Docker

2020-03-09 17:05:54

机器学习工程师数据结构

2022-04-15 09:30:00

Kubernetes云计算多云
点赞
收藏

51CTO技术栈公众号