背景

前两年一直在使用从萌咖购买的 AlphaSSL 通配符证书,最近这两天发现萌咖已经下架了这一款证书。于是想寻找更便宜经济的通配符证书。通过查询发现,现在 ZeroSSL 已经支持了通配符证书的申请,而且现在的 acme.sh 已经能很好地实现自动化了,只需要几条命令就能轻松安装证书。

安装 acme.sh

虽然有些教程推荐使用 Docker 部署 acme.sh 脚本,但是实际测试下来,如果你的 Web 服务器也是运行在 Docker 中的话,这一个方案并不是很方便。所以还是采取普通的方式安装。

#将 my@example.com 修改成自己的邮箱
curl https://get.acme.sh | sh -s email=my@example.com

目前的安装脚本已经实现了下面两个自动化:

  • 自动执行 alias acme.sh=~/.acme.sh/acme.sh,后续直接通过 acme.sh 命令调用脚本
  • 自动添加 Crontab 定时任务,不需要手动添加

在执行结束后,执行 source .bashrc 使 acme.sh 命令生效,当然如果你使用的是其它的 shell 环境,需要修改这一条指令。

获取 DNS API

acme.sh 申请通配符证书只能通过 DNS 的方式进行验证,首先需要获得域名所在 DNS 的 API 密钥/令牌。这里以 Cloudflare DNS 为例,只需要在命令行输入以下命令:

export CF_Token="Y_jpG9AnfQmuX5Ss9M_qaNab6SQwme3HWXNDzRWs"

这里使用的是 API 令牌,可以灵活限制权限以及过期时间。更多的 API 使用方法参考这一个页面

申请证书

申请证书也是一句命令的事,输入下面的命令:

acme.sh --issue --dns dns_cf -d example.com -d *.example.com

除了将 example.com 修改成自己的域名外,还需要注意你使用的 DNS 服务,如果不是 Cloudflare,还需要修改命令中的 dns_cf 字段。另外需要注意的是,如果你的域名有其它证书颁发机构的 CAA 记录,需要提前删除,或者添加 ZeroSSL 的证书颁发机构的 CAA 记录。

site.com. 3600 IN CAA 0 issue "sectigo.com"
site.com. 3600 IN CAA 0 issuewild "sectigo.com"

配置 Nginx

在 Nginx 中配置 SSL 主要关注 ssl_certificatessl_certificate_key 两个字段,这里给出一个最简单的示例配置,实际的配置需要自行修改。

server {
  listen 443 ssl;
  server_name localhost;
  ssl_certificate /etc/nginx/conf.d/selfsigned.crt;
  ssl_certificate_key /etc/nginx/conf.d/selfsigned.key;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers HIGH:!aNULL:!MD5;
  location / {
    proxy_pass http://webserver:8080;
  }
}

安装证书

这里使用 acme.sh 脚本中的 --install-cert 参数安装,这种方式的好处是 acme.sh 会记录下安装的参数(证书安装路径、Web 服务重启指令),不需要额外编写 shell 脚本。

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     "sudo nginx -s reload"

这里的文件地址、Nginx 重启命令参考实际的系统环境给定。至此已经完成,刷新你的网站后应该就能看到新的证书已经生效了。

参考资料