下面是一个完整 openssl.cnf 配置文件

ini
  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
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
BASE_DOMAIN=
CLUSTER_NAME=
CERT_DIR=
APISERVER_CLUSTER_IP=
MASTER_NAME=

[ ca ]
# man ca
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
dir               = \${ENV::CERT_DIR}
certs             = \$dir
crl_dir           = \$dir/crl
new_certs_dir     = \$dir
database          = \$dir/index.txt
serial            = \$dir/serial
# certificate revocation lists.
crlnumber         = \$dir/crlnumber
crl               = \$dir/crl/intermediate-ca.crl
crl_extensions    = crl_ext
default_crl_days  = 30
default_md        = sha256

name_opt          = ca_default
cert_opt          = ca_default
default_days      = 375
preserve          = no
policy            = policy_loose

[ policy_loose ]
# Allow the CA to sign a range of certificates.
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
# man req
default_bits        = 4096
distinguished_name  = req_distinguished_name
string_mask         = utf8only
default_md          = sha256

[ req_distinguished_name ]
countryName                    = Country Name (2 letter code)
stateOrProvinceName            = State or Province Name
localityName                   = Locality Name
0.organizationName             = Organization Name
organizationalUnitName         = Organizational Unit Name
commonName                     = Common Name

# Certificate extensions (man x509v3_config)

[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ client_cert ]
basicConstraints = CA:FALSE
nsCertType = client
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, serverAuth
subjectAltName = @etcd_client

[ server_cert ]
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth

[ identity_server_cert ]
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = DNS.1:tectonic-identity-api.tectonic-system.svc.cluster.local

[ etcd_server_cert ]
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @etcd_server_and_peer_dns

[ etcd_peer_cert ]
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @etcd_server_and_peer_dns

[ apiserver_cert ]
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @apiserver_names

[ master_component_client_cert ]
basicConstraints = CA:FALSE
nsCertType = client
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
subjectAltName = @master_component_names


[etcd_server_and_peer_dns]
DNS.1 = \${ENV::BASE_DOMAIN}
DNS.2 = localhost
IP.1 = 10.0.0.5
IP.2 = 127.0.0.1
IP.3 = 127.0.0.5

[apiserver_names]
DNS.1 = \${ENV::CLUSTER_NAME}-\${ENV::BASE_DOMAIN}
DNS.2 = \${ENV::BASE_DOMAIN}
DNS.3 = kubernetes
DNS.4 = kubernetes.default
DNS.5 = kubernetes.default.svc
DNS.6 = kubernetes.default.svc.cluster.local
IP.1 = \${ENV::APISERVER_CLUSTER_IP}
IP.2 = 10.0.0.5
IP.3 = 10.0.0.4


[ master_component_names ]
DNS.1 = \${ENV::MASTER_NAME}.\${ENV::BASE_DOMAIN}
DNS.2 = \${ENV::BASE_DOMAIN}
IP.1 = 10.0.0.5
IP.2 = 10.0.0.4

# used for etcd_client
[ etcd_client ]
DNS.1 = localhost
IP.1 = 10.0.0.5
IP.2 = 10.0.0.4
IP.3 = 10.0.0.6
IP.4 = 127.0.0.1

环境变量部分,用于定义配置文件内的配置会读取这个环境变量来替换

ini
1
2
3
4
5
BASE_DOMAIN=                  # 基础域名,通常用于 Kubernetes 集群或 API 服务器的域名配置
CLUSTER_NAME=                 # 集群名称,通常作为集群的标识符
CERT_DIR=                     # 证书文件存放的目录
APISERVER_CLUSTER_IP=         # API 服务器的集群内部 IP 地址
MASTER_NAME=                  # Kubernetes 主节点的名称

CA 配置部分

指定默认的 CA 配置部分,即下面的 [CA_default] 部分

conf
[ ca ]
default_ca = CA_default

[CA_default] 部分

该部分定义了 CA (证书颁发机构) 的各种配置参数。

ini
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Directory and file locations.
dir               = \${ENV::CERT_DIR}    # 证书存放的根目录
certs             = \$dir                 # 证书文件夹
crl_dir           = \$dir/crl             # CRL(证书吊销列表)文件夹
new_certs_dir     = \$dir                 # 新证书文件夹
database          = \$dir/index.txt       # 用于存储证书请求、签发等信息的数据库文件
serial            = \$dir/serial          # 用于跟踪签发证书的序列号文件
crlnumber         = \$dir/crlnumber       # CRL 证书吊销序列号
crl               = \$dir/crl/intermediate-ca.crl  # 吊销列表文件
crl_extensions    = crl_ext               # CRL 扩展配置
default_crl_days  = 30                    # 默认 CRL 有效期为 30 天
default_md        = sha256                # 默认使用 sha256 哈希算法
name_opt          = ca_default            # 证书的名称选项
cert_opt          = ca_default            # 证书的选项
default_days      = 375                   # 证书默认有效期为 375 天
preserve          = no                    # 是否保留 CA 对已签发证书的审计日志
policy            = policy_loose          # 使用 'policy_loose' 签发证书

[policy_loose] 部分

该部分定义了证书签发策略,允许一些字段为 optional,即证书可以包含这些字段,但不要求必须存在。

ini
1
2
3
4
5
6
7
countryName             = optional       # 国家名称可选
stateOrProvinceName     = optional       # 省/州名称可选
localityName            = optional       # 地市名称可选
organizationName        = optional       # 组织名称可选
organizationalUnitName  = optional       # 组织单位名称可选
commonName              = supplied       # 公共名称是必须提供的(通常是域名或主机名)
emailAddress            = optional       # 邮件地址可选

[req] 和 [req_distinguished_name] 部分

distinguished执意为,显著的,杰出的。用于生成证书请求(CSR)。配置了默认的密钥长度、签名算法等信息。

ini
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[ req ]
default_bits        = 4096           # 默认的密钥位数为 4096 位
distinguished_name  = req_distinguished_name  # 引用 'req_distinguished_name' 部分来定义 DN(区分名称)
string_mask         = utf8only       # 使用 UTF-8 字符编码
default_md          = sha256         # 默认使用 sha256 作为散列算法

[ req_distinguished_name ]
countryName                    = Country Name (2 letter code)  # 国家(2个字母的国家代码)
stateOrProvinceName            = State or Province Name      # 省/州名称
localityName                   = Locality Name               # 城市/地区名称
0.organizationName             = Organization Name           # 组织名称
organizationalUnitName         = Organizational Unit Name    # 组织单位名称
commonName                     = Common Name                 # 通用名称(通常是域名或主机名)

证书扩展部分

这些扩展是用于指定证书的用途和其它属性的配置,通常包括证书的使用场景(例如,客户端、服务器认证等)。

扩展部分的名字,例如[v3_ca] 并不是一个固定的格式,只是一个 OpenSSL 配置文件中的命名部分,通常用于定义颁发 CA(证书颁发机构)证书时所需要的扩展(extensions)。你可以根据需要自定义该部分的内容,但它通常包含一些通用的证书扩展,尤其是 基本约束 (basicConstraints)、密钥用法 (keyUsage) 和 证书签发权限

[v3_ca] 部分

该部分用于设置根证书(CA)的扩展,包括证书签发权限、密钥使用等。

bash
1
2
3
4
5
6
subjectKeyIdentifier = hash                     # 用于标识证书的主题密钥标识符
authorityKeyIdentifier = keyid:always,issuer    # 用于标识证书的颁发者密钥标识符
# 基本约束,标明该证书为 CA 证书,且路径长度为 0(不能作为其他证书的颁发机构)
# CA:true 表示这个为ca
basicConstraints = critical, CA:true, pathlen:0  
keyUsage = critical, digitalSignature, cRLSign, keyCertSign  # 证书使用场景:数字签名、证书吊销列表签名、证书签发

客户端、服务器证书扩展部分

这些部分定义了不同类型证书(如客户端证书、服务器证书)的扩展选项:

  • [client_cert][server_cert] 定义了客户端和服务器证书的基本约束和使用场景。
  • [identity_server_cert][etcd_server_cert] 定义了特定的服务器证书,通常用于指定 API 服务、etcd 服务等。

这些扩展中的 subjectAltName 字段用于指定证书的备用名称(例如,DNS 或 IP 地址),这是证书有效性的一个重要部分。

ini
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
[ client_cert ]
# 不允许作为 CA 证书使用
basicConstraints = CA:FALSE
# 客户端证书使用场景
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
# 扩展用途:客户端身份验证、服务器身份验证
extendedKeyUsage = clientAuth, serverAuth
# 使用 'etcd_client' 部分中定义内容用作的 SAN 配置
subjectAltName = @etcd_client


[ server_cert ]
# 不允许作为 CA 证书使用
basicConstraints = CA:FALSE
# 服务器证书使用场景
keyUsage = critical, digitalSignature, keyEncipherment
# 扩展用途:服务器身份验证、客户端身份验证
extendedKeyUsage = serverAuth, clientAuth
# 使用 'etcd_server_and_peer_dns' 配置
subjectAltName = @etcd_server_and_peer_dns
  • keyUsage:通常包括 digitalSignaturekeyEncipherment,表明证书可以用于签名和加密。
  • extendedKeyUsage:指定该证书可用于 serverAuth(服务器认证)和 clientAuth(客户端认证)。
  • subjectAltName:通常会列出服务器的 DNS 名称或 IP 地址,用于验证服务器身份。

extendedKeyUsage = serverAuth, clientAuth 同时设定时,表示该证书可以同时用于服务器身份验证和客户端身份验证。这意味着该证书可以被用于 服务器端 来验证客户端的请求,也可以被用作 客户端 来向服务器进行身份验证。例如 Mutual TLS,mTLS。

单独配置:extendedKeyUsage = serverAuthextendedKeyUsage = clientAuth 时:

  • extendedKeyUsage = serverAuth:表示证书的用途是 服务器身份验证,即浏览器可以用它来验证服务器的真实性,确保用户正在访问的是正确的、合法的服务器。此配置通常用于大多数网站的 SSL/TLS 服务器证书
  • extendedKeyUsage = clientAuth:表示证书仅用于客户端身份验证,例如用于 SSL/TLS 客户端证书。

Subject Alternative Name (SAN) 部分

SAN 是证书中的一个字段,允许将多个 DNS 名称、IP 地址或 URI 作为证书的有效域名或 IP 地址。它可以包含多个 DNS 名称和 IP 地址。

ini
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
[ etcd_server_and_peer_dns ]
DNS.1 = \${ENV::BASE_DOMAIN}             # 基础域名
DNS.2 = localhost                        # 本地主机名
IP.1 = 10.0.0.5                          # IP 地址
IP.2 = 127.0.0.1                         # 本地回环地址
IP.3 = 127.0.0.5                         # 另一个本地回环地址

[ apiserver_names ]
# 使用集群名称和基础域名组成的 DNS 名称
# 使用上面的变量
DNS.1 = \${ENV::CLUSTER_NAME}-\${ENV::BASE_DOMAIN}
# 基础域名
DNS.2 = \${ENV::BASE_DOMAIN}
# API 服务器的 IP 地址
IP.1 = \${ENV::APISERVER_CLUSTER_IP}
# 备用 IP 地址
IP.2 = 10.0.0.5