HTTPS 证书生成 & Nginx/Tomcat 配置 HTTPS

  1. OpenSSL安装

    OpenSSL官网,或者参考 linux升级OpenSSL

    中间可能会遇到 openssl.cnf 的问题,请使用 openssl-1.0.1t.tar.gz 包 apps下的 demoCA 和 openssl.cnf

  2. 证书生成

    • 单向认证,参考 Nginx单向认证的安装配置

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      openssl genrsa -des3 -out server.key 2048 #自定义密码

      openssl req -new -key server.key -out server.csr

      #---------------------------------------------------------------------------------------------------------------
      Enter pass phrase for server.key: 自定义密码
      Country Name (2 letter code) [XX]: CN #国家
      State or Province Name (full name) []: GD #区域或是省份
      Locality Name (eg, city) [Default City]: SZ #地区局部名字
      Organization Name (eg, company) [Default Company Ltd]: Test #机构名称:填写公司名
      Organizational Unit Name (eg, section) []: Test #组织单位名称:部门名称
      Common Name (eg, your name or your server's hostname) []: *.domain.com #网站域名
      Email Address []: admin@domain.com #邮箱地址
      A challenge password []: #输入一个密码
      An optional company name []: #一个可选的公司名称
      #---------------------------------------------------------------------------------------------------------------

      怎么让nginx配置SSL安全证书重启免输入密码,不然Nginx、Tomcat使用该私钥启动的时候需要输入上面的密钥

      openssl rsa -in server.key -out server.key.unsecure
      openssl x509 -req -days 365 -in server.csr -signkey server.key.unsecure -out server.crt #使用上面的密钥和CSR对证书进行签名

    • 双向认证,参考 openssl生成SSL证书的流程

      CA根证书的生成

      1
      2
      3
      4
      5
      6
      # Generate CA private key   
      openssl genrsa -out ca.key 2048
      # Generate CSR
      openssl req -new -key ca.key -out ca.csr
      # Generate Self Signed certificate(CA 根证书)
      openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt

      用户证书的生成

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      # 服务器端用户证书
      # private key
      openssl genrsa -des3 -out server.key 1024
      # generate csr
      openssl req -new -key server.key -out server.csr
      # generate certificate
      openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key

      # 客户端用户证书
      openssl genrsa -des3 -out client.key 1024
      openssl req -new -key client.key -out client.csr
      openssl ca -in client.csr -out client.crt -cert ca.crt -keyfile ca.key
      免密钥启动同上,TXT_DB error number 2 异常请参考 openssl TXT_DB error number 2

      生成pem格式证书
      有时需要用到pem格式的证书,可以用以下方式合并证书文件(crt)和私钥文件(key)来生成

      1
      2
      $cat client.crt client.key> client.pem
      $cat server.crt server.key > server.pem
  3. Nginx、Tomcat配置HTTPS

    nginx.conf添加

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    server {
    listen 443 ssl;
    server_name localhost;

    ssl_certificate /work/openssl/single/server.crt;
    ssl_certificate_key /work/openssl/single/server.key.unsecure;

    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 5m;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    location / {
    allow all;
    proxy_pass https://192.168.1.121:443;
    proxy_set_header Host $host;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header X-Real-Ip $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    }

    tomcat server.xml添加

    1
    2
    3
    4
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
    maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
    clientAuth="false" SSLCertificateFile="/work/openssl/single/server.crt" SSLProtocol="SSLv2+SSLv3+TLSv1"
    SSLCertificateKeyFile="/work/openssl/single/server.key.unsecure" SSLVerifyClient="optional"/>

    server.xml默认注释了

    1
    2
    3
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
    maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
    clientAuth="false" sslProtocol="TLS" />

    需要注意protocol中的 Http11AprProtocol 与 Http11NioProtocol,加密算法不支持的话,可能报异常 Java and SSL - java.security.NoSuchAlgorithmException

  4. 一个大坑

    Ubuntu上跑Tengine,代理Windows上的应用,访问HTTPS页面时候总是报504错误,后来又报502错误。

    排查了一个多小时后发现是Windows系统安装了Vmware Workstation,而Vmware的VMware Authorization Service自动启动了。

    还有另外一个Vmware的服务忘记了,这两个服务会影响本地应用使用HTTPS,所以停止掉或禁用掉就可以了。

    HTTP状态码

    502 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。

    504 作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。   注意:某些代理服务器在DNS查询超时时会返回400或者500错误

参考资料: