由于要测试一下客户端信任自定义证书,需要生成一个自定义的CA并配置给服务器。网上查找几篇教程,要么过时,要么行文混乱,经过反复测试,最终完成了目标,特此记录。
假设基本信息如下:
- 公司为:YourCompany
- 网址为:yourdomain.tech
1 生成根CA
openssl req -x509 -newkey rsa:4096 -subj "/C=CN/ST=JS/L=NJ/O=YourCompany Corporation/CN=YourCompany Root CA/emailAddress=yourdomain@yourdomain.tech" -keyout yourcompany_root_ca.key -out yourcompany_root_ca.cer -days 36500 -nodes
2 生成二级CA
首先编写一个包含CA基本配置的cloud_ca.conf文件,内容如下:
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = req_ext
[ req_distinguished_name ]
C=CN
ST=JS
L=NJ
O=YourCompany Corporation
CN=YourCompany Cloud CA
emailAddress=yourdomain@yourdomain.tech
[ req_ext ]
keyUsage = critical
extendedKeyUsage = TLS Web Server Authentication, TLS Web Client Authentication
basicConstraints = CA:FALSE
[ v3_req ]
keyUsage = critical
extendedKeyUsage = TLS Web Server Authentication, TLS Web Client Authentication
[ v3_ca ]
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
extendedKeyUsage = TLS Web Server Authentication, TLS Web Client Authentication
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
然后执行命令:
openssl req -newkey rsa:4096 -subj "/C=CN/ST=JS/L=NJ/O=YourCompany Corporation/CN=YourCompany Cloud CA/emailAddress=yourdomain@yourdomain.tech" -keyout yourcompany_cloud_ca.key -out yourcompany_cloud_ca.csr
openssl x509 -req -in yourcompany_cloud_ca.csr -extensions v3_req -extensions v3_ca -extfile cloud_ca.conf -CA yourcompany_root_ca.cer -CAkey yourcompany_root_ca.key -CAcreateserial -out yourcompany_cloud_ca.cer -days 36500
3 生成服务器证书
同样,首先编写一个包含证书基本配置的server.conf文件,内容如下:
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = req_ext
[ req_distinguished_name ]
C=CN
ST=JS
L=NJ
O=YourCompany Corporation
CN=*.yourdomain.com
OU=Server
emailAddress=yourdomain@yourdomain.tech
[ req_ext ]
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
basicConstraints = CA:FALSE
subjectAltName = @alt_names
[ v3_req ]
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[ v3_ca ]
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = www.yourdomain.com
DNS.2 = yourdomain.com
DNS.3 = *.yourdomain.com
注意配置文件中的CN的值和[ alt_names ]块下的内容,必须与服务器域名对应。
然后,执行命令:
openssl req -newkey rsa:4096 -subj "/C=CN/ST=JS/L=NJ/O=YourCompany Corporation/CN=*.yourdomain.com/OU=Server/emailAddress=yourdomain@yourdomain.tech" -keyout www.yourdomain.com.key -out www.yourdomain.com.csr
openssl x509 -req -in www.yourdomain.com.csr -extensions v3_req -extensions v3_ca -extfile server.conf -CA yourcompany_cloud_ca.cer -CAkey yourcompany_cloud_ca.key -CAcreateserial -out www.yourdomain.com.cer -days 36500
同样,需要注意,第一个命令中的 CN后面的值需要和服务器域名对应。
4 生成证书链
证书链其实就是把几个CA与证书内容放到一个文件中,从上到下依次是 服务器证书,二级CA,根CA。
使用上面的例子,就是新建一个文件 www.yourdomain.com.pem,依次把www.yourdomain.com.cer,yourcompany_cloud_ca.cer,yourcompany_root_ca.cer中的内容复制进去。
文件内容类似下面:
-----BEGIN CERTIFICATE-----
...
www.yourdomain.com.cer 内容
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
yourcompany_cloud_ca.cer 内容
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
yourcompany_root_ca.cer 内容
...
-----END CERTIFICATE-----
5 Nginx配置
我们需要把签名生成的 www.yourdomain.com.pem,www.yourdomain.com.key放到服务器相应目录下,同时要再添加一个 www.yourdomain.com.password文件,其中是生成服务器证书时的密码。
参考Nginx配置如下:
default.conf
server {
listen 443 ssl;
server_name www.yourdomain.com;
access_log /var/log/nginx/yourdomain.com.access.log main;
ssl_certificate conf.d/cert/www.yourdomain.com.pem;
ssl_certificate_key conf.d/cert/www.yourdomain.com.key;
# www.yourdomain.com.password中放的是生成证书时的密码
ssl_password_file conf.d/cert/www.yourdomain.com.password;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
#表示使用的加密套件的类型。
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; #表示使用的TLS协议的类型,您需要自行评估是否配置TLSv1.1协议。
ssl_prefer_server_ciphers on;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
server {
listen 80;
listen [::]:80;
server_name www.yourdomain.com;
rewrite ^(.*)$ https://$host$1;
access_log /var/log/nginx/yourdomain.com.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
6 信任根CA
因为这是我们自己生成的CA,所以操作系统不清楚该CA安全性,我们需要手动信任该CA。
我们直接双击前面生成的 yourcompany_root_ca.cer文件,为本地计算机,导入到“受信任的根证书颁发机构”。现在根CA系统已经信任了,由它签署的证书链上的证书都会被信任。
7 后记
至此,我们浏览器访问我们网站的https地址,应该就是安全的了。特殊情况下,根证书导入完成需要重启一下浏览器。
通过我们自己配置一遍,我们可以加深对https安全性机制的理解,同时也对签名机制有了更深刻的认识。
如果本篇教程对你有所帮助,请点赞支持。