半夜收到邮件通知,之前签发的博客站点 SSL 证书到期了。通过 KeyManager 1 申请亚洲诚信证书,发现 KM 已经不支持这一产品,遂又动了搞自动签发的念头。于是通过 FreeSSL.cn 2 搞了 ACME 自动签发。

利用 FreeSSL ACME v2 自动化签发 SSL 证书-诺墨的博客站

FreeSSL.cn 是一个免费提供 HTTPS 证书申请、HTTPS 证书管理和 HTTPS 证书到期提醒服务的网站,旨在推进 HTTPS 证书的普及与应用,简化证书申请的流程。通过注册 FreeSSL.cn 2 账号,可以对申请的证书进行保存和在线管理。

添加 FreeSSL ACME 域名

因为平时会用到二级域名做测试,所以干脆对 *.normalcoder.com 进行证书签发。创建证书时使用 *.normalcoder.com

利用 FreeSSL ACME v2 自动化签发 SSL 证书-诺墨的博客站
输入要创建证书的域名

界面跳转到控制台,此处点击下一步即可。

利用 FreeSSL ACME v2 自动化签发 SSL 证书-诺墨的博客站
配置 ACME 域名

配置域名 DNS 解析

一开始,会让你对持有域名进行 DNS验证,首先根据 提示 DCV 配置提示配置一下 DNS

  • 主机记录:_acme-challenge
  • 记录类型:CNAME
  • 记录值:ncnh4r1wdcptuorqzxxe.dcv2.httpsauto.com

跟以前手动配置不一样,此处自动签发用了 CNAME 而不是 TXT 记录,配置的时候要留意

利用 FreeSSL ACME v2 自动化签发 SSL 证书-诺墨的博客站
提示配置 DCV

域名托管在阿里云上,配置 DNS 的过程轻车熟路,生效速度也很快。上面的图是配置完成验证后的结果,如果没验证成功,需要等个 5-10 分钟等待 DNS 解析生效。

利用 FreeSSL ACME v2 自动化签发 SSL 证书-诺墨的博客站
在阿里云上配置 DNS

DNS 验证通过后就可以开始签发 SSL 了。通过验证后会得到以下的界面,但实际上不需要等待 DCV 验证通过,也可以直接点击「完成」,通过页面「证书申请」按钮,选择添加域名后同样可以得到 acme.sh 的部署命令提示。

截图中应该是 FreeSSL.cn 2 的 Bug,我使用了泛域名,提示的命令对 * 并没有做转义,会导致后续执行失败,下文会提到。

利用 FreeSSL ACME v2 自动化签发 SSL 证书-诺墨的博客站
acme.sh 部署命令

安装 acme.sh

推荐阅读 ACME v2证书自动化快速入门 3 一文。当然,相关文中的操作也可以参考下方:

先来安装个 acme.sh 客户端,命令中的 email 可以替换为你自己的邮箱地址(虽然我还没搞懂有什么用,应该是后续发送通知邮件的吧)。

我是直接在 root 下操作的,非 root 用户可能安装后会有些问题,建议用 sudo su 切换至 root 用户操作。

curl https://get.acme.sh | sh -s email=my@example.com

如果上面官方下载地址失败 或者 太慢,可以选用国内的备用地址

curl https://gitcode.net/cert/cn-acme.sh/-/raw/master/install.sh?inline=false | sh -s email=my@example.com
利用 FreeSSL ACME v2 自动化签发 SSL 证书-诺墨的博客站
安装 acme.sh

安装脚本会给当前 Shell 添加 alias 别名,安装完成后需要 omz reload 重载下 Shell,如果不是用 oh-my-zsh 的自行百度或退出当前用户重新登陆一次就好。

请求签发 SSL 证书

根据上文的部署命令,执行 acme.sh --issue 请求签发会得到 zsh: no matches found: *.normalcoder.com 的错误提示,这是因为 FreeSSL.cn 提示的命令对泛域名的 * 符号没有做转移处理。

# 错误的命令
acme.sh --issue -d *.normalcoder.com --dns dns_dp --server https://acme.freessl.cn/v2/DV90/directory/********************

# 正确的命令
acme.sh --issue -d \*.normalcoder.com --dns dns_dp --server https://acme.freessl.cn/v2/DV90/directory/********************

命令中的 https://acme.freessl.cn/v2/DV90/directory/********************FreeSSL 的专属 ACME 地址,专属 ACME 地址需要注意保密,这非常重要。此处做了脱敏,可以根据自己情况替换。

中间可能会有多次等待签发订单,脚本会自动重试,完成后会把签发证书内容和文件位置打印出来,当看到 Cert success 时证书就已经签发并下载到本地了。

➜  ~ acme.sh --issue -d \*.normalcoder.com --dns dns_dp --server https://acme.freessl.cn/v2/DV90/directory/********************
[Mon Jul 25 04:06:44 CST 2022] Using CA: https://acme.freessl.cn/v2/DV90/directory/********************
[Mon Jul 25 04:06:44 CST 2022] Creating domain key
[Mon Jul 25 04:06:44 CST 2022] The domain key is here: /root/.acme.sh/*.normalcoder.com/*.normalcoder.com.key
[Mon Jul 25 04:06:44 CST 2022] Multi domain='DNS:*.normalcoder.com,DNS:normalcoder.com'
[Mon Jul 25 04:06:44 CST 2022] Getting domain auth token for each domain
[Mon Jul 25 04:07:27 CST 2022] Getting webroot for domain='*.normalcoder.com'
[Mon Jul 25 04:07:27 CST 2022] Getting webroot for domain='normalcoder.com'
[Mon Jul 25 04:07:27 CST 2022] *.normalcoder.com is already verified, skip dns-01.
[Mon Jul 25 04:07:27 CST 2022] normalcoder.com is already verified, skip dns-01.
[Mon Jul 25 04:07:27 CST 2022] Verify finished, start to sign.
[Mon Jul 25 04:07:27 CST 2022] Lets finalize the order.
[Mon Jul 25 04:07:27 CST 2022] Le_OrderFinalize='https://acme.freessl.cn/v2/DV90/finalize/********************/****/*****'
[Mon Jul 25 04:07:27 CST 2022] Order status is processing, lets sleep and retry.
[Mon Jul 25 04:07:30 CST 2022] Polling order status: https://acme.freessl.cn/v2/DV90/order/********************/****/*****
[Mon Jul 25 04:07:31 CST 2022] Order status is processing, lets sleep and retry.
[Mon Jul 25 04:07:31 CST 2022] Retry after: 15
[Mon Jul 25 04:07:47 CST 2022] Polling order status: https://acme.freessl.cn/v2/DV90/order/********************/****/*****
[Mon Jul 25 04:07:47 CST 2022] Order status is processing, lets sleep and retry.
[Mon Jul 25 04:07:47 CST 2022] Retry after: 15
[Mon Jul 25 04:08:03 CST 2022] Polling order status: https://acme.freessl.cn/v2/DV90/order/********************/****/*****
[Mon Jul 25 04:08:03 CST 2022] Order status is processing, lets sleep and retry.
[Mon Jul 25 04:08:03 CST 2022] Retry after: 15
[Mon Jul 25 04:08:20 CST 2022] Polling order status: https://acme.freessl.cn/v2/DV90/order/********************/****/*****
[Mon Jul 25 04:08:20 CST 2022] Downloading cert.
[Mon Jul 25 04:08:20 CST 2022] Le_LinkCert='https://acme.freessl.cn/v2/DV90/cert/********************/71804'
[Mon Jul 25 04:08:20 CST 2022] Cert success.
-----BEGIN CERTIFICATE-----
...签发的证书内容...
-----END CERTIFICATE-----
[Mon Jul 25 04:08:20 CST 2022] Your cert is in: /root/.acme.sh/*.normalcoder.com/*.normalcoder.com.cer
[Mon Jul 25 04:08:20 CST 2022] Your cert key is in: /root/.acme.sh/*.normalcoder.com/*.normalcoder.com.key
[Mon Jul 25 04:08:20 CST 2022] The intermediate CA cert is in: /root/.acme.sh/*.normalcoder.com/ca.cer
[Mon Jul 25 04:08:20 CST 2022] And the full chain certs is there: /root/.acme.sh/*.normalcoder.com/fullchain.cer
利用 FreeSSL ACME v2 自动化签发 SSL 证书-诺墨的博客站
请求签发SSL

安装证书到 Web 服务器

acme.sh 针对不同的 Web Server 提供了不同的证书安装参数。以下为 ApacheNginx 的安装命令,对应只需要替换签发下来的证书文件路径即可。最后一行是写入证书后调用 service 重启对应服务,无需改动。

# 安装证书到 Apache
acme.sh --install-cert -d example.com \
--cert-file      /path/to/certfile/in/apache/cert.pem  \
--key-file       /path/to/keyfile/in/apache/key.pem  \
--fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \
--reloadcmd     "service apache2 force-reload"

# 安装证书到 Nginx
acme.sh --install-cert -d example.com \
--key-file       /path/to/keyfile/in/nginx/key.pem  \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd     "service nginx force-reload"

因为我用的 Nginx,于是执行结果如下,有关 Nginx 如何配置网站 SSL 可参考 Nginx 如何配置证书? 4

➜  ~ acme.sh --install-cert -d \*.normalcoder.com --key-file /root/.acme.sh/\*.normalcoder.com/www.normalcoder.com.key --fullchain-file /root/.acme.sh/\*.normalcoder.com/fullchain.cer --reloadcmd "service nginx force-reload"
[Mon Jul 25 04:11:14 CST 2022] Installing key to: /root/.acme.sh/*.normalcoder.com/www.normalcoder.com.key
[Mon Jul 25 04:11:14 CST 2022] Installing full chain to: /root/.acme.sh/*.normalcoder.com/fullchain.cer
[Mon Jul 25 04:11:14 CST 2022] Run reload cmd: service nginx force-reload
Redirecting to /bin/systemctl force-reload nginx.service
[Mon Jul 25 04:11:14 CST 2022] Reload success
利用 FreeSSL ACME v2 自动化签发 SSL 证书-诺墨的博客站
安装证书到 Nginx

至此,利用 FreeSS ACME v2 自动化签发 SSL 证书完成。

  1. KeyManager
  2. FreeSSL.cn
  3. ACME v2证书自动化快速入门
  4. Nginx 如何配置证书?