Web two-way ssl

说明

  • nginx 需正常支持 https
  • nginx 使用 ssl_client_certificate 配置用于验证客户端身份的 ca
  • 使用 ca 签发子证书,转换格式为 linux 可直接读取的 pfx 格式
  • 将证书导入允许访问的主机中,主机访问网站时选择证书文件,如果认证成功,可正常访问

生成证书

签发 CA

  • Ubuntu
1
2
3
openssl genrsa -out ca.key 4096
# go 1.15 以上版本被识别的 ssl 证书需配置 SANs,申请证书时需通过 addext 指定
openssl req -x509 -new -nodes -sha512 -days 36500  -addext "subjectAltName = DNS:*" -key ca.key  -out ca.crt -subj "/C=CN/O=decent/CN=*"
  • Centos
1
2
3
openssl genrsa -out ca.key 4096
# Centos7 使用低版本 openssl,不支持 -addext 参数,需使用其他方式配置 subjectAltName
ALTNAME="DNS:*" openssl req -x509 -new -nodes -sha512 -days 36500 -key ca.key  -out ca.crt -subj "/C=CN/O=decent/CN=*"

签发验证使用的证书

  • 生成证书申请
1
2
3
4
5
6
7
# DOMAIN 变量配置问 registry 将来要用的域名
DOMAIN=XXX.XXX.XXX
mkdir sub_certs
# 生成证书申请(Ubuntu
openssl req -newkey rsa:4096 -nodes -sha256 -subj "/CN=${DOMAIN}" -addext "subjectAltName = DNS:${DOMAIN}" -keyout sub_certs/${DOMAIN}.key -out sub_certs/${DOMAIN}.csr
# 生成证书申请(Centos7
ALTNAME="DNS:${DOMAIN}" openssl req -newkey rsa:4096 -nodes -sha256 -subj "/CN=${DOMAIN}" -keyout sub_certs/${DOMAIN}.key -out sub_certs/${DOMAIN}.csr
  • 签发证书

    • Centos:
    1
    
    openssl x509 -req -days 35600 -extfile <(printf "subjectAltName=DNS:${DOMAIN}")  -in sub_certs/${DOMAIN}.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out sub_certs/${DOMAIN}.crt 
    
    • Ubuntu 20+ openssl 不支持使用 -extfile < print 的方式申请证书,需通过写入文件并指定文件的方式签发证书
    1
    2
    
    echo "subjectAltName=DNS:$DOMAIN" > altsubj.ext
    openssl x509 -req -days 35600 -extfile altsubj.ext  -in sub_certs/${DOMAIN}.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out sub_certs/${DOMAIN}.crt
    
  • 更改证书格式,从 crt 更改为 pfx

1
2
cd sub_certs
openssl pkcs12 -export -out ${DOMAIN}.pfx -inkey ${DOMAIN}.key -in ${DOMAIN}.crt -certfile ../ca.crt

Nginx 配置

  • 将 ca 拷贝至 nginx certs 目录
1
2
cd /usr/local/platform/openresty/nginx/conf/certs/
sudo cp -rp ~/tmp/ca.crt ${DOMAIN}_ca.crt
  • nginx server 内配置 ssl_client_certificate
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
server {
    ssl_client_certificate certs/access_ssl_ca.crt;
    # optional 表示可验证客户端证书
    # on 表示强制验证客户端证书,如果证书验证失败,返回 400,当此域名下所有请求均需双向 ssl 认证时,可使用此配置
    ssl_verify_client optional;

	location ~* ^/admin {
	    # 需要限制 ssl 认证的请求,单独使用 if 校验是偶使用证书
        if ( $ssl_client_verify != "SUCCESS" )
        {
            return 403;
        }
        root /var/www/html;
    }
}
  • reload
1
sudo systemctl reload openresty

windows 客户端安装证书

  • 双击客户端证书 ${DOMAIN}.pfx 弹出证书导入向导,按照提示,下一步直至完成即可。

验证

  • 安装好证书后,浏览器第一次访问此域名时,会弹窗选择证书
  • 若选择错证书或未选择证书,可能造成无法访问的情况,这时需要将浏览器完全退出(kill掉所有进程)才可以进行更换