使用 acme.sh 自动更新 ssl 证书

今天发现 SSL 证书过期了,本来打算人工来 ZeroSSL 人工申请下更新下证书就算了,但是发现这次还是要验证 DNS,然后发现每次设置后使用 dnslookup 都可以看到效果了,点击 NEXT 还有会说不匹配,因为每次提交都要等好几分钟,几次不成我就不想再试了。打算再再次尝试下使用 Let’s Encrypt 的 SSL 自动更新的客户端(acme.sh),发现 在 shell 下 tab 键 都不会自动提示了,发现硬盘爆了,被 jenkins 的日志塞满了。记录下今天遇到几个问题的解决办法:

使用 du -h --max-depth=1 命令查看硬盘使用的情况,发现是日志文件 /var/log/jenkins/jenkins.log 文件达到了 10+g,删除后 使用 df -h 命令查看磁盘空间,发现并没有立即释放,然后又去 百度了 “linux删除文件后没有释放空间”,发现是 linux 默认进程运行的情况下,会标记使用到的文件,并不会立即的释放空间,使用 lsof |grep deleted 命令查看已经删除但是还没有释放的文件,找到进程 id, kill 掉 jenkins 进程后,再次查看磁盘大小,总算腾出来空间了。

然后开始整证书的问题,看了下 certbot 还是不支持 ubuntu 下面调用 acme v2 的接口,只支持在 docker 下面启动一个然后去申请,因为在 docker 下执行也比较麻烦,还得停掉 本机运行的 nginx 腾出80,443端口,太麻烦了,则选用 aceme.sh 这个文件,而且有比较完整中文的文档。可能是我今天运气不好,上次使用 dnspod 的 token 添加 TXT record 的时候已经添加了一个 token,这次 export DP_Id 和 DP_Key 之后发现还是不能添加成功,后来查了一下看了下别人执行的时候参数 debug 参数给了一个2,可以显示出接口返回的信息,返回的是dnspod的验证没有成功,我看了下请求的url 上的登录参数,发现使用的不是我刚 export 出来的,然后找了下,发现 acme.sh 同级目录下有一个 account.conf 的配置文件,打开后发现里面配置的 DP_Id 和 DP_Key 是上次的,修改为本次的后重新调用,MMP,这次直接 ACME 的调用次数限制把我挡住了,说我调用了太多次都失败了,看了ACME 接口限制每个域名一个周最多调用20次申请,所以最近只能等等了,等一个礼拜后重新执行 acme.sh --debug 2 --issue --dns dns_dp -d firegod.cn -d *.firegod.cn文章后面给了更简单的自动更新证书的方法,不需要再修改域名解析

更新于2018年07月24日:

今天重新试了一下接口可以调用了,但是一直会说 域名的 TXT 记录没有生效,但是使用 nslookup 命令已经可以返回 TXT 记录了,百度了一下,网上说是如果有 CNAME 类型的解析,TXT 的就会失效,难道Let’s Encrypt验证的方式是通过浏览这个地址返回的内容来做验证的?暂停掉 CNAME 类型的泛域名的解析,过上几分钟等直接访问URL返回的是 TXT 记录的内容后再试试。

更新于2018年07月26日

去掉 CNAME 的泛域名解析后,执行上面命令的时候增加了 --dnssleep 700 的命令,强制让等到700秒后再去检查证书有效性,没注意看,时间到了后发现证书已经成功的申请到了保存在 .acme.sh目录下对应的域名目录下了

更新于2018年09月08日

今天更新证书,执行的命令是

acme.sh --debug 2 --issue --dnssleep 10 --dns dns_dp -d firegod.cn -d *.firegod.cn --force

更新于2018年12月23日
申请到的证书中如果在火狐或者android手机浏览器中报告说是证书有问题,实际上可能是缺少中间证书信任链,可以参考我这篇文章解决:

更新于2019年02月25日
今天发现证书又过期了,还是没有自动更新,而且我上面给的命令无法更新泛域名,于是经过我再次探索,发现可以直接使用 acme.sh –renew-all 来自动刷新所有的证书,此命令会智能的更新需要更新的证书,而不会更新最新才更新过的证书。例如下面这样的提示:

然后我使用下面的命令重新安装了cron任务,这下应该可以高枕无忧了。

yangyan@VM-202-6-ubuntu:~$ acme.sh --uninstall-cronjob
[2019年 02月 25日 星期一 22:09:15 CST] Removing cron job
yangyan@VM-202-6-ubuntu:~$ acme.sh --install-cronjob
[2019年 02月 25日 星期一 22:09:20 CST] Installing cron job

更新于2019年03月03日

因为泛域名的证书,二级的泛域名只支持二级泛域名,如果是想要添加其他的域名,可以执行 :

acme.sh --debug 2 --issue --dnssleep 10 --dns dns_dp -d a.b.c.firegod.cn

后续再执行 –renew-all 命令的时候就会自动更新新增的域名了

更新于2020年04月22日:

今天发现 -renew-all 命令不能用了,最新的可以正常执行的命令是:

acme.sh --cron

更新与2020年05月05日:

今天我换了一个服务器,nginx 的配置丢了,所以需要重新配置一下ssl,下面这个两个环境的值,可以登录DNSPOD申请API获取。如果是其他的域名解析服务商,可能也是类似的,看一下官方文档,估计变量名可能不同。

export DP_Id="xxx"
export DP_Key="xxx"

然后执行:

~/.acme.sh/acme.sh --issue -d firegod.cn -d *.firegod.cn --dns dns_dp

今天发现一个命令可以自动的将acme.sh申请到的证书配置到nginx下面,虽然我的没有自动配置成功,但是却实现了复制证书到指定的地址,然后我人工配置了证书到nginx,下面的路径给的是需要将acme.sh申请到的证书复制到的路径,后面的那个reloadcmd参数是指,以后当证书更新后会自动执行的命令:

~/.acme.sh/acme.sh --install-cert -d firegod.cn \
--key-file       /opt/nginx/ssl/firegod.cn.key  \
--fullchain-file /opt/nginx/ssl/firegod.cn.crt \
--reloadcmd     "service nginx force-reload"

然后去nginx配置文件中添加:

ssl_certificate      /opt/nginx/ssl/firegod.cn.crt;
ssl_certificate_key  /opt/nginx/ssl/firegod.cn.key;