华为云 ECS 上用 Nginx + Let's Encrypt 配置 HTTPS 并自动续期:从安全组到 HSTS 的完整实践

举报
yd_252351073 发表于 2026/11/01 10:19:54 2026/11/01
【摘要】 在华为云 ECS 上用 Nginx + certbot 申请 Let's Encrypt 证书、配置 HTTPS、自动续期及常见坑。

华为云 ECS 上用 Nginx + Let’s Encrypt 配置 HTTPS 并自动续期:从安全组到 HSTS 的完整实践

站点上线后,浏览器地址栏的"不安全"提示很影响观感,部分接口和小程序也要求必须走 HTTPS。Let’s Encrypt 提供免费的 DV 证书,配合 certbot 可以做到签发、配置、续期全自动。本文以华为云 ECS 为例,分别给出 Ubuntu 22.04/24.04 和 HCE 2.0(Huawei Cloud EulerOS)下的操作步骤,最后整理几个容易踩的坑。下文用 your_domain 代表你自己的域名,照做时替换成实际域名即可。

一、准备工作

开始之前确认三件事:

  1. 域名已解析到 ECS 的弹性公网 IP,可以用下面的命令确认解析结果与 EIP 一致:
dig +short your_domain
dig +short www.your_domain
  1. 如果 ECS 在中国大陆区域(如华北-北京四、华东-上海一),域名必须完成 ICP 备案,否则访问 80/443 端口会被拦截,HTTP 验证也会失败。备案未完成时,可以先用香港等非大陆区域,或者改用 DNS 验证方式。

  2. 安全组放通 80 和 443。在控制台进入 ECS 详情页 → 安全组 → 入方向规则,添加两条规则:协议 TCP,端口 80 和 443,源地址 0.0.0.0/0。注意 80 端口不能省,证书签发和续期时 Let’s Encrypt 需要通过 80 端口访问验证文件。

二、安装 Nginx 并开放系统防火墙

Ubuntu 22.04/24.04:

sudo apt update
sudo apt install -y nginx
sudo systemctl enable --now nginx
# 如果启用了 ufw
sudo ufw allow 'Nginx Full'

HCE 2.0 / EulerOS:

sudo dnf install -y nginx
sudo systemctl enable --now nginx
# 如果启用了 firewalld
sudo firewall-cmd --permanent --add-service=http --add-service=https
sudo firewall-cmd --reload

先写一个最简单的站点配置,后面 certbot 会在这个基础上自动修改。Ubuntu 放在 /etc/nginx/sites-available/example.conf 并软链接到 sites-enabled,HCE 直接放到 /etc/nginx/conf.d/example.conf:

server {
    listen 80;
    server_name your_domain www.your_domain;
    root /var/www/example;
    index index.html;
}
sudo mkdir -p /var/www/example
echo ok | sudo tee /var/www/example/index.html
# 仅 Ubuntu 需要
sudo ln -s /etc/nginx/sites-available/example.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
curl -I your_domain

curl 返回 200 再往下走,否则先排查解析和安全组。

三、安装 certbot

Ubuntu 上推荐用 snap 安装官方版本,它会自带续期定时器:

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

也可以用 apt 安装发行版自带的包:sudo apt install -y certbot python3-certbot-nginx,两者选其一,不要同时装。

HCE 2.0 上没有 snap,可以按 certbot 官方文档用 Python 虚拟环境安装:

sudo dnf install -y python3 augeas-libs
sudo python3 -m venv /opt/certbot
sudo /opt/certbot/bin/pip install --upgrade pip
sudo /opt/certbot/bin/pip install certbot certbot-nginx
sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot

四、签发证书并开启跳转

第一次建议先用测试环境跑通流程,避免触发正式环境的频率限制:

sudo certbot certonly --nginx --staging -d your_domain -d www.your_domain

成功后去掉 --staging,正式签发并让 certbot 改写 Nginx 配置:

sudo certbot --nginx -d your_domain -d www.your_domain

过程中会询问邮箱并要求同意服务条款。完成后证书位于 /etc/letsencrypt/live/your_domain/,certbot 会在配置里加上 443 监听,并把 80 端口的请求 301 跳转到 HTTPS。如果想自己控制配置,可以手写成下面这样:

server {
    listen 80;
    server_name your_domain www.your_domain;
    set $target_scheme https;
    return 301 $target_scheme://$host$request_uri;
}

server {
    listen 443 ssl;
    http2 on;   # Nginx 1.25.1 以下改为 listen 443 ssl http2;
    server_name your_domain www.your_domain;

    ssl_certificate     /etc/letsencrypt/live/your_domain/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    root /var/www/example;
    index index.html;
}

Ubuntu 22.04 自带的 Nginx 是 1.18,不认识 http2 on;,要用注释里的旧写法;Ubuntu 24.04 自带 1.24,同样用旧写法。改完执行 sudo nginx -t && sudo systemctl reload nginx。

五、自动续期

Let’s Encrypt 证书有效期 90 天,certbot 会在到期前 30 天内自动续期。先确认定时器存在:

# snap 安装
systemctl list-timers | grep certbot   # 应看到 snap.certbot.renew.timer
# apt 安装对应 certbot.timer

HCE 上用 pip 安装没有定时器,需要自己加一条 cron:

echo "0 3,15 * * * root /opt/certbot/bin/python -c 'import random,time;time.sleep(random.random()*3600)' && /usr/bin/certbot renew -q" | sudo tee /etc/cron.d/certbot

续期后需要让 Nginx 加载新证书。用 --nginx 插件签发的证书续期时会自动 reload;如果用的是 webroot 等方式,加一个部署钩子:

sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx <<'HOOK'
#!/bin/sh
systemctl reload nginx
HOOK
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx

最后模拟一次续期,确认整条链路可用:

sudo certbot renew --dry-run

六、常见坑

  • 安全组只开了 443:首次签发能用 DNS 验证绕过,但用 HTTP 验证续期时会失败,三个月后证书过期才发现。80 端口要一直开着,靠 301 跳转即可。
  • 未备案被拦截:大陆区域未备案的域名,验证请求拿到的是拦截页,certbot 报 unauthorized 或超时。先完成备案,或用 --preferred-challenges dns 走 DNS 验证。
  • 频率限制:同一组域名每周最多签发 5 张重复证书,反复调试很容易撞上。调试阶段一律加 --staging。
  • HSTS 加得太早:add_header Strict-Transport-Security "max-age=31536000" always; 一旦被浏览器记住,期间证书出问题用户将无法访问。建议先用 max-age=300 观察,稳定后再加大;includeSubDomains 和 preload 要确认所有子域都支持 HTTPS 后再加。
  • 不要指望到期邮件:Let’s Encrypt 已于 2025 年停止发送证书到期提醒邮件,需要自己用监控或脚本检查,例如 echo | openssl s_client -connect your_domain:443 -servername your_domain 2>/dev/null | openssl x509 -noout -enddate。
  • CDN 或 ELB 前置:如果 HTTPS 在 ELB 或 CDN 上终结,证书应上传到对应服务,ECS 上的证书不会生效,续期也要相应改成上传流程。

七、验证部署效果

配置完成后,从本地或另一台机器检查三项内容:跳转是否生效、证书链是否完整、到期时间是否正确。

curl -I your_domain                 # 应返回 301,Location 指向 https
curl -I --proto-default https your_domain         # 应返回 200
sudo certbot certificates           # 查看域名、到期时间与证书路径

certbot certificates 的输出里,Expiry Date 后面会标出剩余天数,Certificate Path 指向 fullchain.pem。Nginx 一定要引用 fullchain.pem 而不是 cert.pem,后者缺少中间证书,桌面浏览器可能还能打开,但部分手机和 Java、curl 等客户端会报证书链不完整。

另外建议把证书目录纳入日常备份范围。/etc/letsencrypt 里保存了账号密钥和续期配置,重装系统后直接恢复这个目录,再装好 certbot 就能继续续期,不必重新签发。如果要迁移到新的 ECS,先把这个目录拷过去,确认 Nginx 正常后再切换域名解析,可以做到不停机。

八、关于泛域名证书

如果子域名很多,可以申请 *.your_domain 这样的泛域名证书。泛域名只支持 DNS 验证,需要在域名解析里添加一条 _acme-challenge 开头的 TXT 记录。手动方式每次续期都要人工改记录,没法自动化;想全自动的话,需要用支持华为云 DNS 接口的第三方插件或 acme_sh 脚本 的 DNS API 模式,并为它创建只拥有云解析权限的 IAM 子用户,避免把主账号的 AK/SK 放到服务器上。

结语

按以上步骤操作,一台 ECS 就能在十分钟左右完成 HTTPS 部署,之后基本不用再管证书。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。