openssl/cfssl 自签证书

搭建各种云原生环境的过程中,经常需要生成证书,本文记录使用 openssl/cfssl 快速生成证书的方法。

使用 opessl 生成证书

测试证书: openssl s_client -connect 1.1.1.1:443 2> /dev/null | openssl x509 -text | grep -A 1 “X509v3 Subject Alternative Name:”

1
2
3
4
5
6
7
8
9
# 0.一气呵成,不产生csr
$ openssl req -newkey rsa:4096 \
-subj "/C=CN/ST=ZheJiang/L=HangZhou/O=ZMQ/OU=ZMQ Group/CN=*.zmq100.cn/emailAddress=zmq@zmq100.cn" \
-x509 \
-sha256 \
-days 3650 \
-nodes \
-out server.crt \
-keyout server.key

自签服务器证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 1.生成私钥
$ openssl genrsa -out server.key 4096

# 2.生成 CSR (Certificate Signing Request)
$ openssl req \
-subj "/C=CN/ST=ZheJiang/L=HangZhou/O=ZMQ/OU=ZMQ Group/CN=*.zmq100.cn/emailAddress=zmq@zmq100.cn" \
-new \
-key server.key \
-out server.csr

# 3.生成自签名证书
$ openssl x509 \
-req \
-days 3650 \
-in server.csr \
-signkey server.key \
-out server.crt

# 查看crt证书的文件格式
$ openssl x509 -in server.crt -text

# 查看csr证书的文件格式
$ openssl req -in server.csr -text

通过私有 CA 签名服务器证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 1.创建 CA 私钥
$ openssl genrsa -out ca.key 2048

# 2.生成 CA 的自签名证书
$ openssl req \
-subj "/C=CN/ST=ZheJiang/L=HangZhou/O=ZMQ/OU=ZMQ Software/CN=Server CA/emailAddress=zmq@zmq100.cn" \
-new \
-x509 \
-days 3650 \
-key ca.key \
-out ca.crt

# 3.生成需要颁发证书的私钥
$ openssl genrsa -out server.key 2048

# 4.生成要颁发证书的证书签名请求,证书签名请求当中的 Common Name 必须区别于 CA 的证书里面的 Common Name
$ openssl req \
-subj "/C=CN/ST=ZheJiang/L=HangZhou/O=ZMQ/OU=ZMQ Software/CN=*.zmq100.cn/emailAddress=zmq@zmq100.cn" \
-new \
-key server.key \
-out server.csr

# 5.用 2 创建的 CA 证书给 4 生成的 签名请求 进行签名
$ openssl x509 \
-req \
-days 3650 \
-in server.csr \
-CA ca.crt \
-CAkey ca.key \
-set_serial 01 \
-out server.crt

SAN证书文件方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# 1. 创建ca证书
$ openssl genrsa -out ca.key 4096
$ openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
$ openssl genrsa -out server.key 4096

# 2. Subject Alt Name(SAN)
# 高版本的Chrome浏览器会要求设置subjectAltName,如果没有设置SAN会报证书错误
# 参考openssl配置文件,Linux服务器上通常在/etc/pki/tls/openssl.cnf
# 新建包含san信息的文件san.conf使用
$ cat > san.conf << EOF
[req]
default_bits = 4096
distinguished_name = req_distinguished_name
req_extensions = v3_req

[req_distinguished_name]
countryName = country
stateOrProvinceName = stateOrProvince
localityName = locality
organizationName = organization
commonName = commonName

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1=*.zmq100.cn #可以使用通配符
IP.1=127.0.0.1
EOF

# 3. 用新的包含san的conf 生成证书签名请求(CSR)
# 生成csr 注意要使用sha256算法(推荐是sha256算法,默认算法浏览器会报弱加密算法错误)
$ openssl req -new -key server.key -out server.csr -config san.conf -sha256

# 4. 查看csr信息
$ openssl req -text -in server.csr
...
Requested Extensions:
X509v3 Subject Alternative Name:
DNS:*.zmq100.cn, IP Address:127.0.0.1

# 5. 使用根证书按照csr给证书签名,生成新证书server.crt
# 这里serial参数需要全局唯一,否则在同一台设备上使用serial值相同的证书会冲突。
$ openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt -extfile san.conf -extensions v3_req

# 6. 查看证书信息
$ openssl x509 -text -in server.crt
...
Requested Extensions:
X509v3 Subject Alternative Name:
DNS:*.zmq100.cn, IP Address:127.0.0.1

SAN证书命令行方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ openssl genrsa -out ca.key 4096
$ openssl req -new -x509 -days 36500 -key ca.key -sha256 -subj "/CN=ZMQ CA" -out ca.crt
$ openssl genrsa -out server.key 4096

$ openssl req -new -sha256 \
-key server.key \
-subj "/CN=ZMQ server" \
-reqexts SAN \
-config <(cat /etc/pki/tls/openssl.cnf \
<(printf "\n[SAN]\nsubjectAltName=DNS:www.zmq100.cn,DNS:zmq100.cn,IP:127.0.0.1")) \
-out server.csr

$ openssl x509 -req -days 36500 \
-in server.csr -out server.crt \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-extensions SAN \
-extfile <(cat /etc/pki/tls/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:www.zmq100.cn,DNS:zmq100.cn,IP:127.0.0.1"))

使用 cfssl 生成证书

安装 cfssl

1
2
3
4
5
$ sudo wget -O /usr/local/bin/cfssl  \
https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssl_1.6.4_linux_amd64
$ sudo wget -O /usr/local/bin/cfssljson \
https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssljson_1.6.4_linux_amd64
$ sudo chmod +x /usr/local/bin/cfssl*

生成证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# 1. 创建ca证书json信息
$ cat > ca-csr.json <<EOF
{
"CN": "Kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "ZheJian",
"L": "HangZhou",
"O": "Kubernetes",
"OU": "CA"
}
]
}
EOF

# 2. 通过json信息,创建CA的key和pem和csr请求文件
$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca

# 3. 查看文件ca证书
$ ls ca*
ca.csr ca-csr.json ca-key.pem ca.pem

# 4. 证书签发配置,用 CA 证书来签发其它证书时需要用
$ cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "876000h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "876000h"
}
}
}
}
EOF


# 5. 创建server证书json信息
$ cat > server-csr.json <<EOF
{
"CN": "zmq",
"hosts": [
"*.zmq100.cn",
"127.0.0.1"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "ZheJian",
"L": "HangZhou",
"O": "Kubernetes",
"OU": "CA"
}
]
}
EOF

# 6. 用CA创建server的key、pem、csr请求文件
$ cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
server-csr.json | cfssljson -bare server

# 7. 查看server证书
$ ls server*
server.csr server-csr.json server-key.pem server.pem

Linux客户端信任自签证书

1
2
$ cp ca.crt /etc/pki/ca-trust/source/anchors
$ update-ca-trust extract

参考&转载:
https://www.jianshu.com/p/24ed15c973ec
https://www.jianshu.com/p/e5f46dcf4664
https://imroc.cc/kubernetes/trick/certs/sign-certs-with-cfssl.html
https://www.cnblogs.com/274914765qq/p/4674492.html
https://letsencrypt.org/zh-cn/docs/dst-root-ca-x3-expiration-september-2021/
https://docs.openssl.org/1.1.1/man3/SSL_CTX_set_security_level/#default-callback-behaviour
https://stackoverflow.com/questions/38015537/python-requests-exceptions-sslerror-dh-key-too-small