Skip to content

使用CFSSL生成Nginx使用的HTTPS证书

下载cfssl

https://github.com/cloudflare/cfssl

只是生成证书,(以1.6.5为例)仅下载:

AMDARM重命名
cfssl_1.6.5_linux_amd64cfssl_1.6.5_linux_arm64cfssl
cfssl-certinfo_1.6.5_linux_amd64cfssl-certinfo_1.6.5_linux_arm64cfssl-certinfo
cfssljson_1.6.5_linux_amd64cfssljson_1.6.5_linux_arm64cfssljson

比如将以上三个二进制文件放至:/data/cfssl/bin

配置环境变量:

bash
export PATH=$PATH:/data/cfssl/bin

更新环境变量

bash
. /etc/profile # 或 source /etc/profile

生成证书

ca-config.json

用于定义CA的签名策略,包括证书的过期时间等

json
{  
  "signing": {  
    "default": {  
      "expiry": "87600h",
      "ca_constraint": {  
        "is_ca": true,  
        "max_path_len": 0
      }  
    },  
    "profiles": {  
      "server": {  
        "expiry": "43800h",
        "usages": [  
          "signing",  
          "key encipherment",  
          "server auth",  
          "client auth"  
        ]  
      }  
    }  
  }  
}

ca-csr.json

json
{
  "CN": "Liulike CA",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "Liulike",
      "ST": "Liulike",
      "O": "Liulike",
      "OU": "Liulike TEST"
    }
  ]
}

生成CA证书和私钥

使用CFSSL命令行工具,可以根据ca-config.jsonca-csr.json 来生成CA的证书和私钥

bash
echo "生成CA证书和私钥"
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -

server-csr.json

服务器证书签名请求(CSR)的JSON配置文件

json
{
  "CN": "liulike.test.cn",
  "hosts": [
    "liulike.test.cn",
    "sso.liulike.test.cn"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "Liulike",
      "ST": "Liulike",
      "O": "Liulike",
      "OU": "Liulike TEST"
    }
  ]
}

所有的证书都可以写在hosts列表里

生成服务器私钥和CSR

bash
echo "签署服务器证书"
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server-csr.json | cfssljson -bare server

# ca.pem 服务器证书
# ca-key.pem 服务器私钥 
# -profile 与 ca-config.json 内配置名称一样

Nginx配置SSL

简单配置

nginx
server{
	listen 443 ssl;
	server_name sso.liulike.test.cn;
    
    ssl_certificate /opt/ssl/server.pem;
    ssl_certificate_key /opt/ssl/server-key.pem;
    
	location / {
		proxy_pass http://sso:80;
		proxy_redirect off;
		proxy_http_version 1.1;
		proxy_set_header Connection "";
		proxy_set_header HOST $host:$server_port;
		proxy_set_header Cookie $http_cookie;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	}
}

http重定向到https

nginx
server {
    listen 80;
    listen [::]:80;
    server_name sso.liulike.test.cn;
    
    # 强制转换成 https
    rewrite ^(.*)$ https://${server_name}$1 permanent;
}

配置HTTPS加密连接

nginx
server {
    listen 443 ssl;
    listen [::]:443;
    server_name www.liulike.top;
    
    ssl_certificate /opt/ssl/server.pem;
    ssl_certificate_key /opt/ssl/server-key.pem;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    
    location / {
        proxy_pass http://sso:80;
		proxy_redirect off;
		proxy_http_version 1.1;
		proxy_set_header Connection "";
		proxy_set_header HOST $host:$server_port;
		proxy_set_header Cookie $http_cookie;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

ssl_ciphers: 指定支持的加密套件。些加密套件决定了数据传输时使用的加密算法和密钥交换机制。这里使用的是一系列强加密套件,其中ECDHE-RSA-AES128-GCM-SHA256是推荐的,因为它提供了强大的安全性和性能。:!前缀用于排除某些不安全的加密套件。

ssl_protocols: 指定了服务器支持的TLS协议版本。虽然这里包括了TLSv1和TLSv1.1,但出于安全考虑,建议仅启用TLSv1.2(如果客户端支持的话)。TLSv1和TLSv1.1已经被发现存在多个安全漏洞。

ssl_prefer_server_ciphers: 偏好服务器端的加密套件。服务器在SSL握手过程中,优先从服务器提供的加密套件列表中选择加密套件,而不是从客户端提供的列表中。

Spring Boot 添加ssl证书

注意:这种方式配置后,访问的地址如果在证书内配置有则不会有提示,如果在证书内未配置则会有安全提示

Spring Boot 2.7.x-

转换证书格式

将CFSSL生成的PEM证书转换为 Spring Boot 可用的SSL证书(将PEM证书转换为JKS(Java KeyStore)或PKCS12格式)

bash
openssl pkcs12 -export -out server.p12 -inkey server-key.pem -in server.pem -certfile ca.pem -name alias_name
  • -export:表示导出PKCS12格式的文件。
  • -out:指定输出文件的名称。
  • -inkey:指定私钥文件(服务器)的路径。
  • -in:指定证书文件(服务器)的路径。
  • -certfile:如果证书链中包含CA证书(注意不是ca的key),请指定CA证书文件的路径。在某些情况下,这一步可能是可选的,具体取决于Spring Boot配置和需求。
  • -name:指定别名

证书密码:执行上面命令的时候会提示输入密码,这个密码是Spring Boot必须的

修改Spring Boot配置文件

application.properties

properties
server.ssl.key-store-type=PKCS12
server.ssl.key-store=classpath:server.p12
# 或者
server.ssl.key-store=ssl/server.p12      # 相对或绝对路径
server.ssl.key-store-password=设置的密码
server.ssl.key-alias=1                   # 通常是PKCS12文件中的第一个条目,或者指定的别名

application.yml

yml
server:
  ssl:
    key-store-type: PKCS12
    key-store: classpath:server.p12
    # 或者
    key-store: ssl/server.p12            # 相对或绝对路径
    key-store-password: 设置的密码
    key-alias: 1                         # 通常是PKCS12文件中的第一个条目,或者指定的别名

配置后启动测试

Spring Boot 2.7.x+

Spring Boot 2.7.x及以上版本已经支持PEM格式证书

修改Spring Boot配置文件

application.properties

properties
server.ssl.certificate=classpath:server.pem
server.ssl.certificate-private-key=classpath:server-key.pem

application.yml

yml
server:
  ssl:
    certificate: classpath:server.pem
    certificate-private-key: classpath:server-key.pem

配置后启动测试