结论: 给服务器配置 SSL 证书最快的方式是用 Let's Encrypt 免费证书:安装 certbot 与 python3-certbot-nginx 插件,执行 certbot --nginx -d 你的域名 自动签发并改写 Nginx 配置,放行 443 端口即可。证书有效期 90 天,必须配置自动续期(系统默认自带 timer),并用 certbot renew --dry-run 定期验证续期链路可用。
SSL 证书(TLS Certificate)的作用是在浏览器与服务器之间建立加密通道,让地址栏出现锁标志、URL 前缀变成 HTTPS。截至 2026 年,主流浏览器已对未加密的 HTTP 站点强制标记"不安全",搜索引擎也会降低其收录权重,因此 HTTPS 不再是加分项而是底线。本文只讲 Let's Encrypt 免费证书的自动化签发与续期这条路径,商业证书(OV / EV)、多平台(Apache、Tomcat、IIS)安装方式属于另一篇的范畴。
Let's Encrypt 证书是什么,为什么默认选它
结论:Let's Encrypt 是由 ISRG 运营的免费、自动化、开放的证书颁发机构(CA),单张证书有效期 90 天,通过 ACME 协议自动完成域名归属验证。 它对个人站点、中小企业官网、API 服务完全够用。
| 对比项 | Let's Encrypt(DV) | 商业 DV 证书 | 商业 OV / EV 证书 |
|---|---|---|---|
| 价格 | 免费 | 每年几百元 | 每年千元至万元级 |
| 签发速度 | 1~5 分钟 | 10~30 分钟 | 1~7 个工作日 |
| 有效期 | 90 天 | 通常 398 天 | 通常 398 天 |
| 验证方式 | 自动(HTTP-01 / DNS-01) | 自动或邮箱验证 | 需核验企业营业执照 |
| 浏览器显示 | 锁标志 | 锁标志 | EV 曾显示公司名(现已普遍取消) |
| 保险赔付 | 无 | 有,额度不等 | 有,额度较高 |
| 适用场景 | 博客、官网、API、内部系统 | 小型商业站点 | 金融、电商、政务 |
免费证书的三个硬限制,事先要知道
- 有效期只有 90 天:这是刻意设计,倒逼使用者实现自动化续期,手工续期必然出错。
- 只做域名验证(DV):证书里不含企业信息,无法用来证明主体身份,金融类业务不合规。
- 有签发速率限制:截至 2026 年,同一注册域名每周最多签发 50 张证书,同一组域名重复签发每周上限 5 张。调试时务必加
--dry-run,否则会被限流数小时。
申请前的四项前置检查
结论:签发失败九成是因为前置条件没满足。 花两分钟确认下面四项,能省掉后面绝大部分排查时间。
# 1. 域名已解析到本机,且解析结果与本机公网 IP 一致
dig +short example.com
curl -s ifconfig.me
# 2. Nginx 已配置该域名的 server_name(certbot 靠它定位配置块)
sudo nginx -T | grep -n "server_name"
# 3. 80 端口处于监听状态(HTTP-01 挑战必须通过 80 端口验证)
sudo ss -lntp | grep ':80'
# 4. 443 端口当前是否被占用(一般为空,签发后由 Nginx 监听)
sudo ss -lntp | grep ':443'- 第 1 项不成立,ACME 服务器访问不到你的机器,验证必然失败。
- 第 2 项不成立,certbot 找不到要改写的配置块,会提示无法识别域名。
- 第 3 项中 80 端口若被其他进程占用(如另一个 Web 服务),需要临时停掉或改用 DNS-01 验证方式。
- 服务器位于国内时,域名必须已完成 ICP 备案,否则 80 端口入站被拦截,验证同样失败。
第一步:安装 certbot 与 Nginx 插件
结论:Ubuntu 24.04 直接用 apt 安装 certbot 与 python3-certbot-nginx 即可,其中 Nginx 插件负责自动读取和改写站点配置,不要只装 certbot 本体。
# ===== Ubuntu 24.04 / Debian 12 =====
sudo apt update
sudo apt install -y certbot python3-certbot-nginx
# ===== CentOS Stream 9 / Rocky Linux 9 =====
sudo dnf install -y epel-release
sudo dnf install -y certbot python3-certbot-nginx
# 验证安装版本
certbot --version插件名中的 nginx 就是"authenticator + installer"的组合:--nginx 表示既用 Nginx 完成验证,也由它自动写入证书路径。若服务器上已有其他服务占用 80 端口且不能停,可改用 certbot certonly --webroot -w /var/www/html,只签证书不改配置,再手工引用。
第二步:一键签发证书
结论:一条 certbot --nginx -d 命令即可完成域名验证、证书签发与 Nginx 配置改写三件事。 多个域名用多个 -d 参数,第一个为主域名(Common Name)。
# 同时签发根域名与 www(推荐,一张证书覆盖两个名字)
sudo certbot --nginx -d example.com -d www.example.com
# 只签证书不改动 Nginx 配置(webroot 模式)
sudo certbot certonly --webroot -w /var/www/example.com -d example.com
# 首次运行会交互式询问:
# 1) 邮箱地址(用于到期提醒与安全通告)
# 2) 是否同意服务条款(输入 A 回车)
# 3) 是否共享邮箱给 EFF(选 N 不影响使用)
# 4) 是否把 HTTP 重定向到 HTTPS(选 2 = Redirect,强烈建议)
# 查看已签发的证书列表与到期时间
sudo certbot certificates成功时输出会包含 Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/example.com/fullchain.pem。证书文件保存在 /etc/letsencrypt/live/域名/ 目录下,四个文件各有用途:
cert.pem:服务器证书本身,一般不用直接引用。chain.pem:中间证书(Intermediate CA),用于构建信任链。fullchain.pem:cert.pem + chain.pem的合并,Nginx 应引用这个。privkey.pem:私钥,绝对不能外传,权限应为 600。
第三步:确认 Nginx 配置块已被正确改写
结论:certbot 会在原 server 块中插入 ssl_certificate(指向 fullchain.pem)与 ssl_certificate_key(指向 privkey.pem),并新增一个 443 监听块。 理解这几个指令,才能手工排查证书链问题。
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html index.php;
# 证书链:fullchain.pem 已包含中间证书,浏览器才能追溯到根 CA
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# 会话复用与协议限制
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
access_log /var/log/nginx/example.access.log;
}
# certbot 自动生成的 HTTP 跳转块
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}证书链(Certificate Chain)是指"服务器证书 → 中间证书 → 根证书"的信任传递关系。如果只配 cert.pem 而不配中间证书,多数桌面浏览器能靠缓存补全,但移动端、curl、Java 客户端会直接报 unable to get local issuer certificate。因此永远引用 fullchain.pem,这是最容易被忽略却最难排查的一个细节。
第四步:放行 443 端口并验证
结论:HTTPS 使用 443 端口,必须在系统防火墙与云平台安全组两处同时放行。 只签了证书没开端口,浏览器会停在"连接超时"。
# Ubuntu / Debian
sudo ufw allow 443/tcp
sudo ufw reload
# CentOS Stream 9 / Rocky Linux 9
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
# 重载 Nginx 使证书生效
sudo nginx -t && sudo systemctl reload nginx
# 验证 HTTP 是否跳转 HTTPS
curl -I http://example.com # 期望 301 Moved Permanently
# 验证 HTTPS 返回码
curl -I https://example.com # 期望 200 OK
# 查看证书有效期与颁发者
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates第五步:配置自动续期
结论:Let's Encrypt 证书 90 天到期,必须靠定时任务续期。certbot 的 apt/dnf 安装包默认已注册 systemd timer,一般无需手工加 crontab,但一定要用 --dry-run 实测一次。
# 查看系统自带的续期定时器(Ubuntu 24.04 默认为 certbot.timer)
systemctl list-timers | grep certbot
systemctl status certbot.timer --no-pager
# 强制演练一次续期(不会真的换证书,用的是测试环境)
sudo certbot renew --dry-run
# 出现 "The dry run was successful" 即表示续期链路通畅
# 手工立即续期(仅在证书快到期时用)
sudo certbot renew
# 续期后让 Nginx 加载新证书(certbot 的 nginx 插件会自动 reload,此行用于 certonly 模式)
sudo systemctl reload nginx若系统没有 timer(例如用 snap 安装的 certbot),可自行加一条 crontab:
# 每天凌晨 3:17 检查续期,仅当剩余有效期 < 30 天时才真正签发
sudo crontab -e
17 3 * * * /usr/bin/certbot renew --quiet --deploy-hook "systemctl reload nginx"注意 certbot renew 是幂等的:证书剩余有效期超过 30 天时它什么也不做,所以每天执行不会有速率问题。
续期失败的三种常见原因
- 80 端口被占用或被拦截:HTTP-01 验证要求 ACME 服务器能访问你域名的 80 端口。Nginx 之外的程序占用 80、安全组临时关闭 80、或国内未备案导致 80 被云厂商拦截,都会报
Connection refused/Timeout during connect。 - DNS 验证失败:使用 DNS-01 方式时,插件需要调用 DNS 服务商 API 写入 TXT 记录。API Token 过期、权限不足、TXT 记录尚未传播完成(TTL 未过),都会报
Incorrect TXT record。改用 HTTP-01 或更新 Token 即可解决。 - 权限不足:
certbot renew必须以 root 身份运行(或用 sudo),否则无法写入/etc/letsencrypt与重载 Nginx。crontab 里应写绝对路径/usr/bin/certbot,并确认加在 root 的 crontab 而非普通用户下。
企业QQ咨询




