瑞士军刀之cfssl
一、cfssl
cfssl
是CloudFlare开源的一款PKI/TLS
工具。CFSSL 包含一个命令行工具和一个用于签名、验证并且捆绑TLS证书的HTTP API 服务
。使用Go语言编写。
CFSSL包括:
- 一组用于生成自定义 TLS PKI 的工具
cfssl
程序,是cfssl的命令行工具multirootca
程序是可以使用多个签名密钥的证书颁发机构服务器mkbundle
程序用于构建证书池cfssljson
程序,从cfssl
和multirootca
程序获取JSON输出,并将证书,密钥,CSR和bundle写入磁盘
PKI借助数字证书和公钥加密技术提供可信任的网络身份。通常,证书就是一个包含如下身份信息的文件:
- 证书所有组织的信息
- 公钥
- 证书颁发组织的信息
- 证书颁发组织授予的权限,如
证书有效期
、适用的主机名
、用途等 - 使用证书颁发组织私钥创建的数字签名
1、安装
这里只用到cfssl
工具和cfssljson
工具
# curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl # curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson # curl -L https://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(私钥)和CSR(证书签名请求) scan: 扫描主机问题 revoke: 吊销证书 certinfo: 输出给定证书的证书信息, 跟cfssl-certinfo 工具作用一样 gencrl: 生成新的证书吊销列表 selfsign: 生成一个新的自签名密钥和 签名证书 print-defaults: 打印默认配置,这个默认配置可以用作模板 serve: 启动一个HTTP API服务 gencert: 生成新的key(密钥)和签名证书 -ca:指明ca的证书 -ca-key:指明ca的私钥文件 -config:指明请求证书的json文件 -profile:与-config中的profile对应,是指根据config中的profile段来生成证书的相关信息 ocspdump: 从cert db 中的所有 OCSP 响应中生成一系列连贯的 OCSP 响应,供 ocspserve 使用 ocspsign: 为给定的CA、Cert和状态签署OCSP响应。返回一个base64编码的OCSP响应 info: 获取有关远程签名者的信息 sign: 签名一个客户端证书,通过给定的CA和CA密钥,和主机名 ocsprefresh: 用所有已知未过期证书的新OCSP响应刷新ocsp_responses表。 ocspserve: 设置一个HTTP服务器,处理来自文件或直接来自数据库的OCSP请求(见RFC 5019)。
常用命令
cfssl gencert -initca ca-csr.json | cfssljson -bare ca ## 初始化ca cfssl gencert -initca -ca-key key.pem ca-csr.json | cfssljson -bare ca ## 使用现有私钥, 重新生成 cfssl certinfo -cert ca.pem cfssl certinfo -csr ca.csr
2、使用CFSSL创建CA认证步骤
创建认证中心(CA)
cfssl可以创建一个获取和操作证书的内部认证中心。运行认证中心需要一个CA证书和相应的CA私钥。
任何知道私钥的人都可以充当CA来颁发证书。因此,私钥的保护至关重要,这里我们以k8s所需的证书来实践一下:
cfssl print-defaults config > ca-config.json # 默认证书策略配置模板 cfssl print-defaults csr > ca-csr.json #默认csr请求模板
结合自身的要求,修改证书请求文件ca-csr.json
,证书10年
{ "CN": "kubernetes", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "k8s", "OU": "System" } ], "ca": { "expiry": "87600h" } }
知识点:
"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
{ "signing": { "default": { "expiry": "87600h" }, "profiles": { "kubernetes": { "usages": [ "signing", "key encipherment", "server auth", "client auth" ], "expiry": "87600h" } } } }
知识点:
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
(公钥)
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
创建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": "BeiJing", "L": "BeiJing", "O": "k8s", "OU": "System" } ] }
知识点:
-
这个证书目前专属于 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证书和私钥
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
{ "CN": "admin", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "system:masters", "OU": "System" } ] }
生成admin证书和私钥
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集群的证书。