云服务器面板申请Let's Encrypt证书自动同步至其他服务器
由于拥有一台云服务器,还拥有一台家中的 Mac mini 服务器,所以需要一个证书在不同服务器间同步。早些年腾讯云、阿里云等云服务商还可以手动申请有效期为 1 年的证书,但是如今政策收紧,不得已转向有效期 3 个月的 Let's Encrypt 证书。但是每 3 个月就要手动替换证书还是太麻烦。幸好 Linux 面板如宝塔和 1Panel 提供自动申请证书的服务。只需要授予 DNS 提供商的密钥,就可以自动在到期前申请。面板所在的服务器非常简单,面板已经提供自动更新的服务。可是要在不同服务器间同步可难住了:ssh 目录或文件通常有较为特殊的权限,使用 scp 或 rsync 无法直接更新这些目录;而且在远端很难获取权限来操作这些目录。在询问 ChatGPT 后,找到了这一问题的安全解决方法。
申请证书
这一步在各大面板都可可视化操作,就不展开来说。需要注意的是如果要申请泛域名证书,主域名可以在前面带星号,其他域名可以写域名本身。例如:主域名填写*.ipangbo.cn ,其他域名填写ipangbo.cn 。
在申请证书的同时,需要勾选推送证书到本地目录选项。不同面板说法不同,但都有该选项。以下内容假设推送证书到本地/home/ubuntu/keychains目录,文件名分别为fullchain.pem和privkey.pem。
申请后触发脚本
面板中会有申请证书之后触发脚本的设置,填入以下脚本:
# 推送到临时目录
scp -i /home/ubuntu/.ssh/secondary_server.key -P 22 \
/home/ubuntu/keychains/fullchain.pem \
[email protected]:/tmp/server.crt
scp -i /home/ubuntu/.ssh/secondary_server.key -P 22 \
/home/ubuntu/keychains/privkey.pem \
[email protected]:/tmp/server.key
# 触发免密部署与重载
ssh -i /home/ubuntu/.ssh/secondary_server.key -p 22 [email protected] \
'sudo /usr/local/sbin/deploy_apache_cert.sh'请注意修改目录,改为自己的用户名,端口和路径。也可修改文件名,但一定要与之后的步骤对应。
远端服务器执行脚本
上一部分,申请证书的服务器已经拷贝证书和密钥到/tmp中了。接下来,我们将其移动到ssh文件夹中并妥善处理权限。新建该脚本:
sudo vim /usr/local/sbin/deploy_apache_cert.sh/usr/local/sbin/通常放系统管理员自己安装的系统管理脚本或命令。
脚本内容如下:
#!/bin/bash
set -euo pipefail
CRT_SRC="/tmp/server.crt"
KEY_SRC="/tmp/server.key"
CRT_DST="/Users/user/.ssh/server.crt"
KEY_DST="/Users/user/.ssh/server.key"
# Validation
[ -s "$CRT_SRC" ] || { echo "missing $CRT_SRC"; exit 1; }
[ -s "$KEY_SRC" ] || { echo "missing $KEY_SRC"; exit 1; }
# Backup
ts=$(date +%Y%m%d-%H%M%S)
if [ -f "$CRT_DST" ]; then /bin/cp -p "$CRT_DST" "${CRT_DST}.${ts}.bak"; fi
if [ -f "$KEY_DST" ]; then /bin/cp -p "$KEY_DST" "${KEY_DST}.${ts}.bak"; fi
# Cover Cert
/bin/mv "$CRT_SRC" "$CRT_DST"
/bin/mv "$KEY_SRC" "$KEY_DST"
/usr/sbin/chown ipangbo:staff "$CRT_DST" "$KEY_DST"
/bin/chmod 644 "$CRT_DST"
/bin/chmod 600 "$KEY_DST"
# Reload
/usr/sbin/apachectl configtest
/usr/sbin/apachectl graceful
echo "OK: certs installed & apache reloaded."请注意修改开头变量路径。但该脚本如没有超级用户权限还是不能执行。下一步我们允许用户对该脚本NOPASSWD。
echo 'user ALL=(root) NOPASSWD: /usr/local/sbin/deploy_apache_cert.sh' \
| sudo tee /etc/sudoers.d/certsync >/dev/null
sudo visudo -cf /etc/sudoers.d/certsync注意修改用户名。以上命令实际上在sudoer文件中写入用户可以免密运行该具有管理员权限的脚本,并且验证。
到此,每当到期日自动申请证书时,服务器便能自动更新证书,无需人工操作。本文配合上篇文章,实现了自动为家中 Mac mini 服务器更新 https 证书,让家中 Mac mini 服务器变成更好的影音服务器。