华为云 Flexus L 公网 IP 配 HTTPS:Let's Encrypt 6 天短效证书 + nginx 自动续期踩坑记

举报
yd_286747025 发表于 2026/11/04 09:07:27 2026/11/04
【摘要】 最近在华为云 Flexus 应用服务器 L(2 核 2G)上跑了一个自己写的小应用,想让手机 App 通过 wss:// 连上来。问题是:我没给这台机器绑域名,浏览器和 App 对明文 ws 又不太友好。查了一圈发现,Let’s Encrypt 现在可以直接给公网 IP 签证书,只不过证书是"短效"的,只有 6 天左右。这篇记录我的配置和踩到的坑。一、整体思路nginx 监听 80 和 44...

最近在华为云 Flexus 应用服务器 L(2 核 2G)上跑了一个自己写的小应用,想让手机 App 通过 wss:// 连上来。问题是:我没给这台机器绑域名,浏览器和 App 对明文 ws 又不太友好。查了一圈发现,Let’s Encrypt 现在可以直接给公网 IP 签证书,只不过证书是"短效"的,只有 6 天左右。这篇记录我的配置和踩到的坑。

一、整体思路

  1. nginx 监听 80 和 443,80 端口只用来放 ACME 的 HTTP-01 验证文件,其余请求一律 404;
  2. 443 终止 TLS,把 /ws/mobile 这一个路径反代给后端;
  3. certbot 用 webroot 方式申请证书,选 shortlived 配置;
  4. systemd timer 每天跑两次 renew,续上之后 reload nginx。

安全组需要放行 80 和 443(华为云控制台里的安全组规则,默认没开,别忘了)。

二、nginx 配置(节选)

server {
    listen 80;
    server_name <你的公网IP>;
    location ^~ /.well-known/acme-challenge/ {
        root /var/lib/myapp/acme;
        default_type text/plain;
    }
    location / { return 404; }
}

server {
    listen 443 ssl;
    server_name <你的公网IP>;
    ssl_certificate     /etc/letsencrypt/live/myapp/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/myapp/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    location = /ws/mobile {
        proxy_pass http://127.0.0.1:3080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 3600s;
        proxy_buffering off;
    }
    location / { return 404; }
}

三、申请证书

我用 pip 在独立 venv 里装了 certbot(这台机器 PyPI 官方源很慢,换成了华为云的 PyPI 镜像),当前版本 5.8.0。关键参数是 webroot 验证、ECDSA 密钥和 shortlived 配置,对应 renewal 文件里能看到:

preferred_profile = shortlived
authenticator = webroot
key_type = ecdsa

IP 证书只能走 HTTP-01 / TLS-ALPN 这类验证,不能用 DNS 验证,所以 80 端口必须能从外网访问。

四、自动续期

证书有效期只有 6 天多一点,我这张是 11 月 3 日签发、11 月 9 日到期,手动续肯定不现实。写了一对 systemd 单元:

# renew.timer
[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=20m
Persistent=true

# renew.service
[Service]
Type=oneshot
ExecStart=/opt/myapp/certbot/bin/certbot renew --quiet --deploy-hook "/bin/systemctl reload nginx"

Persistent=true 的作用是:如果服务器恰好关机错过了触发点,开机后补跑一次。短效证书对这个很重要。

五、踩坑

坑 1:deploy-hook 必须是一个整体参数。如果写成 --deploy-hook /bin/systemctl reload nginx,certbot 只会把 /bin/systemctl 当 hook,后面的 reload nginx 成了多余参数,续期命令会报错。要用双引号把整条命令包起来。我是用 systemd 的 drop-in 覆盖的:先写一行空的 ExecStart= 清掉原来的,再写新的,不改原文件,升级也不会被覆盖。

坑 2:后端只监听内网网卡。我的应用绑定的是 Flexus 的内网网卡地址,而 nginx 里习惯写 127.0.0.1,对不上。不想改应用的话,可以用 systemd 自带的 systemd-socket-proxyd 做本地转发:

# loopback.socket
[Socket]
ListenStream=127.0.0.1:3080
# loopback.service
[Service]
ExecStart=/usr/lib/systemd/systemd-socket-proxyd <内网网卡地址>:3080

不用额外装 socat,有连接才拉起,对 2G 内存的小机器很友好。

六、验证

systemctl list-timers 能看到下次触发时间;journalctl -u renew.service 看到 “Deactivated successfully” 就说明跑通了。我这边 11 月 4 日凌晨那次检查是正常结束的,nginx 和转发的 socket 都是 active。想自己确认证书日期可以用:

openssl x509 -in /etc/letsencrypt/live/myapp/fullchain.pem -noout -dates

七、小结

给裸 IP 配 HTTPS 比我想象的简单,难点不在签发,而在"6 天一续"带来的自动化细节:timer 要有 Persistent、hook 引号要对、80 端口要一直通。手头没有域名时,这是个挺实用的办法。nginx 只暴露必要路径、其余全部 404,也别把后端直接裸露在公网上。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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