免费HTTPS证书实战:ACME自动续期与Nginx部署指南

发布时间:2026/9/28 8:49:02
免费HTTPS证书实战:ACME自动续期与Nginx部署指南 上周帮一个朋友续服务器远程上去顺手看了一眼 Nginx 配置发现证书还有两个月到期签发方是一家商业 CA。我多嘴问了一句“这证书多少钱一年”他说几百块。我说你交的不是加密钱是“信任税”——因为明明有免费渠道能拿到同样被浏览器信任的 HTTPS 证书而且还能自动续期长期不用手动管。这不是抬杠。HTTPS 证书这件事在过去十年里变化非常大。现在你完全可以用免费证书跑生产环境个人博客、企业官网、API 服务、小程序后端都能稳得住。这篇文章不劝你把银行卡里的钱都省下来而是想认真聊聊为什么付费证书正在变得不划算免费证书到底能不能扛住生产环境以及如果你决定迁移应该怎么操作、踩过哪些坑。1. 为什么说现在继续为普通域名买付费证书不值当1.1 证书到底是什么浏览器凭什么信任它先把基础说清楚。HTTPS 的本质是“HTTP 跑在 TLS 加密隧道上”而 HTTPS 证书更准确地说叫 TLS/SSL 证书负责两件事一是通过非对称加密算法完成密钥协商所需的公钥交换二是向浏览器证明“你正在访问的这个域名确实由持有对应私钥的一方控制”。证书本身是一个遵循 X.509 标准的数字文件里面包含域名、公钥、有效期、签名算法、签发者信息等。浏览器收到证书后会沿着签发者信息向上找直到找到一个它内置于“信任根证书列表”的根证书。这个链条能走通浏览器就认为证书可信地址栏出现锁形图标走不通就会给你一屏红色警告。很多人误以为免费的 Lets Encrypt 证书“等级低”其实它的签发机构和付费证书一样在浏览器中拥有合法信任链。Lets Encrypt 由 ISRG 运营是 Linux 基金会支持的非营利项目数以亿计的网站都在用。免费和付费证书走的是同一套 TLS 协议、同一个信任体系区别根本不在“能不能加密”而在“签发前的验证深度”和“之后由谁给你做客服”。打个比方免费证书和付费证书就像两家银行都给你发银行卡都能正常刷卡消费。付费那张可能多送一个专属客服但如果你只是楼下买个菜多花的钱并不会让刷卡更流畅。1.2 免费和付费证书的真实差距在哪先看证书类型。绝大多数 HTTPS 证书分为 DV、OV、EV 三种类型验证内容浏览器显示典型价格适合场景DV域名验证验证域名所有权锁形图标免费或几十到几百元/年绝大多数网站OV组织验证验证企业组织和域名部分浏览器会隐藏组织信息几百到几千元/年有合规诉求的企业EV扩展验证更深度的企业资质审核曾经显示绿色公司名现已基本弱化上千到上万元/年金融、高信任背书场景免费渠道基本只做 DV也就是“我证明这个域名归我管”这对个人网站、产品官网、API 服务、SaaS 后台来说完全够用。浏览器锁形图标不会因为你是 DV 就少半个角TLS 加密强度也不会因为你没花钱就降级。付费证书剩下的卖点是 OV/EV、商业保险、品牌背书和电话客服。可问题在于主流浏览器这几年的趋势是在弱化 EV 证书的视觉差异。Chrome 早已不在地址栏单独显示绿色公司名Firefox、Edge、Safari 也陆续调整了展示方式。你花大几千买到的 EV 标识在普通用户眼里跟免费 DV 一模一样。还有一个致命变化CA/Browser Forum 规定2020 年 9 月之后签发的公开受信证书最长有效期不能超过 398 天。也就是说过去“一次买三年”的长期证书彻底成为历史。现在你花高价买“三年套餐”本质上只是预付费证书照样一年左右就得换一次。这个规则直接影响付费证书的剩余价值你付的钱里很大一部分是品牌溢价和服务而不是更高级的技术能力。所以我一直有个观点对绝大多数普通网站来说继续买付费 DV 证书或低价 OV 证书已经不是技术决策而是习惯决策。真正让你犹豫的其实是“免费的东西靠不靠谱”这种心理门槛。下一部分我们就解决这个问题。2. 免费证书落地实操从申请到自动续期2.1 ACME 协议与客户端选型要让免费证书真正好用不能靠浏览器里去点“申请”而是必须走自动化。Lets Encrypt 和 Google Trust Services、ZeroSSL 等免费 CA 都支持 ACME 协议全称是“自动证书管理环境”。ACME 定义了一套标准化的挑战-响应流程客户端证明自己对域名的控制权CA 验证通过后签发证书到期前客户端还能自动续期。既然有标准协议客户端就有很多选择。我实际用下来主流的有这几个客户端特点适合场景CertbotPython 生态由 EFF 维护插件丰富官方文档多手动管理、Nginx/Apache 自动修改配置的场景acme.sh纯 Shell 脚本轻量内置大量 DNS 服务商 API 插件传统服务器、脚本化部署、喜欢极简工具的人CaddyWeb 服务器本身内置 ACME 客户端配置两行即可自动签发续期用 Caddy 做反向代理/独立服务的新项目Traefik / cert-manager云原生集成自动发现服务和路由Docker、Kubernetes 环境如果你只有一台传统服务器、跑着 Nginx我最推荐 acme.sh。它没有 Python 依赖安装快DNS API 插件多得吓人阿里云、腾讯云、Cloudflare 基本都覆盖。想给容器或 K8s 用后文第 5 部分专门讲。2.2 用 acme.sh 申请一张免费证书先确认域名已经解析到服务器 IP80 和 443 端口能访问。然后安装 acme.shcurl https://get.acme.sh | sh -s emailmeexample.com这行命令会把脚本安装到当前用户的~/.acme.sh目录并自动加好 cron 任务。注意直接从管道执行远程脚本虽然官方就这么推荐但如果你对安全有洁癖可以先把脚本下载下来看一遍或者改用系统包的 Certbot。我是觉得 acme.sh 的脚本还算透明实际使用四年多没出过问题。安装完成后建议先确认默认 CA。acme.sh 不同版本的默认 CA 可能不同如果你想明确指定用 Lets Encrypt执行acme.sh --set-default-ca --server letsencrypt接着申请证书。如果 80 端口能用最简单的是 webroot 模式acme.sh --issue -d example.com -d www.example.com --webroot /var/www/html这个模式会临时在网站根目录放一个验证文件CA 通过 HTTP 请求去确认你确实拥有这个域名的控制权。优点是简单缺点是会碰站点目录而且不支持通配符。更推荐的是 DNS API 模式比如 Cloudflareexport CF_Token你的API Token export CF_Account_ID你的Account ID acme.sh --issue --dns dns_cf -d example.com -d *.example.com--dns dns_cf会让 acme.sh 调用 Cloudflare API自动添加一条 TXT 解析记录完成验证后自动删除。整个过程不需要开放 80 端口还能签发*.example.com这种通配符证书。DNS 验证是生产环境最稳的做法尤其适合那些服务器没有独立公网 IP、或者 80 端口被占用的用户。证书签下来后安装到 Nginx。以/etc/nginx/ssl/作为存放目录acme.sh --install-cert -d example.com \ --key-file /etc/nginx/ssl/example.com.key \ --fullchain-file /etc/nginx/ssl/example.com_fullchain.pem \ --reloadcmd systemctl reload nginx这里有两个重点。第一一定要用--fullchain-file它把域名证书和中间证书放在同一个文件里能避免“证书链不完整”这类坑。第二--reloadcmd会在每次续期成功后自动执行否则新证书签下来也没人加载。Nginx 的 server 块配置只需要server { listen 443 ssl http2; server_name example.com; ssl_certificate /etc/nginx/ssl/example.com_fullchain.pem; ssl_certificate_key /etc/nginx/ssl/example.com.key; root /var/www/html; }改完后nginx -t systemctl reload nginx浏览器再访问锁形图标就出来了。2.3 自动续期别让证书过期来找你免费证书的 90 天有效期不是坑反而是设计精髓。短有效期意味着即使私钥泄露影响窗口也有限更重要的是它逼着你把证书管理自动化。90 天一次手工换谁都会忘一旦忘了后果就是用户访问时出现红色警告流量断崖式下跌。acme.sh 安装时会自动写入 cron默认每天检查一次临近过期前 30 天触发续期。你可以确认一下crontab -l | grep acme如果看到类似56 0 * * * acme.sh --cron --home ...的内容说明已经装好。Certbot 用户则用 systemd timer通过systemctl list-timers | grep certbot查看。续期的关键是顺畅。acme.sh 会自动保存账号密钥和证书私钥续期成功后会调用--reloadcmd里的命令。不需要你额外写脚本。但注意两件事一是服务器时间和时区必须准确date查一下时间偏差太大 ACME 验证会失败二是日志在~/.acme.sh/acme.sh.log遇到问题先去翻日志比瞎猜有效得多。如果注册邮箱填对了续期失败时还会收到 CA 的过期提醒邮件提前两天发现问题足够了。3. 别让免费证书给你“挖坑”关键配置与排障3.1 必须处理的三件套证书链、混合内容、OCSP Stapling免费证书本身不难难的是很多人用了免费证书之后把周围的基础配置一起给忽略了。第一个坑是证书链。浏览器需要“域名证书 中间证书 根证书”完整链路。有些新手手动创建.crt文件时只贴了域名证书中间证书漏了结果桌面浏览器访问正常手机浏览器却报“证书不受信任”。解决方法是直接用isrgrootx1.pem? 不最稳的是 acme.sh 生成的fullchain.cer或你安装时指定的fullchain.pemNginx 里ssl_certificate指向它就行。第二个坑是混合内容。全站切到 HTTPS 后页面里如果还有 HTTP 资源图片、JS、CSS、XHR浏览器会默认拦截。表面看是“证书没问题页面就是不完整”。最常见的是统计脚本、第三方图片外链、子域名接口没同步换 HTTPS。建议在 Nginx 强制跳转并检查控制台server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; }当然如果有些接口必须在 HTTP 下被第三方访问比如微信开发者配置里的回调地址那就按路径放行不要一刀切。第三个坑是 OCSP Stapling。浏览器每次建立 TLS 连接时默认会去查 CA 的吊销列表多一次网络往返。开启 OCSP Stapling 后服务器会在握手阶段主动跟随证书一起把吊销状态“打包发送”给客户端提升速度和隐私性。Nginx 配置如下ssl_stapling on; ssl_stapling_verify on; resolver 1.1.1.1 8.8.8.8 valid300s; resolver_timeout 5s;注意不要在没有配置resolver的情况下直接开启ssl_stapling否则 Nginx 会报错。如果网络环境特殊无法稳定访问 OCSP 服务器宁可不开启也别让握手失败。3.2 生产环境中最常见的 5 个问题问题现象根本原因解决方法手机浏览器提示证书不受信任中间证书缺失只放了域名证书使用 fullchain.pem检查ssl_certificate指向证书文件更新了但页面还是旧证书Nginx 没有 reload 或 reload 命令未配置确认--reloadcmd存在手动systemctl reload nginx页面 HTTPS 访问出现红色警告页面里还有 HTTP 资源被浏览器拦截控制台看 Network 面板把被 blocked 的资源替换成 HTTPS通配符证书申请失败DNS API 权限不足或 TXT 记录生效太慢检查 API Token 权限给 acme.sh 增加等待时间或换用传播快的 DNS 服务商申请时提示 rate limit 超限同一域名频繁申请、失败过多查询 Lets Encrypt 配额等一周或切换到备用 CA这里解释一下 rate limit。Lets Encrypt 的限制大约是每注册域名每周 50 张证书单张证书最多 100 个 SAN。正常业务远用不完。但如果你写了个脚本因为配置错误反复重复申请很容易触发。真被限了也没关系换 ZeroSSL 或 Google Trust Services 再签一张应急等限额恢复再切回来。3.3 兼容性免费证书真的很“挑设备”吗以前听过一种销售话术“免费证书兼容性不好老手机打不开。”这话在五年前有点道理现在基本是胡扯。Lets Encrypt 的 ISRG Root X1 根证书已经被所有主流操作系统和浏览器信任。近十年的 Windows、macOS、iOS、Android、Linux 分发版默认都认识它。真正的兼容性问题往往不是证书本身而是服务器端 OpenSSL 版本太老、只支持 TLS 1.0/1.1或者私钥类型不被老客户端支持。别把锅扣在免费证书头上。如果你的用户群体真有一些十年前的老设备比如某类 POS 机、车机、嵌入式硬件可以专门生成 RSA 2048 证书而不要用 ECC。acme.sh 默认生成的可能是 ECC 密钥老系统可能不认可以加参数强制acme.sh --issue -d example.com --keylength 2048 --webroot /var/www/html我这里给的建议是现代服务直接用 ECC性能更好有明确老设备兼容需求再退回 RSA。不要盲目觉得“免费 不兼容”先做一轮真实环境测试再下结论。4. 哪些场景直接换免费证书哪些场景需继续付费4.1 可以直接换的场景最容易迁移的是个人博客、作品集、企业展示官网、SaaS 后台、API 服务、小程序后端。这些场景用户只在意“有没有锁”不会去点开证书详情看签发机构是哪个。支付类业务通常也是通过微信/支付宝官方组件完成你的服务器只需要保证接口是 HTTPS并不强制要求 OV/EV。有一个小电商朋友原来每年花八百多买 OV 证书我帮他换成 acme.sh 自动续期后支付流程完全没变唯一的变化是年底少了一笔支出。迁移的方法非常简单。先备份现有证书文件然后用第 2 部分的流程签一张新证书替换 Nginx 配置用下面的命令验证线上是否生效echo | openssl s_client -connect example.com:443 -servername example.com 2/dev/null | openssl x509 -noout -dates -issuer这个命令会打印证书有效期和签发者。看到签发者是 Lets Encrypt / ZeroSSL就说明切换成功。浏览器访问一次确认没有警告迁移基本就完成了。4.2 暂时还不能换的场景有几种情况我建议继续付费别硬省。第一是金融、银行、政务类系统。这类项目往往有明确的安全合规要求安全评审会写死“必须使用 OV/EV 证书”或者“必须使用指定根证书链”。这是流程问题不是技术问题别和客户争。第二是客户合同里白纸黑字指定了某家商业 CA比如“证书由 XX CA 签发并提供商业担保”你如果擅自换成免费 CA验收过不了。第三是特殊嵌入式设备或老系统比如需要兼容 Windows XP SP2 时代的老浏览器免费证书的信任链可能覆盖不到这时商业 CA 的旧交叉签名证书确实还有优势。第四种是大型企业采购后的运维预期。有些公司宁可每年花一笔小钱换来的是“出了事有人接电话”。你去跟财务说“免费”他们反而觉得你不够专业。这种属于组织惯性没必要强行纠正。记住一点免费不是万能该付的钱是买信任背书的不用心疼。4.3 迁移节奏与回滚方案迁移最忌“一把梭”。我给的建议是分阶段。先把新免费证书部署在一台测试机或测试环境用不同浏览器、手机、命令行工具都跑一遍。没问题后再替换生产服务器。替换时保留旧证书文件至少一个证书周期也就是半年以上。万一免费证书在自动化上出了问题你能在 10 分钟内把旧证书文件换回来并 reload。等到新证书稳定运行几个月后再清理旧文件。如果是几十个域名批量迁移建议先按 DNS 服务商分组。比如所有域名在 Cloudflare就用一个 acme.sh 的 DNS API 批量签在阿里云就换dns_ali。然后写一个脚本把证书分发到对应服务器的ssl/目录最后统一 reload。注意错峰申请不要在同一天把所有域名都申请一遍避免触发 rate limit。这里还有个小技巧迁移期间可以先继续保留商业证书的监控等免费证书连续续期成功两次之后再撤销商业证书。这样即使某一次续期失败了你还有旧证书可用作为兜底。5. 把证书管理做成“无人值守”进阶运维与应急方案5.1 用反向代理/网关自动管理证书如果你的服务已经是用 Caddy 或 Traefik 这类反向代理可以彻底省掉在系统里装 ACME 客户端的步骤。以 Caddy 2 为例配置文件里只要写example.com { reverse_proxy 127.0.0.1:8080 }Caddy 会自动完成证书申请、续期、HTTP 跳转 HTTPS 一条龙。证书数据存放在 Caddy 的 data 目录重启后自动加载。Traefik 也类似配置certresolver后路由和证书绑定由服务自动发现完成。Kubernetes 用户更不用愁。用 cert-manager 创建 ClusterIssuer然后在 Ingress 上加一行注解apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: cert-manager.io/cluster-issuer: letsencrypt-prod spec: tls: - hosts: - example.com secretName: example-tlscert-manager 会自动生成 Kubernetes Secret并在证书到期前自动续期。应用本身不用关心证书文件存在哪Ingress 控制器会读取 Secret。这套方案在生产云原生环境里非常成熟我实际用下来最大的好处是“新服务上线时不需要手动申请证书”只要把域名指向集群证书自己会长出来。5.2 监控证书过期与续期失败自动续期并不等于永不失败。DNS 服务商 API 变更、账号密钥丢失、rate limit 超限都可能导致续期中断。最怕的是你在假期里收到用户投诉“网站打不开”然后才发现证书昨天过期了。所以必须加独立监控。最简单的方案是在外部监控服务里建一条 HTTPS 探测比如 UptimeRobot 免费套餐就支持证书过期前 30 天就能报警。如果想自己控制用 Prometheus blackbox_exporter 的ssl_expiry探针再配合 Alertmanager 推到钉钉或邮件。不想上全家桶的一行 Shell 也能做基础检查expires$(echo | openssl s_client -connect example.com:443 -servername example.com 2/dev/null | openssl x509 -noout -enddate | cut -d -f2) echo $expires把这段解析成日期距离过期小于 15 天时通知自己。工具不重要重点是“监控不能绑在 ACME 客户端里”否则客户端挂了监控也一起瞎了。5.3 别被 Rate Limit 绑定多域名与通配符的全局策略前面提到 Lets Encrypt 有配额限制对于拥有大量子域名的团队最合理的做法是给每个主域名签一张*.example.com通配符证书。这样以后新增子域不需要重新申请证书直接复用同一张通配符证书即可。DNS API 模式下续期也是自动的运维成本几乎为零。如果某个大客户要求每个二级域名单独一张证书而且各自部署在不同服务器上那就别硬塞到一张通配符里。规划好申请时间不要同一天全部申请。可以周一到周三申请一批周四到周六申请另一批真触发限制也有时间缓冲。免费 CA 也不止 Lets Encrypt 一家。ZeroSSL 提供免费证书Google Trust Services 也通过 ACME 提供 90 天证书。日常主力用一家应急时切另一家相当于给证书管理上了双保险。我自己在 DNS API 插件无法使用时切过两次备用 CA体验顺畅页面没有任何区别。说回个人体会。我自己的服务器跑了四年多 Lets Encryptcron 自动续期几乎没在半夜收到过过期告警。唯一一次续期失败是因为 DNS 服务商调整了 API 权限监控提前发现手工补了一次就恢复了。这几年省下的证书费用加起来够我买一台不错的开发机。免费证书不是“低配版”只是 CA 的商业模式不同而已。关键是你的运维习惯有没有跟上自动化。如果你现在还在为普通域名付费不妨先找一台测试机器跑一次 acme.sh感受下“自动签发”的踏实感。等跑顺了再逐步把生产域名迁过来。省下的钱可以给服务器升个配置比交给证书代理商有意义得多。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询