0%

使用 Certbot 自动申请和续期泛域名证书

如今的网站开发,如果不能正常支持 HTTPS,主流浏览器如 Chrome 将无法正常访问。好在域名厂商一般都会提供免费的 SSL 证书的申请和延期服务,可证书的期限往往只有一年,且无法实现通配符匹配。也就意味着,每过一段时间,或者每新使用一个域名,总要到域名厂商的网站去操作一下。虽然只需要少量几次点击,但终究还是不方便。且域名厂商提供的可免费申请的域名数量往往有限,随着网站功能的增加,总有不够用的时候。

于是乎,如果能有一个方便的,可以自动申请和续期泛域名(或者称作通配符域名)证书的工具,就很美好了。Certbot 刚好可以胜任这些任务。

Certbot 介绍

Certbot 的具体情况可参考 官网

Certbot 的简要教程(可选择 web 服务器和操作系统):https://certbot.eff.org/instructions?ws=nginx&os=ubuntufocal

Certbot 的官方文档:https://eff-certbot.readthedocs.io/en/stable/intro.html

按照官网的说法,Certbot 是一款免费开源软件,通过自动使用 Let’s Encrypt 证书使网站实现 HTTPS 功能。

这里可以顺便提一句 Let’s Encrypt。这是一家免费发放 SSL 证书的机构,为 HTTPS 的普及发挥了重大贡献。与其类似的还有 zerossl。与 Let’s Encrypt 相比,zerossl 还可以免费签 IP 地址 SSL 证书。

Certbot 的安装

Certbot 需要使用 snap 安装,最新版本的 Ubuntu 已经内置了 snap。如果系统没有内置 snap,可以去 snap 官网 根据系统查找安装方法。

安装好 snap,还要确保 snap 版本是最新的:

1
sudo snap install core; sudo snap refresh core

卸载掉曾经安装过的 Certbot(以下指令根据操作系统的包管理工具选择执行):

1
2
3
sudo apt-get remove certbot    # Debian/Ubuntu
sudo dnf remove certbot # Fedora
sudo yum remove certbot # CentOS

安装 Certbot

1
sudo snap install --classic certbot

将 Certbot 链接到 /bin/bash 目录:

1
sudo ln -s /snap/bin/certbot /usr/bin/certbot

certbot-letencrypt-wildcardcertificates-alydns-au 的使用

国外主流的 DNS,Certbot 官方都有插件支持。可是因为一些众所周知的原因,国内的 DNS 服务器并不在官方支持的厂商之列。好在有一些仁人志士,开发了支持国内一些比较重要的厂商的 Certbot 插件。

我这里使用的是 star 数比较多的一个:certbot-letencrypt-wildcardcertificates-alydns-au

  1. 下载 certbot-letencrypt-wildcardcertificates-alydns-au,并修改 su.sh 文件的权限:

    1
    2
    3
    git clone https://github.com/ywdblog/certbot-letencrypt-wildcardcertificates-alydns-au
    cd certbot-letencrypt-wildcardcertificates-alydns-au
    chmod 0777 au.sh
  2. 查看 domain.ini 文件中是否有要使用域名的根域名,如果没有就添加进去。比如我的根域名是 vip,并不在其中,就在结尾加上了:

  3. 需要使用 API 密钥方能验证对域名的所有权,从而实现对域名的申请和续期。常见域名供应商获取 DNS API 密钥的入口:

    查询好后,将相关密钥配置到 au.sh 文件中:

  4. 目前该工具支持五种运行环境和场景,通过 hook 文件和参数来调用:

    • PHP(>4 以上版本均可)
      • au.sh php aly add/clean:PHP 操作阿里云 DNS,增加/清空 DNS。
      • au.sh php txy add/clean:PHP 操作腾讯云 DNS,增加/清空 DNS。
      • au.sh php godaddy add/clean:PHP 操作 GoDaddy DNS,增加/清空 DNS。
    • Python(支持 2.7 和 3.7,无需任何第三方库)
      • au.sh python aly add/clean:Python 操作阿里云 DNS,增加/清空 DNS。
      • au.sh python txy add/clean:Python 操作腾讯云 DNS,增加/清空 DNS。
      • au.sh python hwy add/clean:Python 操作华为云 DNS,增加/清空 DNS。
      • au.sh python godaddy add/clean:Python 操作 GoDaddy DNS,增加/清空 DNS。

    根据自己服务器环境和域名服务商选择任意一个 hook shell(包含相应参数),具体使用后面会说。

  5. 测试申请证书

    1
    sudo certbot certonly  -d *.example.com --manual --preferred-challenges dns --dry-run  --manual-auth-hook "/脚本目录/au.sh python txy add" --manual-cleanup-hook "/脚本目录/au.sh python txy clean"

    参数说明:

    • *.example.com:要申请证书的域名。注意,*.example.com 为二级域名,并不包括主域名 example.com,若要同时支持 example.com,需要再增加一个 -d 参数指定为 example.com
    • --manual-auth-hook--manual-cleanup-hook 有三个参数:
      1. 要选择哪种语言(php/python)
      2. DNS 厂商(aly/txy)
      3. 固定参数(--manual-auth-hook 中用 add,--manual-clean-hook 中用 clean)
    • 如果需要申请 ECC 证书,则需指定 --key-type 参数为 ecdsa。还可使用 --elliptic-curve 参数指定加密算法,例如 secp384r1
    • 如果申请多个证书(如不同的加密算法)可以使用 --cert-name 参数将证书文件指定为诸如 *.example.com-ecdsa 形式加以区分

    运行后提示 successful,说明配置没有问题

  6. 测试无误后,正式申请证书(去除 --dry-run 参数):

    1
    sudo certbot certonly  -d *.example.com --manual --preferred-challenges dns --manual-auth-hook "/脚本目录/au.sh python txy add" --manual-cleanup-hook "/脚本目录/au.sh python txy clean"

    期间可能需要填写邮箱,同意协议。注意问是否订阅邮件时,建议不要订阅:

    申请到的证书将存放在 /etc/letsencrypt/live/证书名/ 目录下,通过 Web 服务器(如 Nginx)自行配置即可。

续期证书

续期服务器上所有证书

如果续费所有整数,操作就十分简单了,一条命令即可:

1
sudo certbot renew  --manual --preferred-challenges dns --manual-auth-hook "/脚本目录/au.sh python txy add" --manual-cleanup-hook "/脚本目录/au.sh python txy clean"

续期指定证书

有时候或许我们不想把所有整数都续期,可以通过以下方法续期某一张证书。

首先,查看服务器中都有哪些证书:

1
sudo certbot certificates

然后根据查询到的证书名,更新指定的证书:

1
sudo certbot renew --cert-name *.example.com-ecdsa  --manual-auth-hook "/脚本目录/au.sh php aly add" --manual-cleanup-hook "/脚本目录/au.sh php aly clean"

使用 crontab 定时更新证书

续期证书只需要一条指令,可以将其放到 crontab 中定时执行,这样就再也不用操心证书过期的问题了。证书有效期小于 30 天的情况才会真的执行 renew,所以 crontab 的周期可以配置为 1 天或 1 周:

1
1 1 */1 * * root certbot-auto renew --manual --preferred-challenges dns  --manual-auth-hook "/脚本目录/au.sh php aly add" --manual-cleanup-hook "/脚本目录/au.sh php aly clean"

如果 Certbot 机器和运行 Web 服务(比如 Nginx,Apache)的机器是同一台,那么成功 renew 证书后,可以重启对应的 Web 服务器,运行下列 crontab:

1
2
# 注意只有成功 renew 证书,才会重新启动 Nginx
1 1 */1 * * root certbot-auto renew --manual --preferred-challenges dns --deploy-hook "service nginx -s reload" --manual-auth-hook "/脚本目录/au.sh php aly add" --manual-cleanup-hook "/脚本目录/au.sh php aly clean"

Certbot 其他指令

撤销证书(以下指令任选一个即可):

1
2
sudo certbot revoke --cert-name example.com
sudo certbot revoke --cert-path /etc/letsencrypt/live/example.com/cert.pem