Pmail无限重启竟是证书过期惹得祸——编写证书同步脚本解决
前清提要:
为了方便使用,我用podman-compose 文件部署了pmail,配置如下:
#pmail-compose.yml
version: '3'
services:
pmail:
image: ghcr.io/jinnrry/pmail:latest
container_name: pmail
restart: always
ports:
- "25:25"
- "80:80"
- "443:443"
- "110:110"
- "465:465"
- "995:995"
- "993:993"
volumes:
- "/root/podman/pmail/config:/work/config"
这样,更新pmail版本只需要执行:
podman stop pmail
podman rm pmail
podman rmi pmail:latest
podman-compose -f pmail-compose.yml up -d
就能完成数据无损更新。
但是今天发现kmail无法正常连接邮件服务器,打开浏览器一检查后台,发现web后台也挂了,那肯定是后端服务出问题了。
遂SSH上线Debug。podman logs -f pmail
发现日志疯狂刷新不带停的,Ctr+C 好几次后才停下来。报错和ssl.go等文件有关系,我不是开发者也看不明白,不过报错文件路径前有一句指向明确的英语意思是警告证书过期,这句倒是看懂了🤣。
那么接下来就是更新证书了,查看服务配置文件发现,我配置的是手动管理证书。
参见: 配置文件说明
{
"logLevel": "",
"domain": "linuxuser.site",
"domains": [
"linuxuser.site"
],
"webDomain": "mail.linuxuser.site",
"dkimPrivateKeyPath": "/work/config/dkim/dkim.priv",
"sslType": "1",
"SSLPrivateKeyPath": "/work/./config/ssl/private.key",
"SSLPublicKeyPath": "/work/./config/ssl/public.crt",
"dbDSN": "/work/config/pmail.db",
"dbType": "sqlite",
"httpsEnabled": 0,
"spamFilterLevel": 1,
"httpPort": 0,
"httpsPort": 0,
"weChatPushAppId": "",
"weChatPushSecret": "",
"weChatPushTemplateId": "",
"weChatPushUserId": "",
"tgBotToken": "",
"tgChatId": "",
"isInit": true,
"webPushUrl": "",
"webPushToken": ""
}
显然是当初部署的时候因为已经有服务器部署了ACME.sh更新证书所以不能用项目推荐的证书更新管理方式;这等于是又挖了个更新的坑————配置A-B服务器证书文件同步。
编写证书同步脚本:
首先要厘清我的服务架构,我在ClawHK服务器(也就是本博客所在的服务器)部署了ACME.sh管理证书并对其他服务器线路不佳的Web服务(RackNerd-USA)进行反代,因此证书本身是处于ClawHK上的,现在我需要把它同步到Racknerd-USA的指定路径供PMail使用。
先自己简单写出来基本操作流程,再用DeepSeek和ChatGPT进行细节润色。
#!/bin/bash
# PmailSSLSync.sh
# 本脚本应该运行在Racknerd-USA
# 定义变量
local_private_key_path="/root/podman/pmail/config/ssl/private.key"
local_public_key_path="/root/podman/pmail/config/ssl/public.crt"
remote_private_key_path="/home/xfox/www/all_linuxuser.site/privkey.pem"
remote_public_key_path="/home/xfox/www/all_linuxuser.site/fullchain.pem"
temp_dir=$(mktemp -d /tmp/cert_sync_XXXXXX)
# 停止服务
sudo podman stop pmail
# 删除本地过期证书
sudo rm -f "$local_private_key_path" "$local_public_key_path"
# 从ClawHK同步证书文件到临时目录
sudo rsync -avz -e "ssh -i /root/.ssh/id_ed25519 -o StrictHostKeyChecking=no" \
xfox@xfox.fun:"$remote_private_key_path" \
xfox@xfox.fun:"$remote_public_key_path" \
"$temp_dir/"
# 检查文件是否存在
if [ ! -f "$temp_dir/privkey.pem" ] || [ ! -f "$temp_dir/fullchain.pem" ]; then
echo "证书同步失败!"
sudo podman start pmail
exit 1
fi
# 移动证书到最终位置
sudo mkdir -p "/root/podman/pmail/config/ssl"
sudo mv "$temp_dir/privkey.pem" "$local_private_key_path"
sudo mv "$temp_dir/fullchain.pem" "$local_public_key_path"
sudo chmod 600 "$local_private_key_path"
sudo chmod 644 "$local_public_key_path"
# 清理临时目录
rm -rf "$temp_dir"
# 重启服务
sudo podman start pmail
有脚本了,还得保证脚本及脚本所需命令能能按时跑。
在邮件服务器上安装好所需工具,并添加定时任务apt install crontab rsync
crontab -e
添加如下条目
0 4 * * * /root/PmailSSLSync.sh
应该不会有人凌晨四点给我发邮件吧 ;)
添加完成后检查一下:crontab -l
大功告成!