【实践】从零到一:利用acme.sh自动化获取并部署Let‘s Encrypt泛域名证书

张开发
2026/4/20 4:05:06 15 分钟阅读

分享文章

【实践】从零到一:利用acme.sh自动化获取并部署Let‘s Encrypt泛域名证书
1. 为什么需要泛域名证书想象一下你运营着一个拥有多个子域名的网站比如 blog.example.com、shop.example.com、api.example.com。如果每个子域名都要单独申请SSL证书不仅管理起来麻烦续签时更是噩梦。泛域名证书Wildcard Certificate就是为了解决这个问题而生的——一张证书就能覆盖 *.example.com 下的所有子域名。我最早接触Lets Encrypt时每次新增子域名都要重新跑一遍验证流程直到发现acme.sh支持泛域名证书才真正解放双手。实测下来配合DNS验证和自动化部署整套流程可以做到完全无人值守。尤其对于使用Cloudflare管理域名的用户整个过程就像搭积木一样简单。2. 准备工作安装与配置2.1 安装acme.sh这个开源工具堪称证书管理界的瑞士军刀。安装只需一行命令curl https://get.acme.sh | sh -s emailyouremail.com安装完成后会创建专属目录~/.acme.sh/自动添加每日检查续期的cron任务设置命令别名不用记复杂路径注意建议使用非root用户安装避免权限问题。我曾在生产环境用root安装后来迁移服务器时遇到一堆权限坑。2.2 配置Cloudflare APIDNS验证需要API权限到Cloudflare控制台进入「My Profile」→「API Tokens」创建自定义令牌权限选择Zone.DNS: EditZone.Zone: Read作用域选择目标域名得到API令牌后配置环境变量export CF_Token你的API令牌 export CF_Account_ID账户ID export CF_Zone_ID域名区域ID建议把这些写入.bashrc或.zshrc避免每次重新设置。我在三台服务器上部署时漏配了一台的环境变量结果证书续期失败导致服务中断这个教训值得警惕。3. 申请泛域名证书实战3.1 首次签发证书关键命令长这样acme.sh --issue \ -d example.com \ -d *.example.com \ --dns dns_cf \ --server letsencrypt参数说明-d主域名和泛域名必须同时指定--dns指定DNS服务商这里是Cloudflare--server使用Lets Encrypt正式环境第一次运行时可能会遇到Add txt record error这通常是API权限不足导致的。我建议先用--debug参数测试acme.sh --issue ... --debug 23.2 验证过程解析工具背后做了这些事向CA申请验证自动在DNS添加_acme-challengeTXT记录等待DNS生效约2分钟完成验证后自动清理记录曾经有次我在凌晨操作发现验证总是超时后来才明白是Cloudflare的DNS传播延迟。现在我会在命令后加--dnssleep 120参数强制等待2分钟。4. 证书部署与自动化4.1 Nginx配置示例获取证书后需要安装到Web服务器acme.sh --install-cert \ -d example.com \ --key-file /etc/nginx/ssl/example.com.key \ --fullchain-file /etc/nginx/ssl/fullchain.cer \ --reloadcmd systemctl reload nginx对应的Nginx配置server { listen 443 ssl; server_name *.example.com; ssl_certificate /etc/nginx/ssl/fullchain.cer; ssl_certificate_key /etc/nginx/ssl/example.com.key; # 其他SSL优化参数... }重要提示不要直接使用~/.acme.sh/下的证书文件这些是内部管理用的。必须通过--install-cert安装到指定位置。4.2 自动续期机制acme.sh已自动创建cron任务每天检查证书有效期。当证书快到期时默认提前30天会自动续期并触发reloadcmd。验证cron是否生效crontab -l | grep acme如果发现续期失败常见原因有API令牌过期DNS解析故障证书存储目录权限变更我养成了每月检查/var/log/acme.sh.log的习惯这个日志文件记录了所有自动化操作的细节。5. 进阶技巧与排错指南5.1 多域名管理技巧当你有多个泛域名时可以创建批量处理脚本DOMAINS(domain1.com domain2.net) for domain in ${DOMAINS[]}; do acme.sh --issue -d $domain -d *.$domain --dns dns_cf done5.2 常见错误解决方案问题1证书链不完整现象浏览器提示NET::ERR_CERT_AUTHORITY_INVALID解决确保使用--fullchain-file而不是单独的证书文件问题2权限拒绝错误现象install-cert时提示Permission denied解决提前创建目标目录并设置正确权限sudo mkdir -p /etc/nginx/ssl sudo chown -R $(whoami): /etc/nginx/ssl问题3DNS验证超时现象一直等待DNS记录生效解决增加--dnssleep参数值或检查Cloudflare的代理状态要暂时关闭代理有次我遇到特别诡异的情况——验证始终失败最后发现是服务器时间不同步。现在我会在关键服务器上运行sudo timedatectl set-ntp true6. 安全最佳实践API令牌保护使用范围最小的必要权限定期轮换令牌我设置日历每3个月提醒禁止令牌出现在脚本中始终用环境变量证书文件权限chmod 600 /etc/nginx/ssl/*.{key,cer} chown root:root /etc/nginx/ssl/*监控方案用Prometheus监控证书过期时间设置Zabbix触发器检测acme.sh日志错误我自建的监控脚本片段openssl x509 -enddate -noout -in /etc/nginx/ssl/fullchain.cer这套方案在我管理的20域名上稳定运行了两年期间Lets Encrypt的根证书更换、ACME协议升级等重大变更都没有影响服务。唯一需要手动干预的是去年Cloudflare API端点迁移更新acme.sh到最新版就解决了。

更多文章