安装 acme.sh
acme.sh 是一个轻量级的 ACME 客户端,支持 Let’s Encrypt、ZeroSSL 等证书自动签发。
# 安装 acme.sh
curl https://get.acme.sh | sh
# 安装完成后,加载环境变量
export PATH="$HOME/.acme.sh:$PATH"
# 验证安装
acme.sh --version
安装目录默认在 ~/.acme.sh,后续脚本里最好使用绝对路径 /root/.acme.sh/acme.sh 避免 PATH 问题。
acme.sh 默认切到了 ZeroSSL
强制切换 CA 到 Let’s Encrypt
acme.sh --set-default-ca --server letsencrypt
配置阿里云 DNS API(用于 DNS 验证)
1. 登录阿里云,进入 RAM 控制台 创建 AccessKey ID/Secret,记得进行授权
2. 在 ~/.acme.sh/dnsapi/ 下配置 dns_ali.sh:
export Ali_Key="你的AccessKeyID"
export Ali_Secret="你的AccessKeySecret"
这是 acme.sh 用来通过 DNS 验证域名所有权。
签发证书
单域名证书
/root/.acme.sh/acme.sh --issue \
--dns dns_ali \
-d example.com
多域名证书(包含www)
/root/.acme.sh/acme.sh --issue \
--dns dns_ali \
-d example.com \
-d www.example.com
签发成功后,证书的路径一般是
~/.acme.sh/example.com/
├── example.com.cer # 站点证书
├── example.com.key # 私钥
├── ca.cer # 中间 CA
└── fullchain.cer # 完整证书链(站点证书 + 中间证书)
安装aiyuncli
curl -fsSL https://aliyuncli.alicdn.com/install.sh | sh
配置ak
aliyun configure
注册地就填这个: cn-hangzhou
其他按需填写
生成 CDN 专用证书文件
阿里云 CDN 上传证书需要 站点证书 + 中间证书 合并:
合并 PEM
cat ~/.acme.sh/example.com/example.com.cer ~/.acme.sh/example.com/ca.cer > /home/key/cdn.pem
拷贝私钥
cp ~/.acme.sh/example.com/example.com.key /home/key/cdn.key
使用阿里云 CLI 上传 CDN 证书
阿里云 CLI 命令示例:
单域名示例
aliyun cdn SetCdnDomainSSLCertificate \
–DomainName example.com \
–CertType upload \
–SSLProtocol on \
–SSLPub “$(cat /home/key/cdn.pem)” \
–SSLPri “$(cat /home/key/cdn.key)”
多域名示例
aliyun cdn SetCdnDomainSSLCertificate \
–DomainName www.example.com \
–CertType upload \
–SSLProtocol on \
–SSLPub “$(cat /home/key/cdn.pem)” \
–SSLPri “$(cat /home/key/cdn.key)”
注意:阿里云 CLI 的 –SSLPub 和 –SSLPri 必须是内容,不能直接写文件路径。
自动化脚本(单脚本完成生成+上传+nginx reload)
#!/bin/bash
export PATH=$PATH:/root/.acme.sh
set -e
# --- 配置 ---
DOMAIN_ROOT="example.com"
DOMAINS=("$DOMAIN_ROOT" "www.$DOMAIN_ROOT")
ACME_BIN="/root/.acme.sh/acme.sh"
CERT_DIR="/root/.acme.sh/${DOMAIN_ROOT}"
KEY_DIR="/home/key"
CDN_PEM="$KEY_DIR/cdn.pem"
CDN_KEY="$KEY_DIR/cdn.key"
CDN_PUB_HASH_FILE="$KEY_DIR/cdn_pub_hash"
NGINX_RELOAD_CMD="systemctl reload nginx"
LOG_FILE="/var/log/update_cdn_cert.log"
{
echo "=== $(date) - Start certificate update ==="
# 签发证书
$ACME_BIN --issue -d "$DOMAIN_ROOT" -d "www.$DOMAIN_ROOT" --dns dns_ali
# 生成 CDN PEM 文件
cat "$CERT_DIR/$DOMAIN_ROOT.cer" "$CERT_DIR/ca.cer" > "$CDN_PEM"
cp "$CERT_DIR/$DOMAIN_ROOT.key" "$CDN_KEY"
# reload nginx
$NGINX_RELOAD_CMD || true
# 检查是否更新
NEW_HASH=$(sha256sum "$CDN_PEM" | awk '{print $1}')
if [[ -f "$CDN_PUB_HASH_FILE" && "$(cat $CDN_PUB_HASH_FILE)" == "$NEW_HASH" ]]; then
echo "$(date) - Certificate not changed, skipping CDN update."
exit 0
fi
echo "$(date) - Certificate changed, updating CDN ..."
for d in "${DOMAINS[@]}"; do
echo "Updating CDN certificate for $d ..."
aliyun cdn SetCdnDomainSSLCertificate \
--DomainName "$d" \
--CertType upload \
--SSLProtocol on \
--SSLPub "$(cat $CDN_PEM)" \
--SSLPri "$(cat $CDN_KEY)"
done
echo "$NEW_HASH" > "$CDN_PUB_HASH_FILE"
echo "$(date) - All done!"
} > "$LOG_FILE" 2>&1
这个脚本特点:
• 支持单域名和多域名。
• 自动生成 CDN PEM。
• 只有证书变化时才上传 CDN。
• 日志每天覆盖 /var/log/update_cdn_cert.log。
• 自动 reload nginx。
设置定时任务
每天检查证书更新(覆盖日志):
0 2 * * * /root/update_cdn_cert.sh
这样每天凌晨会自动检测和更新证书,如果证书快到期则续签并上传 CDN。