作者:键客_李大白
一、cfssl概述
CFSSL是CloudFlare公司提供的PKI/TLS工具,使用Go语言开发。开源并支持Windows、Linux、macos系统。
官网:https://cfssl.org/
源码:https://github.com/cloudflare/cfssl
二进制:http://pkg.cfssl.org/
工具集:
- multirootca:管理多个签名密钥的情形;使用多个签名密钥的证书颁发机构服务器
- mkbundle:构建证书池;
- cfssljson:将从cfssl和multirootca等获得的json格式的输出转化为证书格式的文件(证书,密钥,CSR和bundle)进行存储;
- cfssl-certinfo:可显示CSR或证书文件的详细信息;可用于证书校验。
文件说明
ca-config.json:配置文件
ca-csr.json:证书请求文件
han-ca.csr:证书签名请求文件
han-ca.pem:公钥
han-key.pem:私钥
ca-config.json解析
可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个profile;此实例只有一个kubernetes模板。
# vim ca-config.json
{
"signing": {
"default": {
"expiry": "168h"
},
"profiles": {
"www": {
"expiry": "8760h",
"usages": [
"signing",
"key encipherment",
"server auth"
]
},
"client": {
"expiry": "8760h",
"usages": [
"signing",
"key encipherment",
"client auth"
]
}
}
}
}
- signing:签署,表示该证书可用于签名其它证书;生成的 ca.pem 证书中 CA=TRUE;
- expiry:证书有效期限(单位:小时),8760h=1年;指定了证书的过期时间。
- usage:用法;
- key encipherment:密钥加密;
- profiles:指定了不同角色的配置信息;可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个 profile。
- server auth:服务器身份验证;表示 client 可以用该 CA 对 server 提供的证书进行验证;
- client auth:客户端身份验证;表示 server 可以用该 CA 对 client 提供的证书进行验证;
ca-csr.json解析
# vim ca-csr.json{
"CN": "example.net",
"hosts": [
"example.net",
"www.example.net"
],
"key": {
"algo": "rsa",
"size": 204
},
"names": [
{
"C": "US",
"ST": "CA",
"L": "San Francisco"
“O“:”kubernetes”
“OU”:”system”
}
]
}
- CN: Common Name
- hosts:包含的授权范围,不在此范围的的节点或者服务使用此证书就会报证书不匹配错误。kubernetes 开头的域名作用:集群创建好后,default namespace 下会创建一个叫 kubenretes 的 svc,有一些组件会直接连接这个 svc 来跟 api 通讯的,证书如果不包含可能会出现无法连接的情况;
- Key: 指定使用的加mi算法,一般使用rsa非对称加mi算法(algo:rsa;size:)。“CN”:Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法;“O”:Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group);
.csr文件解析
CA机构不会凭空创建一个证书,他们需要一个公钥和一些元数据来填入证书之中,而这些信息就是存放在CSR文件之中,
Csr文件需要包含:
- 申请者的公钥信息
- 使用申请者私钥产生的数字签名
- 申请者机构相关的信息
CA可以对提供上述内容的CSR进行证书的创建。首先它会通过对于数字签名进行检验来确认申请者的身份,然后通过确认域名或者IP是否有效等方式来确认是否能够进行证书的签发,CA会有一个数据库保存所有的证书信息,不能与既存的有效证书向冲突也是检验的内容之一,如果所有验证都通过,CA就会使用自己的私钥发行一个证书给予此CSR文件的申请者。
# cat ca.csr
-----BEGIN CERTIFICATE REQUEST-----
MIICyDCCAbACAQAwYTELMAkGA1UEBhMCQ04xDjAMBgNVBAgTBUh1YmVpMQ4wDAYD
VQQHEwVXdWhhbjEMMAoGA1UEChMDazhzMQ8wDQYDVQQLEwZzeXN0ZW0xEzARBgNV
BAMTCmt1YmVybmV0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+
8oERNbUqKNXe/FTAVSwLcl3TcxVZLyGVtIoMaxz9u4YV12jetqHquaXP8Ssz4Hhm
/Pm4Jsolapo9mefiZJ8K5xIpU/l2Ag5PedNtimZrdZeeTs0RaDKUIIbwhSbzI4Cf
lSDZ0/WWXY6FBK12zP6Tz7hQTu4m33KMUcujhuqYLs7hC79dwKx4IG5aA2A8J+8M
NeOsBktSQEkAkJMZfI+XXNFlL86SdQAjJUxhamWQPfjtZQ6kdCTsQrk2EPxN4Lg8
nvXpSosL6p5k0FafxHwsUIzULQtxjzP/IXisVkHf8bcFHn73A7dYt/Jf4x+wjG0a
D5jtFw1sPXZaZCvbXEJ7AgMBAAGgIjAgBgkqhkiG9w0BCQ4xEzARMA8GA1UdEwEB
/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJhAiQaKqldV8Iv2caBdSsOrO2LP
EZAz8vlnuA8JxfoPby6m3bRRimg23C7P6an+reDVWO8PWW2RQbnAnfhXT2ZOl4Cz
EyFQz7dWTSfM0JLMHf+PYAfSyPYzqinryVLieYM+mqaG4FhTYBmCKSWVN7gWxXse
/ANx+uoEySUHelYMptleF9fpY1NfupBB3ik5BchfSzMj7MnxvOOvyYdzdrW1NMh/
2zPccPHrzbn7ZRcZn/gfgOSeeoF8PjJ4d736h3ij3+1ZvSX6mgq2MLDdLXWrUumm
a41QIstt7I/fJ62X632LgUxLyXneFndRXNVtYJ8XfTbGyatDrTZu1pNOXNc=
-----END CERTIFICATE REQUEST-----
二、安装CFSSL
1)在线安装
$ ;wget https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssl_1.6.0_linux_amd64 -O /usr/local/bin/cfssl
$ ;wget https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssljson_1.6.0_linux_amd64 -O /usr/local/bin/cfssljson
$ ;wget https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssl-certinfo_1.6.0_linux_amd64 -O /usr/local/bin/cfssl-certinfo
$ ;chmod +x /usr/local/bin/*
2)离线安装
从官网下载相关二进制包
解压后,将二进制文件复制到echo $PATH的目录下即可完成安装
三、命令语法格式
cfssl的用法
语法格式
cfssl 子命令 选项 参数
bundle:创建包含客户端证书的证书捆绑包
bundle的使用
1. 捆绑本地证书文件
cfssl bundle -cert file [-ca-bundle file] [-int-bundle file] [-int-dir dir] [-metadata file] [-key keyfile] [-flavor optimal|ubiquitous|force] [-password password]
2. 从远程服务器捆绑证书
cfssl bundle -domain domain_name [-ip ip_address] [-ca-bundle file] [-int-bundle file] [-int-dir dir] [-metadata file]
-cert=”“:包含公钥的客户端证书
-key=“”:证书的私钥
-ca-bundle=“”:根证书存储的路径
-int-bundle=“”:到中间证书存储的路径
-味道=无处不在:捆绑味道:无处不在、最优和强制。
-int-dir=“”:指定中间产物目录
-metadata=“”:根证书存在的元数据文件。该文件的内容是一个json字典(k,v):
每个密钥k是根证书的SHA-1摘要,而值v是密钥存储文件名的列表。
-domain=”“:远程服务器域名
--ip=“”:远程服务器ip
-ip=“”:远程服务器ip
pa-password=0:用于访问传递给bundler的PKCS#12数据的密码
-db config=“”:证书数据库配置文件
-ca=“”:用于签署新证书的ca--接受“[file:]fname”或“env:varname”
-ca-key=“”:ca私钥--接受“[file:]fname”或“env:varname”
-expiry=168h0m0s:从现在起CRL将过期的时间(默认值:一周)
-loglevel=1:日志级别(0=调试,5=致命)
scan的使用:
cfssl scan [-family regexp] [-scanner regexp] [-timeout duration] [-ip IPAddr] [-num-workers num] [-max-hosts num] [-csv hosts.csv] HOST
cfssl scan -list
-list=false:列出可能的扫描仪
-family=“”:扫描仪族正则表达式
-scanner=“”:scanner正则表达式
-timeout=5ms:超时前扫描每个主机的持续时间(ns、us、ms、s、m、h)
-ip=“”:远程服务器ip
-ca-bundle=“”:根证书存储的路径
-num-workers=10:用于扫描的worker数
-csv=“”:包含主机csv的文件
-max-hosts=100:要扫描的最大主机数
-loglevel=1:日志级别(0=调试,5=致命)
revoke: 撤消证书存储中的证书,吊销证书
用法:
cfssl revoke -db-config config_file -serial serial -aki authority_key_id [-reason reason]
-serial=”“:证书序列号
-reason=0:吊销的原因代码
-loglevel=1:日志级别(0=调试,5=致命)
Reason(原因)可以是整数代码或RFC 5280中ReasonFlags中的字符串
certinfo: 输出给定证书的证书信息, 跟cfssl-certinfo 工具作用一样
selfsign: 生成一个新的自签名密钥和 签名证书
print-defaults: 打印默认配置,这个默认配置可以用作模板
serve: 启动一个HTTP API服务
genkey: 生成一个key(私钥)和CSR(证书签名请求)
gencrl: 生成新的证书吊销列表
gencsr:
gencert: 生成新的key(密钥)和签名证书
gencert的使用:
- 从CSR生成新密钥和证书:# cfssl gencert -initca CSRJSON
# cfssl gencert -ca cert -ca-key key
[-config-config][-profile-profile][-hostname hostname] CSRJSON
# cfssl gencert -remote remote_host
[-config config][ -profile profile][ -label label] [-hostname hostname] CSRJSON - 使用CA密钥和CSR重新生成CA证书# cfssl gencert -initca -ca-key key CSRJSON
- 使用CA密钥和证书重新生成CA证书
# cfssl gencert -renewca -ca cert -ca-key key
论据:
CSRJSON:包含请求的JSON文件,使用“-”从stdin读取JSON
-initca=false:初始化新CA
-ca=:指明ca的证书(ca.pem公钥)
-ca-key:指明ca的私钥文件
-config:指明请求证书的json文件(配置文件)
-profile:签署要使用的配置文件;
与-config中的profile对应,是指根据config中的profile段来生成证书的相关信息
-remote=”“:远程CFSSL服务器
-hostname=”“:证书的主机名,可以是逗号分隔的主机名列表
-label=“”:在远程CFSSL服务器中使用的密钥标签
-loglevel=1:日志级别(0=调试,5=致命)
ocspdump
ocspsign
ocsprefresh
ocspserve
info: 获取有关远程签名者的信息
sign: 签名一个客户端证书,通过给定的CA和CA密钥,和主机名
version
cfssljson的用法:
-bare
来自CFSSL的响应未包装在API标准响应中
-f string
JSON输入(默认为“-”)
-stdout
输出响应,而不是保存到文件
-version
打印版本并退出
四、工具实战应用
生成默认配置模板文件
# cfssl print-defaults config > ca-config.json
生成默认csr请求文件模板
# cfssl print-defaults csr > csr.json
创建ca证书
# cfssl gencert -initca ca-csr.json | cfssljson -bare /etc/etcd/ssl/ca
Kubernetes证书创建
创建CA
创建 Kubernetes 证书
创建 Admin 证书
创建kube-proxy证书
校验证书
(1)使用openssl命令校验证书
# openssl x509 -noout -text -in kubernetes.pem
【说明】:
确认 Issuer 字段的内容和 ca-csr.json 一致;
确认 Subject 字段的内容和 kubernetes-csr.json 一致;
确认 X509v3 Subject Alternative Name 字段的内容和 kubernetes-csr.json 一致;
确认 X509v3 Key Usage、Extended Key Usage 字段的内容和 ca-config.json 中 kubernetesprofile 一致。
(2)使用 Cfssl-Certinfo 命令校验
# cfssl-certinfo -cert kubernetes.pem
分发证书
将生成的证书和秘钥文件(后缀名为.pem)拷贝到所有机器的 /etc/kubernetes/ssl 目录下备用: