当前位置: 首页 > 科技观察

使用CFSSL管理Kubernetes集群证书

时间:2023-03-15 19:16:18 科技观察

熟悉HTTP、HTTPS、SSL,TLSHTTP是一种网络协议,专门用于传输网页内容。大多数网站使用HTTP协议来传输网页和网页中包含的内容各种东东(图片、CSS样式、JS脚本)。SSL是SecureSocketsLayer的缩写,中文称为“安全套接字层”。它是由Netscape在20世纪90年代中期设计的。(顺便说一下,Netscape不仅发明了SSL,还发明了很多Web基础设施——比如CSS样式表和JS脚本),他们为什么要发明SSL协议?因为互联网上原来使用的HTTP协议是明文的,所以有很多缺点——比如传输内容会被窥视(嗅探)和篡改。SSL协议就是为了解决这些问题而发明的。TLS是SSL的标准化。SSL标准化后,名称改为TLS(TransportLayerSecurity的缩写),中文全称为TransportLayerSecurityProtocol。很多相关文章把两者统称为(SSL/TLS),因为这两者可以看作是同一事物的不同阶段。HTTPS协议,说白了就是“HTTP协议”和“SSL/TLS协议”的结合。您可以将HTTPS大致理解为-HTTPoverSSL或HTTPoverTLS。CA认证的原理下面通过介绍信的描述来介绍一下CA的原理◇普通的介绍信,大家一定听说过介绍信的例子吧?假设A公司张三先生要去B公司拜访,B公司没有人认识他,怎么办?通常的方式是带上公司出具的介绍信,上面写着:张三先生特此前往贵公司办理业务,请与我们联系……等等。然后在信上盖上A公司的公章。张三先生到达B公司后,将介绍信交给了B公司的接待员李丝女士,当李女士看到介绍信上有A公司的公章时,A公司由于经常与B公司有业务往来,李女士认为张先生不是小人。这里A公司就是CA证书◇介绍中介机构的介绍信好了,回到刚才的话题。如果和B公司有业务往来的公司很多,而且每个公司的公章都不一样,那前台肯定要懂得区分各种公章,很麻烦。于是,某中介公司C发现了这个商机。C公司专门开设了“代理公章”业务。以后A公司业务员去B公司,需要带两封介绍信:信1:加盖C公司公章和A公司公章,并具体注明:C公司委托公司A、介绍信2:只加盖A公司公章,然后写上:张三先生特此前往贵公司办理业务,请与我们联系……等等。有不开明的同学会问,这样不是更麻烦吗?有什么好处?主要的好处是对于接待公司的前台来说,不用记住每个公司的公章是什么样子的;他/她只需要记住中介公司C的公章。当他/她拿到两封介绍信时,先验证第一封介绍信的C公章的真实性;如果相同,则可以证明介绍信2是可以信任的。公钥基础设施PKICA(CertificationAuthority)证书是指权威机构颁发给我们的证书。密钥是用于加密和解密的文件或字符串。在非对称加密领域,密钥指的是私钥和公钥。它们总是成对出现,主要作用是加密和解密。常用的加密强度是2048bit。RSA代表非对称加密算法。非对称加密有两种不同的密码,一种称为私钥,另一种称为公钥。用其中一个加密的数据只能用另一个密码解密,用自己的密码是解不开的,也就是说用公钥加密的数据只能用私钥解密。证书的编码格式为PEM(PrivacyEnhancedMail),通常用于数字证书认证机构(CertificateAuthorities,CA),扩展名为.pem、.crt、.cer、.key。内容是一个Base64编码的ASCII码文件,带有类似头尾标志的服务器认证证书。"-----BEGINCERTIFICATE-----""-----ENDCERTIFICATE-----"中间认证证书和私钥都可以用PEM格式存储(认证证书其实就是公钥).Apache和Nginx等服务器使用PEM格式的证书。DER(DistinguishedEncodingRules),它与PEM的不同之处在于它使用二进制而不是Base64编码的ASCII。扩展名是.der,但也经常使用.cer作为扩展名,所有类型的认证证书和私钥都可以以DER格式存储。Java使其成为典型的使用平台。CertificateSigningRequestCSRCSR(CertificateSigningRequest),是向CA机构申请数字×××证书时使用的请求文件。在生成请求文件之前,我们需要准备一对对称密钥。私钥信息是自己保存的,公钥信息、国家、城市、域名、Email等信息会附在请求中,签名信息也会附在CSR中。当我们准备好CSR文件后,就可以提交给CA,等待他们签字。签名后,我们会收到crt文件,也就是证书。注意:CSR不是证书。相反,从权威的证书颁发机构获得签名证书的申请。将CSR提交给权威的证书颁发机构,由权威的证书颁发机构签名并完成。保持CSR良好。当权威证书颁发机构颁发的证书到期后,您仍然可以使用同一个CSR申请新证书,Key保持不变。数字签名数字签名是“非对称加密+摘要算法”,其目的不是为了加密,而是为了防止他人篡改数据。核心思想是:比如A要给B发送数据,A先用摘要算法得到数据的指纹,然后用A的私钥加密指纹,加密后的指纹就是A的签名,B收到数据和A的签名,同样用摘要算法计算指纹,然后用A的公钥解密签名,比较两个指纹。如果相同,说明数据没有被篡改,确实是A发送的数据。假设C想把A发给B的数据改成B来欺骗B,因为指纹会变数据被篡改。如果要与A签名中的指纹一致,就必须更改签名,但由于没有A的私钥,所以无法更改。如果C用自己的私钥生成新的签名,B收到数据后就无法用A的公钥解密。常用的摘要算法包括MD5、SHA1和SHA256。用私钥对待传输文本的摘要进行加密,得到的密文称为传输过程的签名。数字证书和公钥数字证书是由CA的根证书签署申请者的一些基本信息和申请者的公钥(相当于盖上证书颁发机构公章后形成的数字文件)。数字证书其实就是经过CA认证的公钥。除公钥外,还有其他信息,如Email、国家、城市、域名等。CFSSL安装及基础知识cfssl是CloudFlare开源的一款PKI/TLS工具。CFSSL包括一个命令行工具和一个HTTPAPI服务,用于签署、验证和绑定TLS证书。用Go语言编写。CFSSL包括:一组用于生成自定义TLSPKI的工具cfssl程序,cfssl的命令行工具multirootca程序是一个证书授权服务器,可以使用多个签名密钥mkbundle程序,用于构建证书池cfssljson程序,从cfssl和multirootca程序中取JSON输出并将证书、密钥、CSR和捆绑包写入磁盘PKI借助数字证书和公钥加密技术提供受信任的网络身份。通常,证书是包含以下身份信息的文件:证书所有者组织的信息证书颁发机构的公钥信息证书颁发机构授予的权限,例如证书有效期、适用的主机名、用途等。创建使用证书颁发机构的私钥数字签名安装cfssl这里我们只使用cfssl工具和cfssljson工具#curl-Lhttps://pkg.cfssl.org/R1.2/cfssl_linux-amd64-o/usr/local/bin/cfssl#curl-Lhttps://pkg.cfssl.org/R1.2/cfssljson_linux-amd64-o/usr/local/bin/cfssljson#curl-Lhttps://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64-o/usr/local/bin/cfssl-certinfo#chmod+x/usr/local/bin/cfssl*cfssl常用子命令介绍bundle:创建包含客户端证书的证书包genkey:生成密钥(私有key)andCSR(certificatesignaturerequest)scan:扫描主机问题revoke:撤销证书certinfo:out放置给定证书的证书信息,同cfssl-certinfo工具gencrl:生成新的证书吊销列表selfsign:生成新的自签名密钥和签名证书print-defaults:打印默认配置,可用作atemplateserve:启动一个HTTPAPI服务gencert:生成新的密钥(key)和签名证书-ca:指定ca的证书-ca-key:指定ca的私钥File-config:表示请求证书的json文件-profile:对应-config中的profile,指根据config中的profile部分生成证书相关信息ocspdump:从certdbOCSPresponse中的所有OCSPresponse生成一系列连贯的OCSPresponse,供ocspserve使用ocspsign:Sign给定CA、证书和状态的OCSP响应。返回base64编码的OCSP响应信息:获取有关远程签名者的信息签名:使用给定的CA和CA密钥以及主机名签署客户端证书ocsprefresh:使用所有已知的未过期证书刷新OCSP响应刷新ocsp_responses表。ocspserve:设置一个HTTP服务器来处理来自文件或直接来自数据库的OCSP请求(请参阅RFC5019)。常用命令$cfsslgencert-initcaca-csr.json|cfssljson-bareca##初始化ca$cfsslgencert-initca-ca-keykey.pemca-csr.json|cfssljson-bareca##使用已有私钥重新生成$cfsslcertinfo-certca.pem$cfsslcertinfo-csrca.csr使用CFSSL创建CA证书的步骤创建证书颁发机构(CA)cfssl可以创建获取和操作证书的内部证书颁发机构。运行证书颁发机构需要CA证书和相应的CA私钥。任何知道私钥的人都可以充当CA来颁发证书。因此,私钥的保护非常重要。这里使用k8s需要的证书来练习:$cfsslprint-defaultsconfig>config.json#default证书策略配置模板$cfsslprint-defaultscsr>csr.json#defaultcsr请求模板组合根据自己的需求,修改证书请求文件csr.json,证书是10年{"CN":"kubernetes","key":{"algo":"rsa","size":2048},"names":[{"C":"CN""ST":"北京","L":"北京","O":"k8s","OU":"系统"}],"ca":{"expiry":"87600h"}}知识points:"CN":CommonName,kube-apiserver从证书中提取该字段作为请求的用户名(UserName)"O":Organization,kube-apiserver从证书中提取该字段作为请求用户所在的组(Group)C:Country,国家L:Locality,region,cityO:OrganizationName,组织名称,公司名称OU:OrganizationUnitName,组织单位名称,公司部门ST:State,state,provincialcertificate配置模板文件ca-config.json{“签名”:{“默认”:{“过期y":"87600h"},"profiles":{"kubernetes":{"usages":["signing","keyencipherment","serverauth","clientauth"],"expiry":"87600h"}}}}知识点:config.json:可以定义多个profile,指定不同的expirations等参数作为时间和使用场景;稍后在签署证书时使用某个配置文件;本实例只有一个kubernetestemplatesigning:表示该证书可用于签署其他证书;CA=TRUEserverauthinthegeneratedca.pemcertificate:表示客户端可以使用这个CA来验证服务器提供的证书;clientauth:表示服务端可以使用这个CA来验证客户端提供的证书;注意标点符号,最后一个字段一般没有逗号。初步创建一个CA认证中心,会生成ca-key.pem(私钥)和ca.pem(公钥)$cfsslgencert-initcaca-csr.json|cfssljson-bareca创建一个Kubernetes证书创建一个kubernetes-csr.json证书请求文件{"CN":"kubernetes","hosts":["127.0.0.1","10.1.20.129","10.1.20.128","10.1.20.126","10.1.20.127","10.254.0.1","*.kubernetes.master","localhost","kubernetes","kubernetes.default","kubernetes.default.svc","kubernetes.default.svc.cluster","kubernetes.default.svc.cluster.local"],"key":{"algo":"rsa","size":2048},"names":[{"C":"CN","ST":"北京","L":"BeiJing","O":"k8s","OU":"System"}]}知识点:此证书目前为apiserver独享,内部私有DNS增加一个*.kubernetes.master域名分辨率(可删除);正如很多人问的,这些kubernetes是否可以删除,答案是否定的;因为在创建集群的时候,默认的namespace下会创建一个名为kubenretes的svc,一些组件会直接连接到这个svc上与api通信。如果不包含证书,则可能无法连接;其他几个kubernetes开头的域名也有同样的效果。hosts包含授权范围,如果这个范围之外的节点或服务使用这个证书,会报证书不匹配错误。10.254.0.1指的是kube-apiserver指定的service-cluster-ip-range网段的第一个IP。生成Kubernetes证书和私钥$cfsslgencert-ca=ca.pem-ca-key=ca-key.pem-config=ca-config.json-profile=kuberneteskubernetes-csr.json|cfssljson-barekubernetes知识点:-config参考是模板中默认的配置文件,-profiles是指定具体的使用场景,比如在config.json中的kubernetes区域创建admin证书创建admin证书请求文件admin-csr.json{"CN":“admin”,“hosts”:[],“key”:{“algo”:“rsa”,“size”:2048},“names”:[{“C”:“CN”,“ST”:”BeiJing","L":"BeiJing","O":"system:masters","OU":"System"}]}生成管理员证书和私钥$cfsslgencert-ca=ca.pem-ca-key=ca-key.pem-config=ca-config.json-profile=kubernetesadmin-csr.json|cfssljson-bareadmin知识点:该admin证书用于以后生成kubeconfig配置文件供管理员使用。现在我们一般推荐使用RBAC给kubernetes分配角色来进行权限控制,kubernetes使用证书中的CN字段为User,O字段为Group。同样,我们也可以用同样的方法在Kubernetes中创建etcd集群的证书。创建etcd集群证书1.证书签名请求文件ca-csr.json{"CN":"etcdCA","key":{"algo":"rsa","size":2048},"names":[{"C":"CN","L":"北京","ST":"北京"}]}2.为节点Request文件创建服务证书,指定授权主机节点etcd-server-csr.json{"CN":"etcd","hosts":["10.1.20.129","10.1.20.126","10.1.20.128"],"key":{"algo":"rsa","size":2048},"names":[{"C":"CN","L":"北京","ST":"北京"}]}3、证书配置模板文件ca-config.json{"signing":{"default":{"expiry":"87600h"},"profiles":{"etcd":{"expiry":"87600h","usages":["signing","keyencipherment","serverauth",“谎言ntauth"]}}}}4.生成etcd集群所需的证书和私钥$cfsslgencert-initcaca-csr.json|cfssljson-bareca-$cfsslgencert-ca=ca.pem-ca-key=ca-key。pem-config=ca-config.json-profile=etcdetcd-server-csr.json|cfssljson-bareserver这样就完成了etcd需要的证书的申请,同时也了解了cfssl工具的强大,写到这里后,本次实验结束