自动化执行Certbot续期通配符SSL证书
通配符证书避免管理多个子域名证书,定期更新免去维护成本

之前使用Certbot管理证书的时候,因为有很多二级域名,管理起来比较麻烦,需要换用通配符证书。

Certbot确定域名所有权的思路(也就是challenge类型)有两种:httpdns,前者是访问域名的某个路径,确定是不是预设的内容。后者是查询dns的某个TXT记录,查看是否是预设的值。Certbot有很多插件可以辅助你完成认证,我用文档里的一张表格来说明:

插件获取证书安装证书challenge类型
apacheyesyeshttp
nginxyesyeshttp
webrootyesnohttp
standaloneyesnohttp
DNS插件yesnodns
manualyesnohttpdns

只有dns类型的可以获取通配符证书。通过manual插件运行的时候,它会给你提供TXT记录的记录名和记录值,你自己去DNS服务商后台改。为了实现自动化,我们要寻求合适的DNS插件。

Certbot官方提供了针对常见服务商的插件,可以帮助你做到自动增加TXT记录,认证完成之后,自动删除记录。常见的CloudflareLinodeRoute 53等等都有官方插件,但是阿里云没有,其他国内的都没有,不过可以使用开源第三方的,比如certbot-dns-aliyun

环境的安装

我用的系统是Ubuntu 24.04 LTS,需要安装Certbot和certbot-dns-aliyun。

Ubuntu的源里有Certbot,这个好说。但certbot-dns-aliyun是个第三方的包,没有纳入到系统级别的库中。所以如果要与Cerbot打配合,需要全局安装certbot-dns-aliyun,它所带来的依赖,有可能会对系统的依赖造成影响,所以系统是默认禁止你用pip安装第三方包的。你可以强制安装,只要你能承受可能的风险。更安全的选择是使用Python虚拟环境,它隔离度比较高。

我把两种方式都描述一下,你可以按需选择。

系统级安装

通过pip命令安装Certbot和certbot-dns-aliyun:

sudo pip install certbot certbot-dns-aliyun --break-system-packages

加上--break-system-packages是为了跳过系统的保护机制,强制安装。加上sudo是为了安装到系统级别目录,不加sudo的话它会被安装到当前用户的目录。如果它在用户目录,执行sudo certbot就识别不到了。

我用的是阿里云的ECS,它的Ubuntu自带了阿里云的PyPI源,如果你不确定有没有,可以通过sudo pip config list查看。如果你的云服务商没有内置地址,那你大概率无法访问PyPI源,可以在pip install命令后添加-i参数,临时切换源地址为阿里云的地址:

-i https://mirrors.aliyun.com/pypi/simple/

你可以换成你方便的源地址,比如清华镜像腾讯镜像

为了确认插件是否安装完成,运行一下命令:

sudo certbot plugins

看看插件列表里是否有dns-aliyun,有的话就说明安装成功了。

使用虚拟环境

更安全的方式就是使用虚拟环境,不同虚拟环境是相互隔离的,可以有各自的库,不过它们的基础Python二进制还是一样的。

首先是安装venv模块,用于创建虚拟环境。

sudo apt install python3-venv

虚拟环境都是放在某个目录的,我们照着Certbot官方网站来,放到/opt/certbot,对应命令是:

sudo python3 -m venv /opt/certbot/

然后在虚拟环境中安装依赖:

sudo /opt/certbot/bin/pip install certbot certbot-dns-aliyun

并使用这个环境里的certbot命令判断阿里云插件是否安装成功:

sudo /opt/certbot/bin/certbot plugins

最后软链接到系统路径里:

sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot

阿里云配置

在获取证书之前,需要配置下RAM用户,并给他授权。在https://ram.console.aliyun.com/中创建一个用户,并开启“OpenAPI 调用访问”,完成后能拿到AccessKey ID和AccessKey Secret。随后给它授予权限AliyunDNSFullAccess,这样它就能修改DNS记录了。

certbot-dns-aliyun从配置文件中读取AccessKey ID和AccessKey Secret。我把配置文件放到了/etc/aliyun.ini

dns_aliyun_access_key = 12345678
dns_aliyun_access_key_secret = 1234567890abcdef1234567890abcdef

还得修改下的权限,不然获取证书的时候会报警,说你的权限比较危险:

sudo chmod 600 /etc/aliyun.ini

然后配置这块儿就算完成了。

获取证书并更新

接下来获取证书的环节就比较简单了:

sudo certbot certonly \
    --agree-tos \
    --no-eff-email \
    -m "mail@example.com" \
    --authenticator=dns-aliyun \
    --dns-aliyun-credentials='/etc/aliyun.ini' \
    -d "*.example.com,example.com"

你可以将图中的域名更换成你的域名,配置地址换成你的地址。在DNS认证的环节,你登陆阿里云DNS解析的后台,会看到有新增的TXT记录,等它认证结束之后,新增的记录会被删除。生成的证书保存在/etc/letsencrypt/live/[域名]目录下,可用于配置nginx。

这个时候,生成的证书有效期只有90天,你需要在过期之间,手动或自动更新证书。如果你是通过apt安装的Certbot,它会自动地添加定时任务,一天执行两次检测,如果哪个证书快过期了,就更新。但是对于我们这种通过pip安装的需要手动添加定时任务:

DELAY=$(awk 'BEGIN{srand(); print int(rand()*(3600+1))}')
echo "0 0,12 * * * root sleep $DELAY && certbot renew -q" | sudo tee -a /etc/crontab > /dev/null

这个是从官方文档复制出来的,每天两次,大概是0点/12点之后的一个小时内运行。

关于更新之后如何通知nginx重新加载证书,可以参考我之前的文章


最后修改于 2024-11-01