从 0 到 1:用 Let's Encrypt 给网站配置 HTTPS(阿里云 + 宝塔)

本文记录一套可复现的流程:从只有 HTTP 和一台云服务器,到浏览器地址栏出现安全锁、全站走 HTTPS。环境以 阿里云 ECS + 宝塔面板 + Nginx 为例;文末附 certbot 命令行 备选方案。

脱敏说明:下文域名、IP、路径均使用占位符(如 example.comYOUR_SERVER_IP),请替换为你自己的值。


0. 先搞懂:Let’s Encrypt 在做什么

概念 说明
Let’s Encrypt 免费 CA,签发短期证书(通常约 90 天),靠自动续期长期使用
你要证明的事 「这个域名归我管」
常见验证方式 HTTP-01(在 http://域名 放验证文件,一般需 80 端口可达)或 DNS-01(在 DNS 加 TXT,不依赖 80/443)
证书装在哪 Nginx(宝塔生成配置)在 listen 443 ssl 或自定义端口(如 5389 ssl)上使用

整体链路:

flowchart LR
    A[域名 DNS 指向服务器] --> B[证明域名所有权]
    B --> C[签发 fullchain + privkey]
    C --> D[Nginx 配置 ssl_certificate]
    D --> E[浏览器 https 访问]
    C --> F[自动续期 约每 60 天检查]

1. 前置准备(不做完这里,后面必失败)

1.1 你需要具备

  • 一台有公网 IP 的云服务器(本文以阿里云 ECS 为例)
  • 一个已解析到该 IP 的域名(如 example.com,可选 www.example.com
  • 已安装 宝塔 Linux 面板,且已安装 Nginx

1.2 域名解析(DNS)

在域名服务商控制台添加 A 记录

主机记录 记录类型 记录值
@ A YOUR_SERVER_IP
www(可选) A YOUR_SERVER_IP

验证(本地终端):

ping example.com
# 应解析到 YOUR_SERVER_IP

# 或
nslookup example.com

DNS 未生效时(几分钟到 48 小时不等),Let’s Encrypt 验证会失败,请耐心等待或换 DNS 验证。

1.3 安全组与防火墙(必放行端口)

端口 用途
80 HTTP-01 验证、HTTP→HTTPS 跳转
443 标准 HTTPS(推荐)
自定义端口(如 5389 若你坚持用非 443 访问站点,需额外放行

阿里云:ECS → 安全组 → 入方向 → 添加规则(TCP 80、443,来源 0.0.0.0/0 或你的办公 IP)。

宝塔:面板 → 安全 → 放行同上端口。

易错点:只开了 443、没开 80,文件验证经常失败——Let’s Encrypt 要先访问 http://example.com/.well-known/...

1.4 在宝塔创建「网站」(不是 Node 项目)

  1. 宝塔 → 网站添加站点
  2. 域名example.com(需要 www 则一并填写)
  3. 根目录:你的站点目录,例如 /www/wwwroot/example.com(静态博客可指向 .../dist
  4. PHP:纯静态站可选「纯静态」或关闭 PHP

验证(服务器上):

curl -I http://127.0.0.1/
# 或指定站点
curl -I -H "Host: example.com" http://127.0.0.1/

应返回 200301,而不是连接拒绝。


2. 路线 A:宝塔一键申请 Let’s Encrypt(推荐)

2.1 打开 SSL 设置

  1. 宝塔 → 网站 → 找到 example.com设置
  2. 左侧 SSL → 选择 Let’s Encrypt

2.2 选择域名与验证方式

  1. 勾选要签发的域名:example.comwww.example.com

  2. 验证方式

    • 文件验证(默认):要求 80 端口从公网能访问到你的服务器
    • DNS 验证:按面板提示到域名商添加 TXT 记录(适合 80 被挡、或仅用非标准端口对外服务时)
  3. 点击 申请

成功后面板会显示:

  • 证书品牌:Let’s Encrypt
  • 到期时间(约 90 天后)
  • 证书目录(宝塔内部路径,一般无需手改)

2.3 开启强制 HTTPS

仍在 SSL 页:

  1. 打开 强制 HTTPS
  2. 确认 HTTP 自动跳转 HTTPS 已生效(访问 http://example.com 应跳到 https://...

2.4 使用非标准 HTTPS 端口(可选)

若你希望访问地址为 https://example.com:5389/(而非默认 443):

  1. 网站设置配置文件(Nginx)
  2. 确认存在类似配置(路径为占位示例):
server {
    listen 5389 ssl;
    http2 on;
    server_name example.com www.example.com;
    root /www/wwwroot/example.com;

    ssl_certificate    /www/server/panel/vhost/cert/YOUR_SITE_ID/fullchain.pem;
    ssl_certificate_key    /www/server/panel/vhost/cert/YOUR_SITE_ID/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    # ... 其余 location、日志等 ...
}
  1. 安全组 + 宝塔防火墙 放行 5389
  2. 保存后 重载 Nginx(宝塔会提示)

注意:证书仍是签给 example.com 的;端口可以自定义,但浏览器地址栏会带 :5389

2.5 验证 HTTPS 是否真正生效

命令行(在服务器或本机)

# 标准 443
curl -I https://example.com/

# 自定义端口
curl -Ik https://example.com:5389/

# 查看证书颁发者与有效期
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates

浏览器

  1. 打开 https://example.com
  2. 点击地址栏 连接安全证书有效
  3. 颁发者应为 Let’s Encrypt(或 R3 / E 系列中间 CA)

3. 路线 B:certbot 命令行(理解原理 / 无面板时)

适合不想依赖面板、或需要脚本化部署的场景。

3.1 安装 certbot(示例:Debian/Ubuntu)

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

CentOS / Alibaba Cloud Linux 可用 yum/dnf 安装同名或 certbot 包(以系统源为准)。

3.2 自动配置 Nginx(最简单)

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

按提示输入邮箱、同意协议;certbot 会修改 Nginx 并申请证书。

3.3 仅申请证书(自行改 Nginx)

sudo certbot certonly --webroot \
  -w /www/wwwroot/example.com \
  -d example.com -d www.example.com

证书常见路径:

/etc/letsencrypt/live/example.com/fullchain.pem
/etc/letsencrypt/live/example.com/privkey.pem

在 Nginx 中引用:

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

重载:

sudo nginx -t && sudo systemctl reload nginx

3.4 续期测试

sudo certbot renew --dry-run

无报错即续期逻辑正常;系统通常有 certbot.timer 或 cron 自动执行。


4. 自动续期(必做认知,否则 90 天后站点变「不安全」)

方式 说明
宝塔 面板一般内置 Let’s Encrypt 续签;在 计划任务 中可看到相关任务;SSL 页查看剩余天数
certbot certbot renew 由 systemd timer 或 cron 触发;用 --dry-run 定期自测

建议:到期前 30 天在日历或监控里加提醒;续期失败时优先查 80 是否仍可达、DNS 是否被改。


5. 常见问题与排错

现象 可能原因 处理
申请失败:连接超时 / 验证失败 80 未放行、DNS 未生效、CDN 橙云代理了验证路径 关 CDN 或改用 DNS 验证;查安全组
http 能开、https 不行 未申请 SSL 或 Nginx 未 listen 443 ssl 重走 2.2;检查配置
证书有效但浏览器仍「不安全」 混合内容(页面里仍有 http:// 的 JS/图片) F12 → Security / Console 查 Mixed Content
仅 IP 能访问,域名不行 server_name 与访问域名不一致 改 Nginx server_name
自定义端口无法访问 安全组/防火墙未放行该端口 放行并在 Nginx listen 该端口
主站已 HSTS,子服务(如面板)用自签证书 浏览器拒绝跳过警告 子服务也换 Let’s Encrypt 或不用 HSTS 域名访问

混合内容排查示例(浏览器控制台可能出现):

Mixed Content: The page at 'https://example.com/' was loaded over HTTPS,
but requested an insecure script 'http://...'

把所有资源链接改为 https:// 或相对路径。


6. 静态博客项目如何配合(可选阅读)

若站点为本仓库这类 Markdown → dist/ 静态站

  1. SSL 在宝塔/Nginx 层配置,与 npm run build 无关
  2. 站点根目录指向 dist(或 pull 后包含 dist 的目录)
  3. 本地发布:npm run deploy → push release → CI 在服务器 git pull 即可更新页面,无需每次重签证书

7. 从零到一 Checklist

复制到笔记里逐项打勾:

  • 域名 A 记录指向
  • 宝塔已创建网站,server_name
  • curl -I https://example.com

8. 参考


总结:Let’s Encrypt 的核心是 证明域名所有权 → 签发短期证书 → Nginx 挂载 → 自动续期。在阿里云 + 宝塔场景下,优先用面板 SSL → Let’s Encrypt;验证失败时先查 80 与 DNS,再考虑 DNS 验证;自定义端口只影响 访问端口,不影响「为域名签发证书」本身。