本文档记录如何为部署在 EC2 上的 Web 站点申请免费的 Let's Encrypt 证书, 并在 Nginx 上启用 HTTPS、配置自动续期。

文档中的以下内容为占位符,请替换为你的实际值:

  • <YOUR_DOMAIN>:站点域名,例如 app.example.com

  • <EC2_PUBLIC_IP>:EC2 公网 IP

  • <NGINX_CONF>:站点 Nginx 配置文件路径,例如 /etc/nginx/conf.d/site.conf


前置条件

  1. 一台可从公网访问的 EC2 实例,已安装并运行 Nginx(监听 80 端口)。

  2. 拥有一个域名,并已将其 A 记录解析到 <EC2_PUBLIC_IP>

  3. EC2 安全组入站规则已放行:

    1. 80 (HTTP):Let's Encrypt HTTP-01 校验 + HTTP→HTTPS 跳转必需,保持开放。

    2. 443 (HTTPS):对外提供 HTTPS 服务必需。

  4. 具备 sudo 权限。

说明:公有 CA(含 Let's Encrypt、AWS ACM)不会为裸 IP 签发证书, 因此必须先有域名并完成解析。


步骤一:确认域名解析已生效


dig +short <YOUR_DOMAIN> A

输出应为 <EC2_PUBLIC_IP>。若不一致,等待 DNS 生效或检查解析记录后再继续。


步骤二:安装 Certbot

Amazon Linux 2023:


sudo dnf install -y certbot python3-certbot-nginx

(Ubuntu/Debian 使用 sudo apt install -y certbot python3-certbot-nginx


步骤三:确认 Nginx 站点配置的 server_name

Certbot 的 nginx 插件需要通过 server_name 匹配到对应的 server 块。 编辑 <NGINX_CONF>,确保包含你的域名:


server { listen 80 default_server; listen [::]:80 default_server; server_name <YOUR_DOMAIN>; root /usr/share/nginx/<APP_DIR>; index index.html; # SPA 前端location / { try_files $uri $uri/ /index.html; } # 后端 API 反向代理location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_read_timeout 600s; proxy_send_timeout 600s; } }

校验并重载:


sudo nginx -t sudo systemctl reload nginx


步骤四:申请证书并自动配置 HTTPS


sudo certbot --nginx \ -d <YOUR_DOMAIN> \ --non-interactive \ --agree-tos \ --register-unsafely-without-email \ --redirect

参数说明:

  • --nginx:使用 nginx 插件,自动完成 HTTP-01 校验并写入 443 配置。

  • -d <YOUR_DOMAIN>:申请证书的域名(多个域名可重复 -d)。

  • --agree-tos:同意 Let's Encrypt 服务条款。

  • --register-unsafely-without-email:不绑定邮箱注册(如需接收到期提醒, 可改用 -m you@example.com 替代本参数)。

  • --redirect:自动添加 HTTP → HTTPS 的 301 跳转。

成功后证书文件位于:


/etc/letsencrypt/live/<YOUR_DOMAIN>/fullchain.pem /etc/letsencrypt/live/<YOUR_DOMAIN>/privkey.pem

Certbot 会自动在 <NGINX_CONF> 中追加 443 监听、证书路径及跳转规则。


步骤五:验证

本机验证(无需依赖外部 DNS,直接指向本地):


# HTTPS 应返回 200 curl -sI https://<YOUR_DOMAIN>/ --resolve <YOUR_DOMAIN>:443:127.0.0.1 | head -3 # HTTP 应返回 301 跳转 curl -sI http://<YOUR_DOMAIN>/ --resolve <YOUR_DOMAIN>:80:127.0.0.1 | head -4

浏览器访问 https://<YOUR_DOMAIN>,地址栏应显示锁标志且无证书告警。


步骤六:启用自动续期

Let's Encrypt 证书有效期 90 天,需保证自动续期任务处于启用状态:


# 启用并立即激活续期定时器 sudo systemctl enable --now certbot-renew.timer # 确认状态 systemctl is-enabled certbot-renew.timer # 期望: enabled systemctl is-active certbot-renew.timer # 期望: active# 续期演练(不会真正续期,仅验证流程) sudo certbot renew --dry-run

看到 Congratulations, all simulated renewals succeeded 即表示续期链路正常。


常见问题

  • 证书申请卡住或失败:检查安全组 80 端口是否对公网开放, Let's Encrypt 需通过 80 端口完成 HTTP-01 校验。

  • 浏览器打不开 HTTPS 但本机 curl 正常:多半是安全组未放行 443。

  • certbot-renew.timer 为 disabled:执行步骤六的 enable --now

  • 更换/新增域名:重新执行步骤四,-d 增加新域名即可。


备选方案(供参考)

方案 是否需要域名 说明
Nginx + Let's Encrypt(本文) 单机部署最简单、免费,本机终止 TLS
CloudFront + ACM 可用 *.cloudfront.net 免域名 附带 CDN/防护,自带有效证书,配置较多
ALB + ACM 贴合生产实践,但 ALB 有固定月费

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐