前言
Let's Encrypt 提供免费 SSL 证书,但通配符证书(*.example.com)必须通过 DNS 验证。本文介绍如何使用阿里云 DNS + 自定义 hook 脚本实现自动化申请和续期。
为什么需要通配符证书
通配符证书可以保护主域名及其所有一级子域名:
example.com*.example.com(www、api、mail 等)
相比为每个子域名单独申请证书,通配符证书管理更简单,成本为零。
准备工作
1. 安装必要工具
# 安装 certbot
apt-get update && apt-get install -y certbot
# 安装阿里云 CLI
curl -sSL https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz | tar xz
mv aliyun /usr/local/bin/
2. 配置阿里云凭证
aliyun configure
输入你的 AccessKey ID 和 AccessKey Secret(在阿里云控制台 RAM 访问控制中创建)。
自定义 DNS Hook 脚本
创建脚本 /usr/local/bin/aliyun-dns-hook.sh:
#!/bin/bash
set -e
# 阿里云 DNS Hook 脚本 for Let's Encrypt
ACTION=$1
DOMAIN=$2
VALUE=$3
# 等待 DNS 生效的函数
wait_dns_propagation() {
local txt_record=$1
local max_attempts=30
local attempt=1
echo "等待 DNS 记录生效..."
while [ $attempt -le $max_attempts ]; do
# 使用 dig 验证 TXT 记录
if dig +short TXT "_acme-challenge.${DOMAIN}" | grep -q "$txt_record"; then
echo "DNS 记录已生效!"
return 0
fi
echo "第 $attempt 次检查,等待 10 秒..."
sleep 10
attempt=$((attempt + 1))
done
echo "警告:DNS 记录未在预期时间内生效,继续尝试..."
return 0
}
case $ACTION in
add)
echo "添加 TXT 记录:_acme-challenge.${DOMAIN}"
aliyun alidns AddDomainRecord \
--DomainName ${DOMAIN#*.} \
--RR "_acme-challenge" \
--Type TXT \
--Value "$VALUE" \
--TTL 60
# 等待 DNS 生效
wait_dns_propagation "$VALUE"
;;
del)
echo "删除 TXT 记录:_acme-challenge.${DOMAIN}"
# 获取记录 ID
RECORD_ID=$(aliyun alidns DescribeDomainRecords \
--DomainName ${DOMAIN#*.} \
--RRKey "_acme-challenge" \
--Type TXT \
| jq -r ".DomainRecords.Record[] | select(.Value==\"$VALUE\") | .RecordId")
if [ -n "$RECORD_ID" ]; then
aliyun alidns DeleteDomainRecord --RecordId $RECORD_ID
echo "记录已删除"
fi
;;
esac
赋予执行权限:
chmod +x /usr/local/bin/aliyun-dns-hook.sh
申请证书
certbot certonly --manual \
--preferred-challenges dns \
--manual-auth-hook "/usr/local/bin/aliyun-dns-hook.sh add" \
--manual-cleanup-hook "/usr/local/bin/aliyun-dns-hook.sh del" \
-d "*.example.com" -d example.com \
--email your@email.com \
--agree-tos \
--manual-public-ip-logging-ok
配置自动续期
编辑 crontab:
crontab -e
添加:
0 3 * * * certbot renew --quiet --manual-auth-hook "/usr/local/bin/aliyun-dns-hook.sh add" --manual-cleanup-hook "/usr/local/bin/aliyun-dns-hook.sh del"
验证与监控
检查证书状态
certbot certificates
测试续期
certbot renew --dry-run
注意事项
- DNS 传播时间:脚本中已包含等待逻辑,确保 DNS 记录生效后再继续验证
- API 限流:阿里云 DNS API 有调用限制,频繁申请可能触发限流
- 凭证安全:妥善保管 AccessKey,建议创建只读 + DNS 管理的 RAM 用户
- 日志记录:建议将 hook 脚本的输出重定向到日志文件便于排查问题
结语
通过自定义 hook 脚本,我们实现了 Let's Encrypt 通配符证书的完全自动化。证书每 90 天到期,cron 会自动续期,真正做到"无限续期"。
有问题欢迎留言讨论。
文章评论