[TOC]
原文地址: SSL与TLS协议原理与证书签名多种生成方式实践指南 (https://mp.weixin.qq.com/s/g-X8UPNwIkuR_Qd2MDvVQw)
0x00 前言简述
简单快速了解HTTP、HTTPS、SSL、TLS
概念:
- HTTP 是一个网络协议,是专门用来传输 Web 内容,大部分网站都是通过 HTTP 协议来传输 Web 页面、以及 Web 页面上包含的各种东东(图片、CSS 样式、JS 脚本)。
- SSL 是Secure Sockets Layer的缩写,中文叫做“安全套接层”,它是在上世纪90年代中期,由网景公司设计的, 为了解决http在传输过程中内容会被偷窥(嗅探)和篡改。
- TLS 是 SSL的 标准化,SSL标准化之后的名称改为 TLS(是
Transport Layer Security
的缩写),中文叫做传输层安全协议。很多相关的文章都把这两者并列称呼(SSL/TLS),因为这两者可以视作同一个东西的不同阶段。 - HTTPS 协议,说白了就是“HTTP 协议”和“SSL/TLS 协议”的组合。你可以把 HTTPS 大致理解为——HTTP over SSL或HTTP over TLS。
CA 认证原理
描述: 通过下面介绍信的例子来介绍CA的原理(转载的)。
场景1.普通的介绍信 想必大伙儿都听说过介绍信的例子吧?假设 A 公司的张三先生要到 B 公司去拜访,但是 B 公司的所有人都不认识他,他咋办捏?常用的办法是带公司开的一张介绍信,在信中说:兹有张三先生前往贵公司办理业务,请给予接洽……云云。然后在信上敲上A公司的公章。
张三先生到了 B 公司后,把介绍信递给 B 公司的前台李四小姐。李小姐一看介绍信上有 A 公司的公章,而且 A 公司是经常和 B 公司有业务往来的,这位李小姐就相信张先生不是歹人了。
这里,A公司就是CA证书
场景2.引入中介机构的介绍信 好,回到刚才的话题。如果和 B 公司有业务往来的公司很多,每个公司的公章都不同,那前台就要懂得分辨各种公章,非常滴麻烦。所以,有某个中介公司 C,发现了这个商机。C公司专门开设了一项“代理公章”的业务。
今后,A 公司的业务员去 B 公司,需要带2个介绍信:
介绍信1:含有 C 公司的公章及 A 公司的公章。并且特地注明:C 公司信任 A 公司。
介绍信2:仅含有 A 公司的公章,然后写上:兹有张三先生前往贵公司办理业务,请给予接洽……云云。
某些不开窍的同学会问了,这样不是增加麻烦了吗?有啥好处捏?
主要的好处在于,对于接待公司的前台,就不需要记住各个公司的公章分别是啥样子的;他/她只要记住中介公司 C 的公章即可。当他/她拿到两份介绍信之后,先对介绍信1的 C 公章,验明正身;确认无误之后,再比对介绍信1和介绍信2的两个 A 公章是否一致。如果是一样的,那就可以证明介绍信2是可以信任的了。
PKI 公钥基础设施
PKI借助数字证书和公钥加密技术提供可信任的网络身份。通常,证书就是一个包含如下身份信息的文件:
证书所有组织的信息 公钥 证书颁发组织的信息 证书颁发组织授予的权限,如证书有效期、适用的主机名、用途等 使用证书颁发组织私钥创建的数字签名
X.509证书包含三个文件:
- key 是服务器上的私钥文件:用于对发送给客户端数据的加密,以及对从客户端接收到数据的解密;
- csr 是证书签名请求文件:用于提交给证书颁发机构(CA)对证书签名
- crt 是由证书颁发机构(CA)签名后的证书或者是开发者自签名的证书:包含证书持有人的信息,持有人的公钥,以及签署者的签名等信息
备注:在密码学中,X.509是一个标准,规范了公开秘钥认证、证书吊销列表、授权凭证、凭证路径验证算法等。
CA(Certification Authority)证书,指的是权威机构给我们颁发的证书。
密钥就是用来加解密用的文件或者字符串。密钥在非对称加密的领域里,指的是私钥和公钥,他们总是成对出现,其主要作用是加密和解密。常用的加密强度是2048bit。
RSA即非对称加密算法。非对称加密有两个不一样的密码,一个叫私钥,另一个叫公钥,用其中一个加密的数据只能用另一个密码解开,用自己的都解不了,也就是说用公钥加密的数据只能由私钥解开。
证书的编码格式 PEM(Privacy Enhanced Mail),通常用于数字证书认证机构(Certificate Authorities,CA),扩展名为.pem, .crt, .cer, 和 .key。内容为Base64编码的ASCII码文件,有类似的头尾标记服务器认证证书。
代码语言:javascript复制"-----BEGIN CERTIFICATE-----"
"-----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,国家,城市,域名等。
0x01 自签名SSL证书生成
默认情况下,所有基于Linux和Unix的系统上都存在Openssl实用程序, 我们可以基于此创建自签名证书。
WeiyiGeek.selfCertificate
1.在线(脚本)生成
方式1.脚本生成即一键生成自签名SSL证书和私钥 脚本地址: https://github.com/cookcodeblog/OneDayDevOps/blob/master/components/ssl/create_self_signed_cert.sh Syntax:
代码语言:javascript复制./create_self_signed_cert.sh "/C=CN/ST=Chongqing/L=Chongqing/O=xdevops/OU=WeiyiGeek/CN=gitlab.WeiyiGeek.top"
2.OpenSSL 生成
(1) OpenSSL生成带有SubjectAltName的自签名SSL证书 描述:适用于安装了OpenSSL的服务器或者Linux;
代码语言:javascript复制# 1.验证OpenSSL版本
openssl version || apt install openssl -y
# 2.生成私钥(需输入4位以上密码)
# genra 生成RSA私钥
# -des3 des3算法
# -out server.key 生成的私钥文件名
# 2048 私钥长度
openssl genrsa -des3 -out server.pass.key 2048
# 3.去除私钥中的密码
# 注意:有密码的私钥是server.pass.key,没有密码的私钥是server.key
openssl rsa -in server.pass.key -out server.key
# 4.生成CSR(证书签名请求)
# req 生成证书签名请求
# -new 新生成
# -key 私钥文件
# -out 生成的CSR文件
# -subj 生成CSR证书的参数
# -subj 参数说明如下:
# 字段 字段含义 示例
# /C= Country 国家 CN
# /ST= State or Province 省 Chongqing
# /L= Location or City 城市 Guangzhou
# /O= Organization 组织或企业 WeiyiGeek
# /OU= Organization Unit 部门 WeiyiGeek
# /CN= Common Name 域名或IP gitlab.WeiyiGeek.top
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Chongqing/L=Chongqing/O=xdevops/OU=WeiyiGeek/CN=gitlab.WeiyiGeek.top"
# 另外一种方式使用OpenSSL生成带有SubjectAltName的自签名证书
# 首先新建一个配置文件 ssl.conf如下
cat <<'EOF' > server.conf
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = req_ext
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = CN
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = ChongQing
localityName = Locality Name (eg, city)
localityName_default = ChongQing
organizationName = Organization Name (eg, company)
organizationName_default = weiyigeek
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
commonName_default = hub.weiyigeek.top
[ req_ext ]
subjectAltName = @alt_names
[alt_names]
DNS.1 = weiyigeek.top
DNS.2 = hub.weiyigeek.top
IP = 10.10.107.201
EOF
openssl req -new -sha256 -out server.csr -key server.key -config server.conf
# 查看请求签发证书的内容
# openssl req -text -noout -in server.csr
# 5.生成自签名SSL证书 以及带有 SAN 的SSL证书 (有效期十年)
openssl x509 -req -days 3650 -in server.csr -signkey server.key -out gitla.bweiyigeek.top.crt
openssl x509 -req -days 3650 -in server.csr -signkey server.key -out hub.weiyigeek.top.crt -extensions req_ext -extfile server.conf
# 6.采用合并的方式获得pem格式证书
cat server.crt server.key > server.pem
# 7.证书内容查看
openssl x509 -text -noout -in hub.weiyigeek.top.crt
(2) 生成CA证书并签发子证书
步骤 01.生成CA根证书,首先我们需要准备一个CA配置文件.
代码语言:javascript复制cat <<'EOF' > ca.conf
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = CN
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = ChongQing
localityName = Locality Name (eg, city)
localityName_default = ChongQing
organizationName = Organization Name (eg, company)
organizationName_default = weiyigeek
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
commonName_default = ca.weiyigeek.top
EOF
步骤 02.生成ca密钥(ca.key),并生成ca证书签发请求得到(ca.csr)。
代码语言:javascript复制openssl genrsa -out ca.key 4096
openssl req -new -sha256 -out ca.csr -key ca.key -config ca.conf # 因为配置文件中已经有默认值了所以此处不用设置-subj参数
步骤 03.生成ca根证书有效期十年并得到ca.crt证书
代码语言:javascript复制openssl x509 -req -days 3650 -in ca.csr -signkey ca.key -out ca.crt
步骤 04.准备生成终端用户证书(子证书),同样首先准备 server.conf 文件。
代码语言:javascript复制cat <<'EOF' > server.conf
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = req_ext
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = CN
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = ChongQing
localityName = Locality Name (eg, city)
localityName_default = ChongQing
organizationName = Organization Name (eg, company)
organizationName_default = weiyigeek
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
commonName_default = www.weiyigeek.top
[ req_ext ]
subjectAltName = @alt_names
[alt_names]
DNS.1 = weiyigeek.top
DNS.2 = www.weiyigeek.top
IP = 192.168.1.254
EOF
温馨提示: Chrome 58以后不再使用CN校验地址(就是就是浏览器地址栏URL中的那个地址host)了而是使用SAN,所以此处需要指定subjectAltName。
步骤 05.生成秘钥以及证书签发请求文件。
代码语言:javascript复制openssl genrsa -out server.key 2048
openssl req -new -sha256 -out server.csr -key server.key -config server.conf
步骤 06.利用CA证书、密钥进行签发终端用户证书(子证书).
代码语言:javascript复制openssl x509 -req -days 3650 -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt -extensions req_ext -extfile server.conf
在服务端配置SSL常规流程:
- 1.声明开启HTTPS (SSL认证)
- 2.声明侦听443端口(并确保已在防火墙上打开443端口)
- 3.复制已签名的SSL证书和私钥到指定位置,并设置正确的文件权限
- 4.配置已签名的SSL证书(.crt)的位置
- 5.配置已签名的SSL证书私钥(.key)的位置
- 6.配置将HTTP请求都重定向到HTTPS
在浏览器中打开https://<domain_name>
来访问。
在Firefox浏览器中可以添加Security Exception来忽略HTTPS错误警告,Chrome浏览器可以尝试通过导入CA证书的方式来忽略HTTPS错误警告。 注意Chrome浏览器可能有导入CA证书后仍然无法访问的问题;
总结
- 1.自签名的SSL证书存在安全隐患,在生产环境上需要购买和使用经权威机构认证和办法的证书。
- 2.不同浏览器对自签名SSL证书的检查和限制也有所区别。
补充参考: https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/auth/client-certs/README.md#creating-certificate-secrets
代码语言:javascript复制TLS certificates
Unless otherwise mentioned, the TLS secret used in examples is a 2048 bit RSA key/cert pair with an arbitrarily chosen hostname, created as follows
$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
Generating a 2048 bit RSA private key
................
................
writing new private key to 'tls.key'
-----
$ kubectl create secret tls tls-secret --key tls.key --cert tls.crt
secret "tls-secret" created
Note: If using CA Authentication, described below, you will need to sign the server certificate with the CA.
Client Certificate Authentication
CA Authentication also known as Mutual Authentication allows both the server and client to verify each others identity via a common CA.
We have a CA Certificate which we obtain usually from a Certificate Authority and use that to sign both our server certificate and client certificate. Then every time we want to access our backend, we must pass the client certificate.
These instructions are based on the following blog
Generate the CA Key and Certificate:
openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 356 -nodes -subj '/CN=My Cert Authority'
Generate the Server Key, and Certificate and Sign with the CA Certificate:
openssl req -new -newkey rsa:4096 -keyout server.key -out server.csr -nodes -subj '/CN=mydomain.com'
openssl x509 -req -sha256 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
Generate the Client Key, and Certificate and Sign with the CA Certificate:
openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr -nodes -subj '/CN=My Client'
openssl x509 -req -sha256 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt
Once this is complete you can continue to follow the instructions here
3.CFSSL 生成
简单介绍: cfssl是CloudFlare开源的一款PKI/TLS工具。CFSSL 包含一个命令行工具和一个用于签名、验证并且捆绑TLS证书的HTTP API 服务, 使用Go语言编写。 项目地址: https://github.com/cloudflare/cfssl 下载地址: https://pkg.cfssl.org/
CFSSL 组件包括:
- 用于生成自定义 TLS PKI 的工具
- cfssl程序,是cfssl的命令行工具
- multirootca程序是可以使用多个签名密钥的证书颁发机构服务器
- mkbundle程序用于构建证书池
- cfssljson程序,从cfssl和multirootca程序获取JSON输出,并将证书,密钥,CSR和bundle写入磁盘
cfssl 安装 此处我们只安装cfssl工具、cfssljson工具和cfssl-certinfo工具。
代码语言:javascript复制# cfssl 最新下载地址: https://github.com/cloudflare/cfssl/releases
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssl_1.6.1_linux_amd64 -o /usr/local/bin/cfssl
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssljson_1.6.1_linux_amd64 -o /usr/local/bin/cfssljson
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssl-certinfo_1.6.1_linux_amd64 -o /usr/local/bin/cfssl-certinfo
# chmod x /usr/local/bin/cfssl*
温馨提示: 如出现如下警告请注意你的cfssl版本,并将cfssl版本从v1.2更新到v1.6.1(最新版本)。
代码语言:javascript复制2022/04/27 19:11:37 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
cfssl 常用子命令 描述: cfssl用法参考地址(https://coreos.com/os/docs/latest/generate-self-signed-certificates.html)
代码语言:javascript复制(0) print-defaults: 打印默认配置,这个默认配置可以用作模板
(1) gencert: 生成新的key(密钥)和签名证书.
-initca: 初始化新CA
-ca:指明ca的证书.
-ca-key:指明ca的私钥文件.
-config:指明请求证书的json文件.
-profile:与-config中的profile对应,是指根据config中的profile段来生成证书的相关信息.
(2) certinfo: 输出给定证书的证书信息, 跟cfssl-certinfo 工具作用一样
bundle: 创建包含客户端证书的证书包
genkey: 生成一个key(私钥)和CSR(证书签名请求)
scan: 扫描主机问题
revoke: 吊销证书
gencrl: 生成新的证书吊销列表
selfsign: 生成一个新的自签名密钥和 签名证书
serve: 启动一个HTTP API服务
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)。
cfssljson 常用子命令
代码语言:javascript复制Usage of cfssljson:
-bare : 来自CFSSL的响应未包装在API标准响应中
-f string: JSON input (default "-")
-stdout: 输出响应Response到终端中,而不是保存到文件。
0x03 cfssl 使用实践
示例1.使用 CFSSL 创建 CA 认证步骤。
步骤 01.生成并配置证书生成策略.
代码语言:javascript复制# 1.打印config模板文件从而进行修改, 其中有两个配置
cfssl print-defaults config > ca-config.json
vim ca-config.json
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"kubernetes": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
},
"harbor": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
# 注意: 该策略文件,有一个default默认的配置和一个profiles,其中profiles可以设置多个profile,例如此处的kubernetes和harbor配置
# 重点参数解析
default 默认策略,指定了证书的默认有效期是一年(8760h)
profile 自定义策略配置
* kubernetes:表示该配置(profile)的用途是为kubernetes生成证书及相关的校验工作
* signing:表示该证书可用于签名其它证书;生成的 ca.pem 证书中 CA=TRUE
* server auth:表示可以该CA 对 server 提供的证书进行验证
* client auth:表示可以用该 CA 对 client 提供的证书进行验证
* expiry:也表示过期时间,如果不写以default中的为准
步骤 02.CA证书签名请求配置文件 ca-csr.json 生成与设置。
代码语言:javascript复制# 1.首先打印csr模板文件输出到ca-csr.json,并进行修改
cfssl print-defaults csr > ca-csr.json
vim ca-csr.json
{
"CN": "weiyigeek.top",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "ChongQing",
"ST": "ChongQing",
"O": "weiyigeek",
"OU": "weiyigeek.top"
}
]
}
# 2.关键参数介绍:
CN: Common Name,浏览器使用该字段验证网站是否合法,一般写的是域名,非常重要。浏览器使用该字段验证网站是否合法
key:生成证书的算法
hosts:表示哪些主机名(域名)或者IP可以使用此csr申请的证书,为空或者""表示所有的都可以使用(本例中没有`"hosts": [""]`字段)
names:常见属性设置
* C: Country, 国家
* ST: State,州或者是省份
* L: Locality Name,地区,城市
* O: Organization Name,组织名称,公司名称(在k8s中常用于指定Group,进行RBAC绑定)
* OU: Organization Unit Name,组织单位名称,公司部门
步骤 03.生成CA证书和私钥(root根证书和私钥
)
注意: 运行认证中心需要一个 CA 证书和相应的 CA 私钥, 任何知道私钥的人都可以充当CA来颁发证书, 因此私钥的保护至关重要。
# 1.利用CA证书签名请求配置文件 ca-csr.json ,生成CA证书和CA私钥和CSR(证书签名请求):
# cfssl gencert -initca -hostname weiyigeek.top csr.json | cfssljson -bare ca
$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca
# 2022/01/17 22:02:40 [INFO] generating a new CA key and certificate from CSR
# 2022/01/17 22:02:40 [INFO] generate received request
# 2022/01/17 22:02:40 [INFO] received CSR
# 2022/01/17 22:02:40 [INFO] generating key: rsa-2048
# 2022/01/17 22:02:41 [INFO] encoded CSR
# 2022/01/17 22:02:41 [INFO] signed certificate with serial number 581660836920751122545368670593588896183219270559
# 2.生成的CA证书、私钥、以及签名请求证书,后续将用于交叉签名或重新签名。
/tmp/pki$ ls
ca-config.json ca.csr(签名请求证书) ca-csr.json ca-key.pem(CA私钥) ca.pem (CA证书)
步骤 04.利用certinfo子命令查看证书签名请求信息、证书信息。
代码语言:javascript复制# 查看cert(证书信息):
cfssl certinfo -cert ca.pem
{
"subject": {
"common_name": "weiyigeek.top",
"country": "CN",
"organization": "weiyigeek",
"organizational_unit": "weiyigeek.top",
"locality": "ChongQing",
"province": "ChongQing",
"names": [
"CN",
"ChongQing",
"ChongQing",
"weiyigeek",
"weiyigeek.top",
"weiyigeek.top"
]
},
"issuer": {
"common_name": "weiyigeek.top",
"country": "CN",
"organization": "weiyigeek",
"organizational_unit": "weiyigeek.top",
"locality": "ChongQing",
"province": "ChongQing",
"names": [
"CN",
"ChongQing",
"ChongQing",
"weiyigeek",
"weiyigeek.top",
"weiyigeek.top"
]
},
"serial_number": "581660836920751122545368670593588896183219270559",
"not_before": "2022-01-17T13:58:00Z",
"not_after": "2027-01-16T13:58:00Z",
"sigalg": "SHA256WithRSA",
"authority_key_id": "6A:EC:E5:BA:36:AF:D2:2A:2:35:B3:90:D3:31:7:A7:91:9D:E1:90",
"subject_key_id": "6A:EC:E5:BA:36:AF:D2:2A:2:35:B3:90:D3:31:7:A7:91:9D:E1:90",
"pem": "-----BEGIN CERTIFICATE-----n*****证书内容base64编码****n-----END CERTIFICATE-----n"
}
# 查看CSR(证书签名请求)信息:
cfssl certinfo -csr ca.csr
# 或者利用 openssl x509 命令查看证书相关信息。
openssl x509 -in ca.pem -text -noout
# Certificate:
# Data:
# Version: 3 (0x2)
# Serial Number:
# 65:e2:92:f1:bc:bd:86:f8:41:c5:ad:f1:cc:aa:46:b2:9f:c2:33:9f
# Signature Algorithm: sha256WithRSAEncryption
# Issuer: C = CN, ST = ChongQing, L = ChongQing, O = weiyigeek, OU = weiyigeek.top, CN = weiyigeek.top
# Validity
# Not Before: Jan 17 13:58:00 2022 GMT
# Not After : Jan 16 13:58:00 2027 GMT
# Subject: C = CN, ST = ChongQing, L = ChongQing, O = weiyigeek, OU = weiyigeek.top, CN = weiyigeek.top
示例2.利用CA认证中心证书签发 Kubernetes 集群apiserver认证使用的证书。
代码语言:javascript复制# 1.创建 kubernetes-csr.json 证书配置请求文件。
tee kubernetes-csr.json << 'EOF'
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"localhost",
"192.168.12.128",
"192.168.12.126",
"192.168.12.127",
"10.99.0.1",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local",
"*.kubernetes.master"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "ChongQing",
"L": "ChongQing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
# 2.利用 ca-config.json配置中kubernetes模板, 生成 Kubernetes 证书和私钥。
# -config : 引用的是模板中的默认配置文件,
# -profiles : 是指定特定的使用场景,比如config.json中的kubernetes区域
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes
2022/01/18 11:23:02 [INFO] generate received request
2022/01/18 11:23:02 [INFO] received CSR
2022/01/18 11:23:02 [INFO] generating key: rsa-2048
2022/01/18 11:23:02 [INFO] encoded CSR
2022/01/18 11:23:02 [INFO] signed certificate with serial number 146326072922083487956554573890123805193577034490
# 3.查看生成的证书与密钥
$ ls kubernetes*
kubernetes.csr kubernetes-csr.json kubernetes-key.pem kubernetes.pem
$ openssl x509 -in kubernetes.pem -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
19:a1:7c:f0:3e:ab:16:45:9a:c1:77:de:a4:b7:3e:d0:b0:49:f2:fa
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = CN, ST = ChongQing, L = ChongQing, O = weiyigeek, OU = weiyigeek.top, CN = weiyigeek.top
Validity
Not Before: Jan 18 03:18:00 2022 GMT
Not After : Jan 16 03:18:00 2032 GMT # 证书有效期十年。
Subject: C = CN, ST = ChongQing, L = ChongQing, O = k8s, OU = System, CN = kubernetes
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
# 4.创建 admin 证书请求文件admin-csr.json并生成相应的证书、私钥文件。
$ tee admin-csr.json <<'EOF'
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "ChongQing",
"L": "ChongQing",
"O": "system:masters",
"OU": "System"
}
]
}
EOF
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
# 5.同样使用相同方法生成kube-proxy证书,创建 kube-proxy-csr.json 证书配置文件。
$ tee kube-proxy-csr.json <<'EOF'
{
"CN": "system:kube-proxy",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "ChongQing",
"L": "ChongQing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy.json | cfssljson -bare kube-proxy
# 此时生成了 kube-proxy-key.pem 和 kube-proxy.pem。
# 关键参数说明:
- hosts: 包含的是授权范围,不在此范围的的节点(Master/Node)或者服务使用此证书就会报证书不匹配错误, 其中10.99.0.1是 kube-apiserver 指定的 service-cluster-ip-range 网段的第一个IP。
- apiserver: 该证书属于 apiserver 加了一个 *.kubernetes.master域名以便内部私有 DNS 解析使用,于很多人问过 kubernetes 这几个能不能删掉,答案是不可以的;因为当集群创建好后,default namespace 下会创建一个叫 kubenretes 的svc,有一些组件会直接连接这个 svc 来跟 api 通信的,证书如果不包含可能会出现无法连接的情况。
- 注意组织名称: 例如 admin证书 是用于将来生成管理员用的kubeconfig 配置文件用的,现在我们一般建议使用 RBAC 来对kubernetes 进行角色权限控制, 所以kubernetes 将证书中的CN字段作为User, O 字段作为 Group。
示例3.利用CA认证中心证书签发 harbor 仓库证书
代码语言:javascript复制# 1.准备一份harbor证书配置请求文件。
tee harbor-csr.json <<'EOF'
{
"CN": "harbor.weiyigeek.top",
"hosts": [
"127.0.0.1",
"192.168.12.108",
"harbor.weiyigeek.top"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "ChongQing",
"ST": "ChongQing",
"O": "weiyigeek",
"OU": "weiyigeek.top"
}
]
}
EOF
# 2.利用CA签发 harbor 仓库使用的服务端证书。
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=harbor harbor-csr.json | cfssljson -bare harbor
# 2022/01/18 14:20:23 [INFO] generate received request
# 2022/01/18 14:20:23 [INFO] received CSR
# 2022/01/18 14:20:23 [INFO] generating key: rsa-2048
# 2022/01/18 14:20:23 [INFO] encoded CSR
# 2022/01/18 14:20:23 [INFO] signed certificate with serial number 633490963371902710405149722919884501418274711654
# 3.生成的对应的证书签名请求文件(harbor.csr)、证书文件、证书私钥。
$ ls harbor*
harbor.csr harbor-csr.json harbor-key.pem harbor.pem
# 4.证书相关信息查询
# 证书信息查看
cfssl certinfo -cert harbor.pem
# 证书签名请求文件查看
cfssl certinfo -csr harbor.csr
# 在线请求指定域名配置的证书相关信息。
$ cfssl certinfo -domain harbor.weiyigeek.top
至此cfssl使用实践完毕!