1. 为什么选择 acme.sh + 腾讯云 DNS 方案
在 HTTPS 已成为标配的今天,泛域名证书(Wildcard SSL Certificate)对于拥有多个子域名的站点来说简直是救命稻草。想象一下,你有一个 SaaS 平台,每个客户都有一个独立的子域名(如 client1.yourdomain.com, client2.yourdomain.com),如果每个子域名都要单独申请证书,管理成本会高得吓人。而泛域名证书用一张证书就能覆盖 *.yourdomain.com 下的所有子域名,这正是我最终选择这个方案的核心原因。
acme.sh 是目前最受欢迎的 Let's Encrypt 客户端之一,它有几个让我无法拒绝的优点:
- 纯 Shell 编写,零依赖,在任何 Linux 服务器上都能跑
- 支持 DNS API 验证方式,这是申请泛域名证书的唯一途径
- 自动续期功能完善,完全不用人工干预
- 社区活跃,遇到问题容易找到解决方案
腾讯云 DNS 的 API 集成是另一个关键选择点。相比其他 DNS 服务商:
- 腾讯云的 API 文档清晰,权限控制精细
- API 调用免费且稳定(阿里云 API 调用次数多了要收费)
- 国内服务器访问速度快,验证过程更可靠
重要提示:Let's Encrypt 的泛域名证书只支持通过 DNS-01 验证方式申请,这意味着你必须拥有域名的 DNS 管理权限。如果你用的是共享主机或无法控制 DNS 的情况,这个方案就不适用了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与依赖安装
2.1 服务器基础环境
我的测试环境是 CentOS 7.9,这也是目前企业服务器中最常见的版本之一。虽然 CentOS 7 已经 EOL,但大量生产环境仍在运行,所以特别说明兼容性:
bash复制# 查看系统版本
cat /etc/redhat-release
# CentOS Linux release 7.9.2009 (Core)
必备的基础组件:
- curl:用于下载安装脚本
- cron:定时任务服务(acme.sh 依赖它自动续期)
- socat:acme.sh 的依赖项
安装命令:
bash复制yum install -y curl cronie socat
systemctl enable crond
systemctl start crond
2.2 安装 acme.sh
官方推荐的一键安装方式:
bash复制curl https://get.acme.sh | sh -s email=my@example.com
这里有几个关键细节需要注意:
- 邮箱地址应该替换为你自己的,用于证书到期提醒
- 安装脚本会自动创建 cron 任务:
0 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null - 所有文件会安装在
~/.acme.sh目录下 - 脚本会自动添加环境变量,可能需要重新登录或执行
source ~/.bashrc
验证安装:
bash复制acme.sh --version
# v3.0.8
2.3 配置腾讯云 DNS API
这是整个流程中最容易出错的部分。你需要先在腾讯云控制台获取 API 密钥:
- 登录腾讯云控制台,访问 https://console.cloud.tencent.com/cam/capi
- 新建或使用现有密钥,记录下 SecretId 和 SecretKey
- 为安全起见,建议创建一个子账号并仅授予 DNS 相关权限
在服务器上设置环境变量:
bash复制export TX_DNS_Id="你的SecretId"
export TX_DNS_Key="你的SecretKey"
这些变量会被 acme.sh 自动读取。为了永久生效,可以添加到 ~/.bashrc 或 ~/.acme.sh/account.conf 中。
3. 申请泛域名证书全流程
3.1 首次证书申请命令
核心命令结构如下:
bash复制acme.sh --issue --dns dns_tencent -d example.com -d *.example.com
参数解析:
--dns dns_tencent:指定使用腾讯云 DNS 验证-d example.com:主域名(必须包含)-d *.example.com:泛域名(这才是我们的主要目标)
实际执行示例:
bash复制acme.sh --issue --dns dns_tencent \
-d mysite.com \
-d *.mysite.com \
--yes-I-know-dns-manual-mode-enough-go-ahead-please
注意最后的
--yes-I-know...参数是必须的,这是 acme.sh 的安全确认,表示你了解这是通过 DNS 验证方式。
3.2 DNS 记录验证过程
执行命令后,acme.sh 会输出类似这样的提示:
code复制Add the following TXT record:
Domain: '_acme-challenge.mysite.com'
TXT value: 'xxxxxxx-your-verification-code-xxxxxxx'
Please add those TXT records to the DNS zone.
这时你需要:
- 登录腾讯云 DNS 控制台
- 找到你的域名解析记录
- 添加一条 TXT 记录:
- 主机记录:_acme-challenge
- 记录类型:TXT
- 记录值:上面显示的 TXT value
- TTL:默认 600 即可
添加后,执行验证:
bash复制acme.sh --renew -d mysite.com -d *.mysite.com
acme.sh 会自动检测 DNS 记录是否生效。由于 DNS 缓存的存在,这个过程可能需要等待 2-5 分钟。
3.3 证书文件说明
申请成功后,证书文件会存放在:
code复制~/.acme.sh/mysite.com/
主要文件:
mysite.com.cer:证书文件mysite.com.key:私钥文件ca.cer:中间证书fullchain.cer:完整证书链(包含你的证书和中间证书)
安全提示:
.acme.sh目录下的文件权限是 600,这是正确的安全设置,不要随意修改。
4. Nginx 证书部署实战
4.1 证书文件准备
虽然可以直接使用 .acme.sh 目录下的文件,但最佳实践是将证书复制到标准位置:
bash复制mkdir -p /etc/nginx/ssl/mysite.com
acme.sh --install-cert -d mysite.com \
--key-file /etc/nginx/ssl/mysite.com/key.pem \
--fullchain-file /etc/nginx/ssl/mysite.com/cert.pem \
--reloadcmd "systemctl reload nginx"
这个命令做了三件事:
- 将私钥复制到
/etc/nginx/ssl/mysite.com/key.pem - 将完整证书链复制到
/etc/nginx/ssl/mysite.com/cert.pem - 设置自动续期后的重载命令
4.2 Nginx 配置示例
一个完整的 HTTPS 配置示例:
nginx复制server {
listen 443 ssl http2;
server_name mysite.com www.mysite.com;
ssl_certificate /etc/nginx/ssl/mysite.com/cert.pem;
ssl_certificate_key /etc/nginx/ssl/mysite.com/key.pem;
# 优化 SSL 配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384...';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 其他配置...
location / {
root /var/www/html;
index index.html;
}
}
# HTTP 跳转 HTTPS
server {
listen 80;
server_name mysite.com www.mysite.com;
return 301 https://$host$request_uri;
}
4.3 子域名配置技巧
泛域名证书的真正威力在于支持无限子域名。配置示例:
nginx复制server {
listen 443 ssl http2;
server_name *.mysite.com;
# 使用相同的证书
ssl_certificate /etc/nginx/ssl/mysite.com/cert.pem;
ssl_certificate_key /etc/nginx/ssl/mysite.com/key.pem;
# 根据子域名动态设置根目录
set $subdomain "";
if ($host ~* ^([^.]+)\.mysite\.com$) {
set $subdomain $1;
}
location / {
root /var/www/$subdomain;
try_files $uri /index.html;
}
}
这个配置可以实现:
- 访问 client1.mysite.com -> /var/www/client1
- 访问 client2.mysite.com -> /var/www/client2
- 所有子域名共用同一张证书
5. 自动续期与故障排查
5.1 自动续期机制
acme.sh 安装时已经创建了每日执行的 cron 任务。你可以手动测试续期:
bash复制acme.sh --cron
成功续期后,acme.sh 会自动:
- 获取新证书
- 将新证书复制到
/etc/nginx/ssl/mysite.com/ - 执行
systemctl reload nginx
查看续期日志:
bash复制cat ~/.acme.sh/acme.sh.log
5.2 常见问题解决
问题1:DNS 验证超时
code复制Verify error:Invalid response from https://dns.google/resolve
解决方案:
- 检查 DNS 记录是否真的生效:
dig TXT _acme-challenge.mysite.com @8.8.8.8 - 腾讯云 API 可能有延迟,等待 5 分钟再试
- 确保服务器能正常解析 DNS(检查
/etc/resolv.conf)
问题2:证书不被信任
浏览器提示"证书不受信任",通常是因为证书链不完整。确保 Nginx 配置中使用的是 fullchain.cer 而非单独的证书文件。
问题3:续期失败
code复制Cert not yet due for renewal
这是正常提示,表示证书还没到续期时间(Let's Encrypt 证书有效期 90 天,acme.sh 会在到期前 30 天自动续期)。
5.3 监控与告警
虽然 acme.sh 的自动续期很可靠,但建议添加监控:
- 证书过期监控:
bash复制openssl x509 -enddate -noout -in /etc/nginx/ssl/mysite.com/cert.pem - 设置 cron 任务每周检查一次证书有效期:
bash复制0 0 * * 0 openssl x509 -checkend 2592000 -noout -in /etc/nginx/ssl/mysite.com/cert.pem || echo "Certificate will expire in 30 days" - 结合监控系统(如 Prometheus)对证书有效期进行告警
6. 高级配置与优化
6.1 多域名证书管理
如果你有多个主域名需要管理,比如:
- mysite.com
- myapp.com
- myapi.net
可以为每个域名单独申请证书:
bash复制acme.sh --issue --dns dns_tencent -d myapp.com -d *.myapp.com
acme.sh --issue --dns dns_tencent -d myapi.net -d *.myapi.net
然后分别配置安装路径:
bash复制acme.sh --install-cert -d myapp.com \
--key-file /etc/nginx/ssl/myapp.com/key.pem \
--fullchain-file /etc/nginx/ssl/myapp.com/cert.pem \
--reloadcmd "systemctl reload nginx"
6.2 ECC 证书支持
相比 RSA 证书,ECC(椭圆曲线)证书更安全且更高效。acme.sh 支持生成 ECC 证书:
bash复制acme.sh --issue --dns dns_tencent -d mysite.com -d *.mysite.com --keylength ec-256
Nginx 配置需要相应调整:
nginx复制ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305...';
6.3 OCSP Stapling 配置
OCSP Stapling 可以加速 SSL 握手并提高隐私性。在 Nginx 中添加:
nginx复制ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/mysite.com/fullchain.pem;
resolver 8.8.8.8 1.1.1.1 valid=300s;
resolver_timeout 5s;
验证配置:
bash复制openssl s_client -connect mysite.com:443 -status -servername mysite.com < /dev/null 2>&1 | grep -i "OCSP response"
6.4 Docker 环境下的部署
如果你使用 Docker 运行 Nginx,证书管理需要特别注意:
- 将证书目录挂载到容器中:
bash复制
docker run -d \ -v /etc/nginx/ssl:/etc/nginx/ssl \ -v /etc/nginx/conf.d:/etc/nginx/conf.d \ nginx:latest - 修改 acme.sh 的 reloadcmd:
bash复制acme.sh --install-cert -d mysite.com \ --reloadcmd "docker exec nginx_container nginx -s reload" - 确保容器内可以访问腾讯云 API(如果需要在容器内运行 acme.sh)
7. 安全加固与最佳实践
7.1 密钥文件权限
正确的文件权限设置:
bash复制chmod 600 /etc/nginx/ssl/mysite.com/key.pem
chmod 644 /etc/nginx/ssl/mysite.com/cert.pem
chown root:root /etc/nginx/ssl/mysite.com/*
7.2 API 密钥保护
腾讯云 API 密钥应该:
- 仅授予 DNS 解析权限
- 设置 IP 白名单(如果你的服务器 IP 固定)
- 定期轮换(建议每 3-6 个月)
7.3 证书透明度日志
Let's Encrypt 会自动提交证书到 CT 日志。你也可以手动检查:
bash复制openssl x509 -in /etc/nginx/ssl/mysite.com/cert.pem -noout -text | grep -i ct
7.4 HSTS 增强安全
在 Nginx 配置中添加:
nginx复制add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
这告诉浏览器在未来两年内都只能通过 HTTPS 访问你的网站(包括所有子域名)。
8. 性能优化技巧
8.1 会话复用配置
减少 SSL 握手开销:
nginx复制ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
8.2 TLS 1.3 优先
现代浏览器都支持 TLS 1.3,它比 TLS 1.2 更快更安全:
nginx复制ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off; # TLS 1.3 不需要这个
8.3 证书链优化
确保证书链顺序正确:
bash复制openssl s_client -connect mysite.com:443 -showcerts </dev/null 2>/dev/null
正确的顺序应该是:你的证书 → 中间证书 → 根证书(根证书通常不需要包含)
8.4 0-RTT 配置(谨慎使用)
TLS 1.3 的 0-RTT 可以加速重复访问,但有安全风险:
nginx复制ssl_early_data on;
只对非敏感操作启用,或者配合 $ssl_early_data 变量做额外验证。
