自签发 SSL 证书

这两天需要安装 NextCloud, 对外仅使用 IP 访问,NextCloud 强制使用 HTTPS, 但是各大证书颁发机构都不对 IP 地址颁发证书,所以需要自己签发一套证书。

签发方法

签发有两种思路,一种是直接签发单一证书,然后导入,另一种是签发一个根证书,再用这个根证书签发下面的证书,这里为了以后的方便,我采用第二种。
直接签发单一证书的流程为:

  1. 生成私钥 key;
  2. 由私钥和相关设置生成证书请求 csr 文件;
  3. 根据 key 和 csr 文件生成证书;

先签发根证书再签发具体证书的流程如下:

  1. 生成根证书私钥 ca-key;
  2. 生成根证书请求 ca-csr;
  3. 生成根证书 ca-crt;
  4. 生成所需证书的私钥 key;
  5. 由私钥 key 和相关设置生成所需证书的 csr 文件;
  6. 由根证书私钥 ca-key, 根证书 ca-crt 和所需证书请求 csr 生成所需的 crt.

由此 crt 和 key 放入 nginx, 而 ca-crt 导入系统并信任即可。

具体过程

根证书生成

生成根证书的 3 步可以合并为 1 步,命令如下,其中 -subj 即证书相关参数,如果不指定 -subj 参数将通过交互方式生成:

openssl req -x509 -nodes -days 1461 -newkey rsa:2048 -subj "/C=CN/ST=MyProvince/L=MyCity/O=MyOrganization" -keyout CA-private.key -out CA-certificate.crt -reqexts v3_req -extensions v3_ca

生成具体证书

生成私钥

生成具体证书所需私钥 key:

openssl genrsa -out private.key 2048

生成证书请求,注意这里 -subj 中的 CN 参数为你的目标 IP 或 域名:

openssl req -new -key private.key -subj "/C=CN/ST=MyProvince/L=MyCity/O=MyOrganization/CN=123.123.123.123" -sha256 -out private.csr

解决 Chrome 安全警告

按照上面的流程,需要注意的是,在默认情况下生成的证书一旦选择信任,在 Edge, Firefox 等浏览器都显示为安全,但是 Chrome 仍然会标记为不安全并警告拦截,这是因为 Chrome 需要证书支持扩展 Subject Alternative Name, 因此生成时需要特别指定 SAN 扩展并添加相关参数。
SAN Extension 所需配置文件关键属性:

  • req_distinguished_name: 一节的内容与上面 -subj 一样都是证书的附加信息
  • subjectAltName: 是最关键的属性,取值有两种情况,除前缀外值应与上一步 -subj 中指定的 CN 参数值相同:
    • 如果是为某一域名签发证书,则其值可为 DNS:www.example.com 或者使用通配符 DNS:*.example.com
    • 如果为 IP 地址颁发证书,则应该使用 IP:xxx.xxx.xxx.xxx 的形式。

以下是一个例子:

[ req ]
default_bits        = 2048
distinguished_name  = req_distinguished_name
req_extensions      = san
extensions          = san
[ req_distinguished_name ]
countryName         = CN
stateOrProvinceName = MyProvince
localityName        = MyCity
organizationName    = MyOrganization
[SAN]
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = IP:123.123.123.123

最终生成证书

-extfile 参数即为上面的 SAN 配置文件:

openssl x509 -req -days 1461 -in private.csr -CA CA-certificate.crt -CAkey CA-private.key -CAcreateserial -sha256 -out private.crt -extfile private.ext -extensions SAN

使用证书

生成的具体域名证书和私钥可在 nginx 中使用,然后再客户端所在电脑导入根证书:

  • Windows 需要添加根证书至 受信任的根证书颁发机构
  • macOS 将其导入 钥匙串访问 并选择信任

另外 Windows 快捷安装根证书脚本如下(需要管理员权限):

certutil -addstore -f -enterprise -user root ".\CA-certificate.crt"

发表评论

电子邮件地址不会被公开。 必填项已用*标注