使用 Certimate 管理并通过 SSH 自动更新域名证书

:certimate Certimate 是一个 SSL 中心化管理工具,方便对多个主机🖥️上的域名证书🔐进行集中管理。只是当作 acme.sh 的前端替代很好上手,但如果你想使用“自动”功能,坑还是不少的。

⏳定时任务失效

这是一个已知 bug,在我提交这个 issue 之前,应该有不少人都遇到过类似问题。简言之,就是某些前端支持的 cron 语法不兼容 crontab,而后台在没有进行转换🔄或拒绝🙅‍♂️的情况下抛出异常。目前的解决方式就是使用 crontab 兼容语法,比如去 crontab.guru 验证一下,就像这条讨论提到的,举个例子: 0 0 * * Tue 👉 ``0 0 * * 2`

:terminal: 无法通过 ssh 上传证书

工作流
授权配置

如果是密码👀认证方式,那么大概率是上传路径填错了。⚠️注意这里的四个“路径”都是指的远端服务器,而非前两个是本地,后两个是被部署端。具体来说📣,证书文件上传路径是 fullchain,证书私钥文件上传路径是 key,服务器证书文件上传路径是 cert,中间证书文件上传路径是 Intermediate,这里中文表述并不十分准确。还有一种可能性是读写权限不够,这里需要确保用于登录的账户对 ssl 证书所在文件夹有执行权限,对证书文件有写权限

如果使用密钥鉴权方式,注意 <SSH 密钥>一栏需要填写本地生成的私钥,并且对应的公钥需要添加到远端主机对应账户的文件夹下。⚠️这里既不是填公钥,也不是远端服务器的私钥🫠。

🔔Telegram 通知不起作用

老版本是在“系统设置👉通知渠道”中进行配置,新版将切换到授权管理模块。需要注意的是,如果从本地无法访问 api.telegram.org,那么通知提醒将直接失败。所以,我更推荐用云函数中转并采用 Webhook 的方式,这样既解决了域名访问受限,也便于统一接口。分享我使用 cloudflare worker 实现的关键代码:

worker.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const msg = reqBody['msg'] || '';
const msgParts = msg.split('|');
const messageText = decodeURIComponent(msgParts[0] || '');
const buttonUrl = msgParts[1] || '';
const buttonText = decodeURIComponent(msgParts[2] || '🔗链接');

let param = {
chat_id: env.TG_CHAT_ID,
parse_mode: 'markdown',
text: messageText,
reply_markup: {
inline_keyboard: []
}
}

if (buttonUrl) {
param.reply_markup.inline_keyboard.push([{
text: buttonText,
url: buttonUrl
}]);
}

let resp = await sendMessage(`${env.TG_HOST}${env.TG_TOKEN}/sendMessage`, param);
respBody.push('tgbot: ' + resp.status)

这里还有另一个坑🤧,注意 Webhook 回调地址不能有前后空格,否则也是直接失败,这在复制粘贴的时候容易发生。我想说,对用户输入的信息 trim 一下不是默认操作吗:尴尬:

那么朋友,三个坑你都踩过吗?

另外,失败了不要怕,大胆 debug,正常情况下你应该设置了短时间重复执行工作流不会再次申请证书。发现了新的 bug 记得去仓库提 issue。开源你我他,维护靠大家~