首页 > Technology > 正文

Nginx 配置 Let’s Encrypt SSL 证书完整教程

fenij 2026-08-04 167 Technology

HTTPS 现在已经是网站标配。Let’s Encrypt 提供免费的 DV 证书,有效期 90 天,配合 certbot 可以自动申请和续期。下面是 Nginx 上配置 Let’s Encrypt 的完整步骤。

Let’s Encrypt 证书类型对比

工具 适用场景 特点
certbot Nginx/Apache 标准部署 自动修改配置,最常用
acme.sh DNS 验证/泛域名 纯 shell,依赖少
Cloudflare CDN 接管 SSL 源站可不装证书

续期流程

1certbot renew –dry-run

2检查 crond 定时任务

3nginx -s reload 重载配置

安装 certbot

Debian/Ubuntu:

sudo apt update
sudo apt install certbot python3-certbot-nginx -y

CentOS/RHEL:

sudo dnf install certbot python3-certbot-nginx -y

申请证书

certbot 会自动读取 Nginx 配置里的 server_name,然后验证域名所有权。执行:

sudo certbot --nginx -d example.com -d www.example.com

按提示选择是否把 HTTP 流量重定向到 HTTPS。建议选 2(强制重定向)。

验证证书

申请完成后检查:

sudo certbot certificates

浏览器访问 https://example.com,应该能看到锁标志。

自动续期

certbot 安装时会创建一个 systemd timer 或 cron 任务。测试续期是否工作:

sudo certbot renew --dry-run

如果测试通过,证书会在到期前自动续期。

手动配置 Nginx

如果 certbot –nginx 自动修改配置失败,可以手动配置。certbot 会把证书放在 /etc/letsencrypt/live/example.com/

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # 现代 TLS 配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:...;
    ssl_prefer_server_ciphers off;

    location / {
        root /var/www/html;
        index index.html;
    }
}

server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

常见问题处理

验证失败:确保 80 端口能从外网访问,Nginx 配置里有正确的 server_name,域名解析已经生效。

证书路径错误:检查 /etc/letsencrypt/live/ 下的域名目录是否正确。

自动续期没跑:检查 systemctl list-timers 里的 certbot.timer,或者 /etc/cron.d/certbot

关于证书过期后的处理,参考 HTTPS 证书过期怎么办?确认与续期完整指南

HTTPS 优化

# 开启 HSTS
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

# OCSP 装订
ssl_stapling on;
ssl_stapling_verify on;

更多 Nginx 运维教程,请访问 fenij.com

常见问题

问:一个证书可以覆盖多个域名吗?
答:可以。申请时加上多个 -d 参数,certbot 会生成 SAN 证书。最多 100 个域名。

问:通配符证书怎么申请?
答:需要 DNS 验证。执行 certbot -d *.example.com --manual --preferred-challenges dns certonly,按提示添加 TXT 记录。

问:Let’s Encrypt 证书支持 IP 吗?
答:不支持。必须有域名。如果只有 IP,可以考虑 ZeroSSL 或自签证书。

延伸:续期失败的三种真实原因

证书申请下来只是第一步,续期才是高频出问题的地方。其一,80 端口被占或强制跳 HTTPS:certbot 校验时要临时监听 80 端口,若已有别的进程占用,或 Nginx 把所有 http 强制 301 到 https,校验请求会被挡。其二,DNS 没生效:用 acme.sh 做泛域名时,TXT 记录刚加还没传播完就去验证,必然失败,等几分钟再跑。其三,证书路径配反:Nginx 的 ssl_certificate 要用 fullchain.pem 而非 cert.pem,配错会报证书链不完整。

验证方式适用常见坑
HTTP-01单域名80 端口占用
DNS-01泛域名TXT 未生效
CDN 托管源站不装证书回源协议错

实操速查清单

部署完别急着关窗口,把这几步顺手做了更稳:① 申请完立刻 certbot certificates 看到期日和路径;② 把 certbot renew --dry-run 跑通,确认续期链路没问题;③ 检查系统里 certbot 的自动任务(cron 或 systemd timer)确实在;④ Nginx 配置里顺手加上 80 转 443 和 HSTS,但别在续期验证时段强制跳 HTTPS。这样证书到期前会自动无缝续上,不会出现半夜过期的情况。

常见问题

问:certbot renew 报错怎么办?
答:先跑 certbot renew --dry-run 看具体错误,多半是 80 端口或权限问题,按提示放开即可。

问:证书快过期却没自动续?
答:certbot 只在剩余不到 30 天时才会真正续期,确认系统的 cron 或 systemd timer 在正常跑。

问:Nginx 报 SSL 证书链不完整?
答:ssl_certificate 指向 fullchain.pem,ssl_certificate_key 指向 privkey.pem,顺序别反。

问:怎么确认证书真的生效了?
答:浏览器点地址栏小锁看签发者和到期日,或用 openssl s_client -connect 域名:443 检查返回的证书链;若链里出现别的服务商,说明 Nginx 配错了证书文件。

相关完整手册

系统化的排查与配置思路,建议顺手收藏这几篇完整手册: