免费证书有免费证书的麻烦(有效期),付费证书有付费证书的缺点(需要资金)。
由于并不是任何时候都需要去找证书颁发机构购买数字证书,所以合理使用自签名证书(比如测试或者非公开环境)有时候也是一种可行的替代选择。

准备工作

  • Windows 10 WSL Ubuntu 16.04
  • OpenSSL
    如果没有安装过 OpenSSL,只需要运行一下命令 sudo apt install openssl

生成 CA 根证书

这一步需要做的是:

  1. 生成用于 CA 根证书的私钥
  2. 生成 CA 根证书(公钥)

生成证书的过程中程序会询问国家C、州或省ST、城市L、组织O之等信息,重要的是通用名Common Name/CN,这个填要签发证书的主域名 example.com
既然是自签证书,为了实现一劳永逸有效期自然越长越好,所以设置成 7305 天也就是 20 年。
至于为什么生成 ECC 证书不用 RSA 证书……体积小速度快,而且反正不是对外使用不需要考虑兼容性。

命令如下:

mkdir ca && cd ca
openssl ecparam -genkey -name prime256v1 -out ca.key
openssl req -new -x509 -days 7305 -key ca.key -out ca.crt

生成泛域名证书的签名请求

这一步需要做的是:

  1. 生成用于泛域名证书的私钥
  2. 生成证书签名请求(CSR)

生成 CSR 时会被询问同样的信息,操作方法相同。

命令如下:

openssl ecparam -genkey -name prime256v1 -out example.com.key
openssl req -new -sha256 -key example.com.key -out example.com.csr

使用 CA 根证书对泛域名证书签名

这一步需要做的是:

  1. 对泛域名证书签名
  2. 将 CA 根证书与泛域名证书合并成 fullchain 证书

新建 extended.ext 文件,最后一行的 subjectAltName 字段为证书的主域名+泛域名。

[ req ]
default_bits        = 2048
distinguished_name  = req_distinguished_name
req_extensions      = san
extensions          = san

[ req_distinguished_name ]
countryName         = JP
stateOrProvinceName = Chiba
localityName        = Futtsu

[ SAN ]
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = DNS:example.com,DNS:*.example.com

使用这个 extended.ext 文件执行签名,有效期同样设成了 20 年。

openssl x509 -req \
  -days 7305 \
  -sha256 \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -in example.com.csr -out cert.crt \
  -extfile extended.ext -extensions SAN

最后将泛域名证书 cert.crt 与根证书 ca.crt 合并为 fullchain 证书。

cat cert.crt ca.crt > fullchain.crt

Nginx 部署

到此为止已经得到了需要的三个文件:

  • example.com.key
  • cert.crt
  • fullchain.crt

当然生成证书仅仅是一项准备工作,将证书导出然后部署到服务器上才能发挥作用。为 Nginx 配置自签名证书的配置文件需要这样修改:

listen 443 ssl;

ssl_certificate /path/to/cert.crt;
ssl_certificate_key /path/to/example.com.key;
ssl_trusted_certificate /path/to/fullchain.crt;

根据需要可能还要写 http 跳转为 https 的配置,不过相较于为 Nginx 部署一般的证书没什么特殊区别。


参考来源:

  1. Lixingcong - Cloudflare自签名SSL证书
  2. EAimTY - 用自签名SSL证书配合 CloudFlare 免费SSL构建全站HTTPS加密