Let's Encrypt 免费 HTTPS 证书全攻略
一、Let’s Encrypt 是什么
Let’s Encrypt 是一个免费、自动化、开放的证书颁发机构(CA),由 ISRG(Internet Security Research Group)运营。它的使命是让每个网站都能用上 HTTPS。
| 特点 | 说明 |
|---|---|
| 免费 | 完全免费,无任何收费项 |
| 自动化 | 通过 ACME 协议自动申请、验证、部署、续期 |
| 安全 | 和付费证书同等级别,浏览器信任链完整 |
| 短期 | 证书有效期 90 天,强迫自动化续期 |
和传统付费证书的区别:
| Let’s Encrypt | 传统付费证书 | |
|---|---|---|
| 价格 | 免费 | $10-$1000+/年 |
| 有效期 | 90 天 | 1 年 |
| 通配符 | 支持(DNS 验证) | 部分支持 |
| OV/EV | 不支持(仅 DV) | 支持 |
| 申请方式 | 命令行自动化 | 网页提交 + 人工审核 |
| 续期 | 自动 | 手动/付费自动 |
说明:DV(域名验证)只验证域名所有权,OV/EV 还需要验证组织身份。个人博客、中小型网站用 DV 完全足够。
二、核心原理:ACME 协议
ACME(Automatic Certificate Management Environment)是 Let’s Encrypt 使用的自动化证书管理协议。
工作流程
1 | 你的服务器 Let's Encrypt CA |
两种验证方式
| 验证方式 | 原理 | 适用场景 |
|---|---|---|
| HTTP-01 | CA 访问 http://你的域名/.well-known/acme-challenge/token,验证文件存在 |
公网可访问的服务器 |
| DNS-01 | 你在 DNS 添加一条 TXT 记录,CA 查询 DNS 验证 | 通配符证书、内网服务器、CDN 后面 |
两种方式的对比:
| HTTP-01 | DNS-01 | |
|---|---|---|
| 网络要求 | 80 端口公网可达 | 只要能改 DNS 记录 |
| 通配符证书 | 不支持 | 支持 |
| 自动化难度 | 简单 | 依赖 DNS 服务商 API |
| 适用 | 一般 Web 服务器 | 所有场景 |
三、客户端工具选择
ACME 客户端不止 Certbot 一个,主流选择:
| 客户端 | 特点 | 推荐场景 |
|---|---|---|
| Certbot | Let’s Encrypt 官方推荐,功能全面 | 新手、标准 Nginx/Apache 场景 |
| acme.sh | 纯 Shell,零依赖,DNS API 丰富 | 高级用户、需要 DNS 验证、国内云服务商 |
| lego | Go 编写,单二进制文件 | CI/CD、Docker 环境 |
| Caddy | Web 服务器自带自动 HTTPS | Caddy 用户、最简单的方案 |
以下分别介绍 Certbot 和 acme.sh 两种主流方案。
四、Certbot 实战
安装
Ubuntu/Debian:
1 | sudo apt update |
CentOS/RHEL:
1 | sudo dnf install certbot python3-certbot-nginx -y |
检查版本:
1 | certbot --version |
参数速查
Certbot 的命令结构是 certbot [子命令] [参数]。
子命令:
| 子命令 | 说明 |
|---|---|
run |
默认子命令,获取证书并安装(可省略不写) |
certonly |
仅获取证书,不修改 Web 服务器配置 |
renew |
续期所有或指定证书 |
certificates |
列出已获取的证书 |
revoke |
吊销证书 |
delete |
删除证书 |
常用参数:
| 参数 | 说明 | 示例 |
|---|---|---|
--nginx |
用 Nginx 插件自动获取并配置证书 | certbot --nginx |
--apache |
用 Apache 插件自动获取并配置证书 | certbot --apache |
--webroot |
在网站根目录放置验证文件来验证 | certbot certonly --webroot -w /var/www/html |
--standalone |
自启一个临时 Web 服务器来验证(需要 80 端口空闲) | certbot certonly --standalone |
--manual |
手动验证模式(交互式,用于非标场景) | certbot certonly --manual |
--dns-cloudflare |
通过 Cloudflare DNS API 自动验证 | certbot certonly --dns-cloudflare |
-d |
指定域名(可重复使用以包含多个域名) | -d example.com -d www.example.com |
-w |
配合 --webroot,指定网站根目录 |
-w /var/www/html |
--staging |
使用测试环境(不触发速率限制) | certbot --staging ... |
--dry-run |
试运行,不真正申请证书 | certbot renew --dry-run |
--force-renewal |
强制续期,忽略到期时间检查 | certbot renew --force-renewal |
--preferred-challenges |
指定验证方式(http / dns) | --preferred-challenges http |
--email |
设置通知邮箱(到期提醒、紧急通知) | --email admin@example.com |
--agree-tos |
同意服务条款(非交互模式用) | --agree-tos |
--non-interactive |
非交互模式,不提问 | --non-interactive |
--nginx-server-root |
Nginx 配置目录(非标准路径时用) | --nginx-server-root /opt/nginx/conf |
--deploy-hook |
续期成功后执行的命令 | --deploy-hook "nginx -s reload" |
验证方式对比:
| 方式 | 参数 | 适用场景 | 要求 |
|---|---|---|---|
| Nginx 插件 | --nginx |
标准 Nginx 场景 | 80 端口公网可达 |
| Webroot | --webroot -w /path |
已有 Web 服务器 | 站点根目录可写 |
| Standalone | --standalone |
临时操作,无 Web 服务器 | 80 端口空闲 |
| DNS 插件 | --dns-cloudflare 等 |
通配符证书、内网 | DNS API 凭证 |
| Manual | --manual |
非标场景 | 手动操作 |
方式一:自动配置(Nginx)
Certbot 会直接读取 Nginx 配置,找到匹配的域名,自动修改配置、添加 SSL:
1 | sudo certbot --nginx -d your-domain.com -d www.your-domain.com |
按提示输入邮箱并同意条款,Certbot 会自动完成所有配置,然后重载 Nginx。
方式二:仅获取证书(手动配置)
如果你不想让 Certbot 改 Nginx 配置,用 certonly 模式:
1 | sudo certbot certonly --manual \ |
运行后 Certbot 会提示你在 DNS 后台添加一条 TXT 记录:
1 | _acme-challenge.your-domain.com → TXT → "随机生成的验证字符串" |
添加完按回车,验证通过后证书就到手了。
注意:
--manual模式不支持自动续期,因为每次续期都需要手动添加 DNS 记录。生产环境建议用--dns-cloudflare等 DNS API 插件实现自动化。
获取后证书文件在 /etc/letsencrypt/live/your-domain.com/:
1 | /etc/letsencrypt/live/your-domain.com/ |
然后手动写 Nginx 配置引用证书即可。
配置 Nginx 使用证书
1 | server { |
配置 SSL 安全增强
1 | # HSTS — 告诉浏览器永远用 HTTPS 访问 |
完成后重载 Nginx:
1 | sudo nginx -t && sudo nginx -s reload |
五、acme.sh 实战
acme.sh 是纯 Shell 实现的 ACME 客户端,零依赖,对国内云服务商的 DNS API 支持非常好。
安装
1 | curl https://get.acme.sh | sh |
安装后自动添加别名 acme.sh,配置文件和证书都在 ~/.acme.sh/。
方式一:HTTP 验证(Webroot 模式)
1 | acme.sh --issue -d your-domain.com -d www.your-domain.com \ |
方式二:DNS 验证(手动)
1 | acme.sh --issue --dns -d your-domain.com \ |
终端会输出需要添加的 TXT 记录,去 DNS 管理后台添加一条 TXT 记录:
- 主机记录:
_acme-challenge - 记录类型:TXT
- 记录值:终端输出的那串字符
添加完成后等待 DNS 生效(通常 1-10 分钟),然后执行 renew:
1 | acme.sh --renew -d your-domain.com \ |
方式三:DNS 验证(自动 — 以阿里云为例)
先设置 API 密钥:
1 | export Ali_Key="你的AccessKey ID" |
然后自动申请:
1 | acme.sh --issue --dns dns_ali -d your-domain.com -d *.your-domain.com |
国内主流服务商的 DNS API 都支持:
| 服务商 | API 前缀 | 示例 |
|---|---|---|
| 阿里云 | dns_ali |
--dns dns_ali |
| 腾讯云 | dns_dp |
--dns dns_dp |
| 华为云 | dns_huaweicloud |
--dns dns_huaweicloud |
| Cloudflare | dns_cf |
--dns dns_cf |
| DNSPod | dns_dp |
--dns dns_dp |
安装证书到 Nginx
1 | acme.sh --install-cert -d your-domain.com \ |
--reloadcmd 是证书续期后自动执行的命令,确保 Nginx 每次都加载新证书。
生成 dhparam
1 | openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048 |
然后在 Nginx 中引用:
1 | ssl_dhparam /etc/nginx/ssl/dhparam.pem; |
六、通配符证书
通配符证书可以保护一个域名及其所有子域名:
| 证书 | 覆盖范围 |
|---|---|
your-domain.com |
仅限该域名 |
*.your-domain.com |
blog.your-domain.com, api.your-domain.com 等所有一级子域名 |
通配符证书只能用 DNS-01 方式验证,因为你需要证明你拥有整条域名记录的控制权。
使用 acme.sh 申请通配符证书
1 | # DNS API 自动模式(阿里云) |
拿到证书后,Nginx 的配置和普通证书完全一样。
七、自动续期
Let’s Encrypt 证书有效期只有 90 天,必须配置自动续期。
Certbot 续期
Certbot 安装时通常会注册 systemd timer:
1 | # 查看定时器状态 |
续期逻辑:距离到期 30 天内才会真正续期,所以每天检查两次不会产生多余的请求。
acme.sh 续期
acme.sh 安装时会自动创建 crontab:
1 | # 查看 crontab |
在 Docker 中使用
如果 Nginx 运行在 Docker 容器中,续期后需要让容器重新加载:
1 | # acme.sh 的 reloadcmd |
或者绑定挂载证书目录,续期后重启容器:
1 | # docker-compose.yml |
八、速率限制
Let’s Encrypt 有严格的速率限制,申请失败时首先要检查是否触发了限制:
| 限制项 | 限制值 | 说明 |
|---|---|---|
| 每个注册账户每周 | 50 个新证书 | 单域名最多 50 个新证书/周 |
| 每个域名每小时 | 5 次失败验证 | 验证失败 5 次后锁定 1 小时 |
| 每个证书最多域名数 | 100 个 | 一个 SAN 证书最多包含 100 个域名 |
| 重复证书 | 每周 5 个 | 相同域名集合的证书,每周最多签发 5 个 |
避免触发限制的建议:
- 开发测试用
--staging环境,无速率限制 - 不要频繁重复申请同一域名
- 一次申请多域名用 SAN 证书,而非逐个域名申请
使用 Staging 环境测试
1 | # Certbot |
Staging 环境签发的证书浏览器不信任,仅用于测试流程。
九、常见问题排查
1. 验证失败:Connection refused / timeout
1 | Detail: Fetching http://your-domain.com/.well-known/acme-challenge/xxx: |
原因排查:
1 | # 1. 确认 80 端口被监听 |
2. 验证失败:DNS 记录未生效
1 | # 检查 TXT 记录是否发布 |
TXT 记录添加后,等 1-10 分钟生效(取决于 TTL),然后再重试。
3. 证书到期没有自动续期
1 | # Certbot:检查定时器是否启用 |
4. 证书不包含某个子域名
Let’s Encrypt 的通配符 *.your-domain.com 只覆盖一级子域名,不含 your-domain.com 自身。申请时需要同时指定:
1 | acme.sh --issue --dns dns_ali -d your-domain.com -d *.your-domain.com |
同样,*.blog.your-domain.com 也不会覆盖 blog.your-domain.com 本身。
5. 重载后还用旧证书
Nginx 启动时加载证书到内存,reload 不会完全重启。试一下 restart:
1 | sudo systemctl restart nginx |
或者用浏览器隐私窗口、curl 检查确认:
1 | curl -vI https://your-domain.com 2>&1 | grep -A5 "Server certificate" |
6. 权限问题
Let’s Encrypt 的证书目录 /etc/letsencrypt/live/ 是符号链接,且只有 root 可读:
1 | # 将 nginx 用户加入可读组 |
十、多域名和 SAN 证书
一张 SAN(Subject Alternative Name)证书可以包含多个域名,减少证书数量和管理成本:
1 | # Certbot |
注意:所有域名放进一张证书后,任何一个域名验证失败,整张证书都拿不到。
十一、总结
核心流程三件事:
- 申请:选 Certbot 或 acme.sh,根据场景选 HTTP 或 DNS 验证
- 部署:Nginx 引用证书文件,配置 SSL 参数和 HTTP 跳转
- 续期:确保自动续期正常运行,定期检查
推荐的默认方案:
1 | 公网服务器 + 标准 Nginx → Certbot + HTTP-01,一条命令搞定 |
Let’s Encrypt 的出现让 HTTPS 不再是奢侈品。配合自动续期,一次配置,长期受益。