acme.sh不能自动更新证书的问题
本文描述了一种使用acme.sh
颁发的证书始终不能正常自动更新的问题,并记录了解决过程。
在服务器上使用了acme.sh
来颁发ssl证书,按照官方指导在用户user1
根目录下安装了acme.sh
,并在root
用户下执行如下命令(如不在root下执行,会报提醒,建议到root下执行),成功颁发了证书:
/home/user1/.acme.sh/acme.sh --set-default-ca --server letsencrypt --issue -d test_domain.com --standalone --keylength ec-256 --force |
然后在root
下执行了将证书安装到指定目录下的操作:
/home/user1/.acme.sh/acme.sh --install-cert -d test_domain.com --ecc \ |
一切正常的话,按照官方所描述的,crontab
中会每日自动检查证书是否需要renew
,然后根据情况在快要到期时(acme.sh
默认证书有效期为90天,到期前30天会自动更新。注意有效期最多只有90天,不能延长,参见此处)更新。
但是在实际操作中,始终不能如预期正常更新证书。user1
下检查定时任务
sudo crontab -l |
查看结果:
48 0 * * * "/home/user1/.acme.sh"/acme.sh --cron --home "/home/user1/.acme.sh" > /dev/null |
由于一直没找到原因,故每次到期后都需要手动更新证书:
sudo ~/.acme.sh/acme.sh --renew -d test_domain.com --force --ecc --reloadcmd "systemctl reload nginx ; systemctl restart v2ray" |
上述命令执行在用户user1
下。最后的参数是在执行后重启nginx
和v2ray
。
手动更新正常(这很奇怪,可能是因为在root
与user1
下都生成了证书,保留了两个目录下的参数与证书,并在根目录下生成证书时输入了错误的域名?检查发现root
下也安装了acme.sh
,将其卸载,并删除了.acme.sh/
目录。)。
一直对acme.sh
定时更新的工作流程,特别是为什么在crontab
的定时任务里不需要传参的原因不是很理解,于是花了点时间检索,发现了相关解答。即在执行--install-cert
后参数会保存,自动更新时调用之,故不需要在crontab
中传参。
然后尝试直接debug
执行更新操作:
"/home/user1/.acme.sh"/acme.sh --cron --home "/home/user1/.acme.sh" --debug |
发现执行日志有如下内容:
[Thu Oct 12 10:33:01 UTC 2023] ===Starting cron=== |
从上述内容可见问题出现在参数配置文件目录出错,导致找不到.acme.sh/*.*/
文件。这才意识到安装acme.sh
脚本的目录是在user1
根目录下,但是在申请证书是在root
根目录下操作的。执行了:
sudo su - |
造成目录切换到了root
根目录下,运行--issue
域名的操作生成的文件直接保存在了root
根目录下,即证书、配置的目录与脚本的目录不匹配。程序自动更新时在脚本目录/home/user1/.acme.sh
下寻找不到所需的证书与参数,因而出错、忽略了。加上日志直接输到了/dev/null
,故一直没找到原因。
修改--home
后debug
:
"/home/user1/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" --debug |
发现结果显示包含如下内容:
[Thu Oct 12 10:47:17 UTC 2023] di='/root/.acme.sh/test_domain_ecc/' |
显然,这次脚本成功检查了证书的有效期,并跳过了不需要更新的证书。可判断这回脚本能够正确运行了。
在root
下修改crontab
中的任务:
crontab -e |
将--home
参数后的目录修改一下:
48 0 * * * "/home/user1/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null |
即可正常自动更新了。