创建证书
docker run -it --rm --name certbot-dns-aliyun \
-v "/etc/letsencrypt:/etc/letsencrypt" \
-v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
-e ALIYUN_CLI_ACCESS_KEY_ID=<ALIYUN_CLI_ACCESS_KEY_ID> \
-e ALIYUN_CLI_ACCESS_KEY_SECRET=<ALIYUN_CLI_ACCESS_KEY_SECRET> \
aiyax/certbot-dns-aliyun certonly \
-d <CERT_DOMAIN> \
--manual \
--preferred-challenges dns \
--manual-auth-hook 'aliyun-dns' \
--manual-cleanup-hook 'aliyun-dns clean'
创建证书只需执行以上命令,当然,该命令需要服务器已安装Docker。另外,需要替换下命令中的三个变量:
-
CERT_DOMAIN,需要获取证书的域名,比如
aiyax.com
,chat.aiyax.com
或者*.aiyax.com
。 -
ALIYUN_CLI_ACCESS_KEY_ID,阿里云的AccessKey ID,如何获取下面会详细介绍。
-
ALIYUN_CLI_ACCESS_KEY_SECRET,阿里云的AccessKey Secret,获取方式同上。
AccessKey在阿里云控制台的右上角账号下进行管理。
进入后阿里云会建议使用子用户的AccessKey,建立RAM用户并生成AccessKey即可。权限最小化原则,这里只开放OpenAPI访问。
创建用户后,就可看到对应的AccessKey ID和AccessKey Secret了。
注意,还没结束,这时我们需要对该用户授权,使其可以对云解析进行查插删改操作。只赋予其AliyunDNSFullAccess权限即可。
这样,我们就拿到了AccessKey ID及Secret, 同时,也为其赋予了相应的访问权限。具体可以参考:https://help.aliyun.com/zh/ram/user-guide/create-an-accesskey-pair
更新证书
更新证书更加方便,因为Certbot会自动查找并续订已经存在的证书而无需指定域名。使用如下命令即可轻松检查并续订:
docker run -it --rm --name certbot-dns-aliyun \
-v "/etc/letsencrypt:/etc/letsencrypt" \
-v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
-e ALIYUN_CLI_ACCESS_KEY_ID=<ALIYUN_CLI_ACCESS_KEY_ID> \
-e ALIYUN_CLI_ACCESS_KEY_SECRET=<ALIYUN_CLI_ACCESS_KEY_SECRET> \
aiyax/certbot-dns-aliyun renew \
--manual \
--preferred-challenges dns \
--manual-auth-hook 'aliyun-dns' \
--manual-cleanup-hook 'aliyun-dns clean' \
--non-interactive
当然,更佳的办法是配置Crontab,这样服务器可以定期检查并续订。
下面是一个crontab的例子,其中需要提前配置环境变量ALIYUN_CLI_ACCESS_KEY_ID和ALIYUN_CLI_ACCESS_KEY_SECRET,可以将它们写入 /etc/environment 以防止服务器重启后丢失环境变量。与此同时,我们需要使用一个deploy-hook.sh脚本来重启web服务以使证书被部署生效。 注意替换</path/to/deploy-hook.sh>。
# 每5/15/25号3点执行certbot renew,注意替换</path/to/deploy-hook.sh>
0 3 5,15,25 * * docker run -it --rm --name certbot-dns-aliyun -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt" -e ALIYUN_CLI_ACCESS_KEY_ID="${ALIYUN_CLI_ACCESS_KEY_ID}" -e ALIYUN_CLI_ACCESS_KEY_SECRET="${ALIYUN_CLI_ACCESS_KEY_SECRET}" aiyax/certbot-dns-aliyun renew --manual --preferred-challenges dns --non-interactive | grep "Congratulations, all renewals succeeded" && </path/to/deploy-hook.sh>
以上的Crontab中的5,15,25
可以根据需求自行调整,有两点需要考虑:
-
Let's encrypt证书只有达到一定时间才会renew,即过期前30天。
-
过于频繁的renew会被限制。
02 思路
那么,该自动化是如何一步步实现的呢?
首先,让我们梳理一下场景,我们使用的是Let's Encrypt组织颁发的免费证书,使用Certbot这个软件来实现创建和续订。那么,第一步便是自动化执行certbot renew命令,这倒是简单,配置crontab即可。
然后,我们需要让renew的整个过程自动完成、没有交互。这一步需要详细调研下,查阅资料可以得到以下几点:
-
Certbot生成的证书有效期为90天
-
Renew在证书过期前30天开始生效。
-
Renew时需要验证对域名的控制权,可以是HTTP验证或者DNS验证。
对比可以发现,DNS验证比HTTP验证逻辑简单,所以更容易自动化。DNS验证只需在域名的DNS记录中添加特定的TXT记录,而HTTP验证需要将Certbot生成的特殊文件部署在域名的指定路径下,若Web服务部署在动态环境中或者有负载均衡,问题无疑将被复杂化。
下一步,尝试实现DNS验证的自动化。
对于DNS的自动化验证,Certbot提供了支持,比如manual-auth-hook,并且针对许多域名解析服务有现成的插件支持。
可惜,这里面没有对阿里云的支持,还好,阿里云提供了管理云资源的命令行工具Alibaba Cloud CLI。通过该工具,我们可以通过命令行来对云解析进行添加、删除等操作,这就完美地解决了DNS验证的自动化。
接下来,就是如何设计脚本让运维可以更简单地复用,因为整个步骤要安装至少两个软件——certbot和aliyun-cli,之前安装certbot时遇到过报错的情况,所以就决定使用Docker镜像将这两个软件封装到一起。这样,就可以用docker方便地使用这两个工具,再也不用担心安装失败。
下一步,就是设计DNS验证的脚本。这也比较简单,主要分两步:
-
配置aliyun-cli的身份认证信息,我选择了比较简单的AccessKey。
-
通过aliyun-cli来操作云解析来添加和删除解析记录,当然,要解析的域名信息以及TXT解析值都已被manual-auth-hook放到环境变量里。
然后,将脚本打包进Docker,通过cron定时执行docker run命令,来催动cerbot命令,再通过manual-auth-hook来执行脚本,来调用aliyun-cli修改域名解析记录,从而实现证书续订功能的完全自动化。
03 结语
最后,所有代码都在Github,欢迎Star:https://github.com/aiyaxcom/certbot-dns-aliyun
版权声明:本站资源来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系客服并出示版权证明以便删除!
发表评论