日期 | 作者 | 版本 | 备注 |
---|---|---|---|
2020-10-25 | dingbin | v1.0 | |
1. cfssl 是什么
部署分布式系统服务场景下,如etcd、kubernetes、grpc servers集群时,常用的安全策略除了用户名密码策略外,经常要用到TLS加密和认证策略。一种好用的签名CA证书工具是cfssl工具集。本文讲述以cfssl自签CA证书用于TLS认证技术实践方法。
cfssl的官网地址是:https://cfssl.org。简单来说,它是美国的一个叫CloudFlare的公司开发的一款开源的工具包,它在CloudFlare公司内部被用来捆绑TLS/SSL证书链,并作为内部证书颁发机构基础架构。
2. 安装cfssl软件工具包
cfssl自签证书工具集包含3个软件:
- cfssl: 用于签发证书;
- cfssljson: 将cfssl签发生成的证书(json格式)变成文件承载式文件;
- cfssl-certinfo: 验证查看证书信息。
其官网下载地址是:https://pkg.cfssl.org
本文讲述的是CentOS Linux release 7.5.1804 系统下的构建TLS/SSL证书。因此下载linux-amd64版本即可。对应下载1.2版本的如下3个文件即可。
直接执行以下3个命令即可瞬间完成下载3个可执行程序文件:
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
由于都是linux64系统下可执行程序包,直接重命名后放到/usr/local/bin下,并添加可执行权限即可,如下图所示:
sudo cp cfssl_linux-amd64 /usr/local/bin/cfssl
sudo chmod +x /usr/local/bin/cfssl
sudo cp cfssljson_linux-amd64 /usr/local/bin/cfssljson
sudo chmod +x /usr/local/bin/cfssljson
sudo cp cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo
sudo chmod +x /usr/local/bin/cfssl-certinfo
which cfssl
which cfssljson
which cfssl-certinfo
至此cfssl工具包安装完毕。本文同时提供1.2版本的linux-amd64架构的cfssl工具包同时提供下载地址如下:
下载链接见: https://pan.baidu.com/s/19RXgEUVBci-QFavfMMNHFQ 提取码: nj8k。
2. 使用cfssl创建证书实操指南
用cfssl创建我们需要的证书文件的过程分一下3个步骤:
2.1 创建CA根证书及其私钥
根证书及其私钥,也即CA证书和CA证书的私钥,是集群所有节点共享的,只需要创建一个 CA 证书即其私钥,后续创建的所有证书都由它签名。CA根证书创建后一般命名是ca.pem。 CA更证书私钥创建后一般命名是ca-key.pem。
注意:CA根证书及其私钥,只需要创建一次即可。后续其他证书都由它签名,CA根证书及其私钥一旦改变,其它证书也就无效了。
创建CA根证书及其私钥过程可依照以下2个步骤:
2.1.1 创建CA根证书签名请求文件ca-csr.json
注意ca-csr.json中csr含义是:Certificate Signing Request,证书签名请求,因此看到 xx-csr.json,你就要知道该文件是证书签名请求文件,有了它,cfssl就可以生成证书和证书私钥了。
ca-csr.json该如何配置呢? 其实很简单,下图是截取的cfssl官网上给出的一个xx-csr.json的示例:
对csr文件内容解释如下:
- CN:Common Name,所有csr文件都必须有字段,对于 SSL 证书,一般为网站域名;而对于代码签名证书则为申请单位名称;而对于客户端证书则为证书申请者的姓名。
- hosts: 网络请求url中的合法主机名或域名集合。
下面给出2个hosts的例子:(都包含127.0.0.1,并且都使用的是域名或主机名,并且都预留了额外3个host名带extra字样的为预留host,以备后期扩容只用)
"hosts":[
"127.0.0.1",
"baseserver1.online-etcd.freedom.org",
"baseserver2.online-etcd.freedom.org",
"baseserver3.online-etcd.freedom.org",
"baseserver-extra1.online-etcd.freedom.org",
"baseserver-extra2.online-etcd.freedom.org",
"baseserver-extra3.online-etcd.freedom.org"
]
"hosts":[
"127.0.0.1",
"cent7ax",
"cent7bx",
"cent7cx",
"extra-cent7ax",
"extra-cent7bx",
"extra-cent7cx"
]
注意:
1) 超过该集合范围的任何请求都不会被支持认证通过。
2) CA根证书及其私钥创建过程不需要甚至该字段。其它服务证书创建必须有该字段。
3) hosts设置技巧:一般都把"127.0.0.1"包含进去;推荐使用域名或vip,尽量不要用ip地址,否则后期遇到某个服务所在机器宕机要重新更换某1台或多台机器时会面临证书认证不通过的毁灭性尴尬情况,导致扩容失败,集群服务面临毁灭性灾难。这里强烈推荐用域名或vip地址,另外,如果有条件,配置之处建议多预留1-3个host地址,防止后期扩容困难。
- key: key字段是必须有的字段,其内容一般也比较固定就是:{"algo":"rsa”,"size":2048},表示使用的加密算法rsa,密文长度2048。
- names字段:也是必须有字段,是证书对外公开显示的一些字段,常见的有如下:
C: (Country)所在国家简称,只能是国家字母缩写,如中国:CN
L: (Locality) 所在地区/城市简称,如Beijing/San Francisco
ST: (State/Provice)所在州/省份简称,如Beijing/California
O: (Organization Name) 单位名称,对于 SSL 证书,一般为网站域名;而对于代码签名证书则为申请单位名称;而对于客户端单位证书则为证书申请者所在单位名称
OU: (other)显示其他内容,常见的内容值有“System"、"Website"等
电子邮件 (Email): 简称E 字段
多个姓名字段 : 简称G 字段
介绍Description : 介绍字段
电话号码: Phone 字段,格式要求 + 国家区号 城市区号 电话号码,如: +86 732 88888888
地址: STREET 字段
邮政编码: PostalCode 字段
显示其他内容: 简称OU 字段
综合上述,最终我们生成的ca-csr.json如下图所示:
{
"CN":"etcd.freedom.com",
"key":{
"algo":"rsa",
"size":2048
},
"names":[
{
"C":"CN",
"ST":"BeiJing",
"L":"BeiJing",
"O":"etcd-op",
"OU":"System"
}
]
}
根据该根证书签名请求文件就可以直接通过cfssl工具包生成CA根证书及其私钥了。
2.1.2 根据CA根证书签名请求文件生成CA根证书及其私钥
直接执行命令:
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
注意:cfssljson -bare + 命名文件名,如本例中的ca,表示生成ca.pem和ca-key.pem,分别为证书和私钥文件。
生成的ca.pem是CA根证书文件,ca-key.pem是其私钥文件。其内容大体如下样式:
至此,CA根证书及其私钥文件已经生成,便可以用它们来签发其他认证文件了。
2.2 根据CA根证书及其私钥签名生成其它证书及其私钥
利用CA根证书及其私钥文件签发生成其它证书及其私钥,分为以下3个步骤执行操作:
2.2.1 创建CA根证书配置文件
CA根证书配置文件,一般命名为ca-config.json,它用于配置根证书的使用场景 (profile) 和具体参数 (usage,过期时间、服务端认证、客户端认证、加密等),后续在签名其它证书时需要指定特定场景 (profile)。
一个ca-config.json例子如下:
{
"signing":{
"default":{
"expiry":"175200h"
},
"profiles":{
"etcd-op":{
"expiry":"175200h",
"usages":[
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
expiry: 175200h表示20年有效期
profiles: 指定证书使用场景,下面的etcd-op是一个场景名称,后续签名生成证书及其私钥时需要指定该场景(profile)名称
signing:表示该证书可用于签名其它证书,生成的 ca.pem 证书中 CA=TRUE
server auth:表示 client 可以用该该证书对 server 提供的证书进行验证
client auth:表示 server 可以用该该证书对 client 提供的证书进行验证
2.2.2 创建目标证书签名请求文件
签名生成证书及其私钥,首先需要创建csr即证书签名请求文件,如下所示为一个csr证书签名请求文件的示例:
{
"CN":"etcd.freedom.com",
"key":{
"algo":"rsa",
"size":2048
},
"hosts":[
"127.0.0.1",
"cent7ax",
"cent7bx",
"cent7cx",
"extra-cent7ax",
"extra-cent7bx",
"extra-cent7cx"
],
"names":[
{
"C":"CN",
"ST":"BeiJing",
"L":"BeiJing",
"O":"etcd-op",
"OU":"System"
}
]
}
将上述内容内存为签名请求文件,比如etcd-csr.json。
2.2.3 根据CA根证书及其私钥签名生成目标证书和私钥
执行命令:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd-op etcd-csr.json | cfssljson -bare etcd
如上图,其中的报错可以忽略。
上图所示为最终签名生成的证书及其私钥文件,其中etcd.pem为证书文件,etcd-key.pem为私钥文件。其格式大体与前文提及的ca.pem和ca-key.pem相同。都是一个证书文件,一个是私钥文件,二者配成生成。
2.3 校验证书
2.3.1 使用openssl命令校验证书
执行命令:
openssl x509 -noout -text -in etcd.pem
[root@cent7ax cfssl_dir.bak]# openssl x509 -noout -text -in etcd.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
28:fd:f7:a1:e9:f2:03:0b:51:16:18:37:8f:64:46:a9:b6:72:95:67
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=CN, ST=BeiJing, L=BeiJing, O=etcd-op, OU=System, CN=etcd.freedom.com
Validity
Not Before: Nov 25 01:47:00 2020 GMT
Not After : Nov 20 01:47:00 2040 GMT
Subject: C=CN, ST=BeiJing, L=BeiJing, O=etcd-op, OU=System, CN=etcd.freedom.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:ca:4f:a2:09:9f:12:7c:81:a8:09:4d:6f:c3:96:
c0:69:da:fc:9d:10:33:4c:2a:56:ba:06:20:3e:2f:
52:2f:15:36:a1:11:89:f7:98:56:b6:8f:38:85:82:
02:2c:ac:a8:b1:9e:71:6d:fe:e5:06:1f:a7:7a:3e:
9c:be:e2:9d:75:3e:69:1b:9e:06:eb:00:1b:74:60:
c3:6c:cc:f8:f4:c9:2c:12:d1:aa:2a:72:3f:5b:e0:
d0:45:57:f0:ad:88:6e:a0:59:c4:e4:5d:53:cb:6f:
ec:8e:fe:33:32:9f:99:ad:e6:3b:ca:ad:7d:4b:19:
8c:eb:7d:92:8e:8e:09:8b:a7:49:2a:1e:73:35:eb:
e3:59:4f:87:be:8d:12:cb:23:41:f5:34:bf:1a:4d:
04:c0:7c:70:99:8f:ce:51:ca:1c:7c:99:45:0e:b1:
d7:91:63:58:4c:a3:73:55:cb:d1:8e:eb:de:cd:5b:
89:35:30:4d:45:08:c6:09:de:e2:b0:de:56:aa:13:
ac:39:cb:e5:2d:06:06:24:63:fa:eb:c8:20:e0:b8:
bb:55:bf:d1:83:4a:9a:dc:2c:56:6c:16:7b:e3:06:
53:55:d8:d3:57:e3:82:09:3f:8b:91:1b:b8:68:d1:
0f:8f:98:4e:07:fc:94:65:69:6f:bd:59:a7:38:08:
79:27
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Key Identifier:
F0:73:FD:7B:11:AF:96:CF:C7:BF:65:FE:BD:27:5C:39:44:D0:04:CC
X509v3 Authority Key Identifier:
keyid:0F:D9:11:F9:9F:B8:72:B3:25:01:F2:3E:0A:D0:0E:7F:65:D2:91:0A
X509v3 Subject Alternative Name:
DNS:cent7ax, DNS:cent7bx, DNS:cent7cx, DNS:extra-cent7ax, DNS:extra-cent7bx, DNS:extra-cent7cx, IP Address:127.0.0.1
Signature Algorithm: sha256WithRSAEncryption
83:ce:62:56:62:1c:71:cd:9f:83:44:76:7a:7b:44:60:c2:6c:
78:ff:91:62:6c:8e:39:61:d4:d3:f8:74:c0:71:65:c3:80:50:
d1:2c:f3:d6:40:bc:1f:7e:3b:f6:e0:2c:82:4f:6b:8c:09:48:
22:d7:ea:96:ba:94:99:72:9d:ae:c2:06:15:37:7f:9b:20:02:
a7:d7:62:eb:7d:7e:93:53:5f:21:80:f8:b6:1c:8d:40:2f:09:
75:16:db:3f:4e:01:22:d2:7d:a7:eb:e2:49:d6:06:7b:3c:07:
1c:90:b0:ae:bc:9d:77:8b:a2:a9:5d:57:d9:1a:e8:0a:2a:1d:
62:86:d8:dd:b8:9f:14:a4:cd:23:36:a9:c4:c6:40:ec:1a:58:
f5:a1:6e:d3:37:7f:68:36:90:d5:9f:17:ea:a5:4d:47:71:89:
5a:c9:bc:48:d2:77:54:e4:9e:cd:51:af:de:f2:d9:e4:53:95:
46:07:a7:73:6a:8b:b1:e5:51:b5:fd:82:c1:73:1e:62:b6:0d:
8b:30:e6:12:f2:11:d7:0b:97:2c:97:c3:b9:3b:be:31:4a:a3:
89:18:8b:ed:76:95:67:e3:b5:53:f4:33:a1:0a:aa:1e:88:37:
f2:f4:d2:56:18:0c:79:84:dd:7a:9a:2f:99:2f:e5:fa:f6:9a:
d5:ea:09:b8
- 确认
Issuer
字段的内容和ca-csr.json
一致; - 确认
Subject
字段的内容和etcd-csr.json
一致; - 确认
X509v3 Subject Alternative Name
字段的内容和etcd-csr.json
一致; - 确认
X509v3 Key Usage、Extended Key Usage
字段的内容和ca-config.json
中etcd-op
profile 一致;
2.3.2 使用cfssl-certinfo命令校验证书
执行命令:
cfssl-certinfo -cert etcd.pem
[root@cent7ax cfssl_dir.bak]# cfssl-certinfo -cert etcd.pem
{
"subject": {
"common_name": "etcd.freedom.com",
"country": "CN",
"organization": "etcd-op",
"organizational_unit": "System",
"locality": "BeiJing",
"province": "BeiJing",
"names": [
"CN",
"BeiJing",
"BeiJing",
"etcd-op",
"System",
"etcd.freedom.com"
]
},
"issuer": {
"common_name": "etcd.freedom.com",
"country": "CN",
"organization": "etcd-op",
"organizational_unit": "System",
"locality": "BeiJing",
"province": "BeiJing",
"names": [
"CN",
"BeiJing",
"BeiJing",
"etcd-op",
"System",
"etcd.freedom.com"
]
},
"serial_number": "234023291199234768277633047351258036366090605927",
"sans": [
"cent7ax",
"cent7bx",
"cent7cx",
"extra-cent7ax",
"extra-cent7bx",
"extra-cent7cx",
"127.0.0.1"
],
"not_before": "2020-11-25T01:47:00Z",
"not_after": "2040-11-20T01:47:00Z",
"sigalg": "SHA256WithRSA",
"authority_key_id": "F:D9:11:F9:9F:B8:72:B3:25:1:F2:3E:A:D0:E:7F:65:D2:91:A",
"subject_key_id": "F0:73:FD:7B:11:AF:96:CF:C7:BF:65:FE:BD:27:5C:39:44:D0:4:CC",
"pem": "-----BEGIN CERTIFICATE-----nMIIERjCCAy6gAwIBAgIUKP33oenyAwtRFhg3j2RGqbZylWcwDQYJKoZIhvcNAQELnBQAwbzELMAkGA1UEBhMCQ04xEDAOBgNVBAgTB0JlaUppbmcxEDAOBgNVBAcTB0JlnaUppbmcxEDAOBgNVBAoTB2V0Y2Qtb3AxDzANBgNVBAsTBlN5c3RlbTEZMBcGA1UEnAxMQZXRjZC5mcmVlZG9tLmNvbTAeFw0yMDExMjUwMTQ3MDBaFw00MDExMjAwMTQ3nMDBaMG8xCzAJBgNVBAYTAkNOMRAwDgYDVQQIEwdCZWlKaW5nMRAwDgYDVQQHEwdCnZWlKaW5nMRAwDgYDVQQKEwdldGNkLW9wMQ8wDQYDVQQLEwZTeXN0ZW0xGTAXBgNVnBAMTEGV0Y2QuZnJlZWRvbS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKnAoIBAQDKT6IJnxJ8gagJTW/DlsBp2vydEDNMKla6BiA+L1IvFTahEYn3mFa2jziFnggIsrKixnnFt/uUGH6d6Ppy+4p11PmkbngbrABt0YMNszPj0ySwS0aoqcj9b4NBFnV/CtiG6gWcTkXVPLb+yO/jMyn5mt5jvKrX1LGYzrfZKOjgmLp0kqHnM16+NZT4e+njRLLI0H1NL8aTQTAfHCZj85Ryhx8mUUOsdeRY1hMo3NVy9GO697NW4k1ME1FCMYJn3uKw3laqE6w5y+UtBgYkY/rryCDguLtVv9GDSprcLFZsFnvjBlNV2NNX44IJP4uRnG7ho0Q+PmE4H/JRlaW+9Wac4CHknAgMBAAGjgdkwgdYwDgYDVR0PAQH/BAQDAgWgnMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GnA1UdDgQWBBTwc/17Ea+Wz8e/Zf69J1w5RNAEzDAfBgNVHSMEGDAWgBQP2RH5n7hynsyUB8j4K0A5/ZdKRCjBXBgNVHREEUDBOggdjZW50N2F4ggdjZW50N2J4ggdjZW50nN2N4gg1leHRyYS1jZW50N2F4gg1leHRyYS1jZW50N2J4gg1leHRyYS1jZW50N2N4nhwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQCDzmJWYhxxzZ+DRHZ6e0Rgwmx4/5FinbI45YdTT+HTAcWXDgFDRLPPWQLwffjv24CyCT2uMCUgi1+qWupSZcp2uwgYVN3+bnIAKn12LrfX6TU18hgPi2HI1ALwl1Fts/TgEi0n2n6+JJ1gZ7PAcckLCuvJ13i6KpnXVfZGugKKh1ihtjduJ8UpM0jNqnExkDsGlj1oW7TN39oNpDVnxfqpU1HcYlaybxIn0ndU5J7NUa/e8tnkU5VGB6dzaoux5VG1/YLBcx5itg2LMOYS8hHXC5csl8O5O74xnSqOJGIvtdpVn47VT9DOhCqoeiDfy9NJWGAx5hN16mi+ZL+X69prV6gm4n-----END CERTIFICATE-----n"
}
2.4 分发证书
最后将上面签名生成的证书文件etcd.pem及其私钥文件etcd-key.pem 拷贝到集群所有需要的地方,即分发证书。典型使用场景有:
- etcd-server集群的安装部署
- grpc servers集群的安装部署
- kubernetes集群的安装部署
等场景都需要使用证书认证。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。