Trojan 节点证书过期的排查与自动续签方案

作为一名长期维护 Trojan 节点的用户,我最近遇到了一个典型问题:节点突然无法连接,排查后发现是 SSL 证书过期了。这种问题在长期运行的节点中很常见,今天我就来分享一套完整的排查流程和自动化续签方案。
证书过期现象与快速排查
那天早上,我收到用户反馈说节点连不上。首先我检查了服务器状态,一切正常。接着查看 Trojan 服务日志:
journalctl -u trojan -f
日志中出现了关键错误信息:”SSL handshake failed: certificate has expired”。这明确指向了证书问题。
要确认证书状态,我使用了 openssl 命令:
openssl x509 -in /path/to/certificate.crt -noout -dates
果然,输出显示证书已经过期。这就是导致服务中断的元凶。
手动续签证书的完整流程
在设置自动化之前,我们先走一遍手动续签流程,这有助于理解整个过程:
首先停止 Trojan 服务:
systemctl stop trojan
使用 acme.sh 申请新证书(我使用的是 Let’s Encrypt):
acme.sh --issue --dns dns_cf -d yourdomain.com
安装新证书到 Trojan 配置目录:
acme.sh --install-cert -d yourdomain.com
--cert-file /etc/trojan/cert.crt
--key-file /etc/trojan/private.key
--reloadcmd "systemctl restart trojan"
重启 Trojan 服务:
systemctl start trojan
验证服务状态:
systemctl status trojan
搭建自动化续签系统
手动续签太麻烦,我设计了一个自动化方案。核心是利用 acme.sh 的自动续签功能和系统定时任务。
首先确保 acme.sh 已正确安装并配置:
curl https://get.acme.sh | sh
source ~/.bashrc
设置 Cloudflare API(以 DNS 验证方式为例):
export CF_Key="your_cloudflare_api_key"
export CF_Email="your_email@example.com"
创建证书更新脚本:
#!/bin/bash
# /opt/scripts/cert-renew.sh
DOMAIN="yourdomain.com"
CERT_DIR="/etc/trojan"
echo "$(date): Starting certificate renewal for $DOMAIN"
/root/.acme.sh/acme.sh --renew -d $DOMAIN --force
if [ $? -eq 0 ]; then
cp /root/.acme.sh/$DOMAIN/fullchain.cer $CERT_DIR/cert.crt
cp /root/.acme.sh/$DOMAIN/$DOMAIN.key $CERT_DIR/private.key
systemctl restart trojan
echo "$(date): Certificate renewed successfully"
else
echo "$(date): Certificate renewal failed"
exit 1
fi
给脚本执行权限并添加到 crontab:
chmod +x /opt/scripts/cert-renew.sh
crontab -e
添加以下行(每周一凌晨检查续签):
0 2 * * 1 /opt/scripts/cert-renew.sh >> /var/log/cert-renew.log 2>&1
监控与告警机制
自动化还不够,还需要监控。我设置了一个简单的证书过期检查脚本:
#!/bin/bash
# /opt/scripts/cert-check.sh
DOMAIN="yourdomain.com"
DAYS_THRESHOLD=30
expiry_date=$(openssl x509 -in /etc/trojan/cert.crt -noout -enddate | cut -d= -f2)
expiry_epoch=$(date -d "$expiry_date" +%s)
current_epoch=$(date +%s)
days_until_expiry=$(( (expiry_epoch - current_epoch) / 86400 ))
if [ $days_until_expiry -le $DAYS_THRESHOLD ]; then
echo "WARNING: Certificate for $DOMAIN expires in $days_until_expiry days" |
mail -s "Certificate Expiry Warning" admin@yourdomain.com
fi
同样添加到 crontab,每天检查一次:
0 8 * * * /opt/scripts/cert-check.sh
踩坑经验分享
在实施过程中,我遇到了几个坑:
1. 权限问题:确保脚本有权限读取证书文件和重启服务
2. 路径问题:acme.sh 的路径可能因安装方式不同而有所变化
3. 服务重启时机:不要在证书更新过程中重启服务,要等文件完全写入后再重启
经过这番折腾,我的 Trojan 节点已经稳定运行了半年多,再也没出现过证书过期导致的服务中断。希望这个方案对大家有所帮助!

刚好遇到同样问题,感谢分享!