• 使用 OpenSSL 为 Nginx 创建自签名证书 并开启客户端身份验证


    本文章默认读者了解Openssl,CA,网站证书相关知识,直接实战!配置完成后,浏览器会显示“安全的HTTPS”连接。不会像其他文章那样,是红色警告的证书提示。

    准备环境

    笔者使用的是Ubuntu16 ,其实什么系统都无所谓,请不要使用旧版Openssl就好,因为里面的漏洞实在太致命。

    #先创建一个文件夹
    mkdir openssl.Test
    cd openssl.Test
    mkdir -p ./demoCA/{private,newcerts} 
    touch demoCA/index.txt 
    touch demoCA/serial
    echo 01 > demoCA/serial
    #复制一份配置文件,可能会因系统不一致
    cp /etc/ssl/openssl.cnf .
    

    自建CA

    1 设置私钥

    openssl genrsa -des3 -out ./demoCA/private/cakey.pem 2048
    

    2 申请自签名证书
    根据提示一步步填写就好,但要记清楚填了什么,后面会用到

    openssl req -new -x509 -days 365 -key ./demoCA/private/cakey.pem -out ./demoCA/cacert.pem
    

    调整openssl.cnf

    调整openssl.cnf 用来支持v3扩展,以实现多域名及扩展用途(EKU)

    调整原因有二,一是让服务端证书支持多个二级域名,二是符合Chrome的证书检查,否则使用Chrome浏览时会提示不信任此证书

    用自己喜欢的编辑器打开openssl.cnf
    确保req下存在以下2行(默认第一行是有的,第2行被注释了)

    [ req ]
    distinguished_name = req_distinguished_name
    req_extensions = v3_req
    

    新增最后一行内容 subjectAltName = @alt_names(前2行默认存在)

    [ v3_req ]
    # Extensions to add to a certificate request
    basicConstraints = CA:FALSE
    keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    #设置扩展用途 (EKU) 可选
    #extendedKeyUsage = serverAuth,clientAuth
    subjectAltName = @alt_names
    

    新增 alt_names,注意括号前后的空格,DNS.x 的数量可以自己加,别忘了把申请证书时填写的域名(Common Name)加上

    [ alt_names ]
    DNS.1 = abc.example.com
    DNS.2 = dfe.example.org
    DNS.3 = ex.abcexpale.net
    

    创建服务端证书

    1 设置私钥

    openssl genrsa -out userkey.pem 2048
    

    2 创建证书申请
    提示 Common Name 时 请填写域名,不要设置密码,否则Nginx部分会有麻烦,国家,省份,城市,公司,部门要和创建CA填写的资料一致,当然在配置文件里调整策略能绕过此检查。本文尽量使用默认的配置来完成~~~,所以请保持一致。

    openssl req -new -days 365 -key userkey.pem -out userreq.pem
    

    3 签发

    openssl ca -in userreq.pem -out usercert.pem -extensions v3_req -config openssl.cnf
    

    4 查看证书

    openssl x509 -in usercert.pem -text -noout
    

    创建客户端证书

    与服务端类似

    openssl genrsa -out clientkey.pem 2048
    # Common name 随意写,设不设置密码随意
    openssl req -new -days 365 -key clientkey.pem -out clientreq.pem
    openssl ca -in clientreq.pem -out clientcert.pem -extensions v3_req -config openssl.cnf
    

    转换下格式,方便windows下导入

    openssl pkcs12 -export -inkey clientkey.pem -in clientcert.pem -out client.pfx
    

    浏览器端导入证书即可,忽略这句话的朋友,通常会遇到400的问题,无法自拔!

    Nginx

    Nginx 需要使用usercert.pem、userkey.pem、demoCA/cacert.pem,请读者自行拷贝出来。
    以下配置文件只是参考,实际情况请读者自行配置。
    PS:把证书和配置文件放在一个文件夹是不规范的行为,笔者图方便,仅做测试用

    配置文件

    server {
        listen       443 ssl;
        server_name  test.com;
    
        #charset koi8-r;
        #access_log  /var/log/nginx/host.access.log  main;
        
        ssl_certificate /etc/nginx/conf.d/usercert.pem;
        ssl_certificate_key /etc/nginx/conf.d/userkey.pem;
        ssl_client_certificate /etc/nginx/conf.d/cacert.pem;
        ssl_verify_client on;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    
        ......
    
    }
    

    Docker 启动

    docker run --rm --name nginx01 -p 443:443 -v /home/xxx/www/conf:/etc/nginx/conf.d nginx
    

    Windows打开证书配置管理器

    1 当前用户

    certmgr.msc
    

    2 本地计算机(win7及以下没有)

    certlm.msc
    

    CA证书导入到"本地计算机"->"受信任的根证书颁发机构"中
    客户端证书要从浏览器中导入哦!!!

    常见问题

    1 火狐浏览器 显示 不安全连接

    考虑是系统根证书被导入了一个劫持证书,Firefox 49 版本开始添加了一个参数,如果遇到未知的 CA 证书,浏览器可以直接对正在使用的 Windows 系统证书存储机制进行检查对比。
    在地址栏键入"about:config" 点击“我了解此风险”
    在下方任意位置右键,选择新建布尔值
    输入首选项名称为“security.enterprise_roots.enabled”并把值设置为 true
    重启浏览器,HTTPS 网站即可正常访问
    来源:百度贴吧

    2 Chrome 显示 400 状态码

    Ctrl + Shift + Del 清除缓存即可

    3 IE8.0 如果要求使用 客户端证书 好像会一直出现 400 状态码 ~~~
    4 IE11、Edge、Firefox、Chrome 测试通过
    5 window导入时可以把*.pem结尾的证书改为*.crt方便识别
    6 如果不想使用双向认证,请忽略【创建客户端证书】部分,并调整Nginx配置文件ssl_verify_client off;即可

    参考

    OpenSSL CA keyUsage extension
    openSSL命令、PKI、CA、SSL证书原理
    那些证书相关的玩意儿(SSL,X.509,PEM,DER,CRT,CER,KEY,CSR,P12等)
    openssl用法详解
    openssl自签名证书生成与单双向验证
    还有一些地址想不起来了,如果引用了您的文章笔者却未声明,请联系笔者。

    声明

    本文采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

  • 相关阅读:
    Oracle Instant Client(即时客户端) 安装与配置
    面试中经典的数据库问题
    MySQL 大表优化方案
    mysql中Timestamp,Time,Datetime 区别
    HTML学习之给div高度设置百分比不生效的问题
    textarea文本域宽度和高度width及height自动适应实现代码
    JAVA基础----java中E,T,?的区别?
    去除ArrayList集合中的重复自定义对象元素
    sql select中加入常量列
    mysql 将null转代为0
  • 原文地址:https://www.cnblogs.com/chasingdreams2017/p/9383500.html
Copyright © 2020-2023  润新知