跳到主要内容

1Panel 反向代理配置 HTTPS:解决 502、申请证书并开启强制跳转

· 阅读需 9 分钟
王小义
在北京打工的程序员,公众号「王小义笔记」,股票、黄金、演唱会门票

我这次处理的是一个很典型的自部署问题:服务在服务器本机端口访问正常,但通过 1Panel 绑定域名后一直报 502 Bad Gateway,证书申请又卡在 DNS 验证超时。

最后跑通的顺序是:先确认后端使用 HTTP 还是 HTTPS,修好反向代理;再开放 80 端口,用 HTTP 验证申请证书;证书签发成功后,最后开启 HTTPS 和强制跳转。

隐私说明:本文中的域名和公网 IP 均已替换为示例值。app.example.com、api.example.com 和 203.0.113.10 是举例说明,不能直接用于你的服务器,请换成自己的真实配置。1Panel 不同版本的菜单名称可能略有区别。

先说结论​

这次踩坑主要有两个原因:

  1. 后端服务只提供 HTTP,反向代理地址却写成了 https://127.0.0.1:9119,导致 1Panel 的 OpenResty 无法正常连接上游,最终返回 502。
  2. Let's Encrypt 证书使用手动 DNS 验证时,TXT 记录没有在规定时间内通过检查,导致验证超时。

我的处理方式是:

公网请求
↓
1Panel / OpenResty(处理 HTTPS)
↓
http://127.0.0.1:9119(本机后端服务)

这里最容易理解错的一点是:网站对外使用 HTTPS,不代表反向代理到本机服务时也必须使用 HTTPS。

如果 TLS 已经在 1Panel/OpenResty 这一层终止,本机后端继续使用 HTTP 很正常。把一个只支持 HTTP 的端口强行写成 https://,反而会直接导致 502。

准备工作​

开始前需要准备:

  • 一台已经安装 1Panel 的云服务器;
  • 一个已解析到服务器公网 IP 的域名;
  • 一个正在本机端口运行的 HTTP 服务;
  • 云厂商安全组和服务器防火墙允许访问 80/TCP、443/TCP;
  • 一个用于注册 ACME 账户的邮箱。

本文使用下面这组脱敏后的示例配置:

配置项示例值
主域名app.example.com
第二个服务域名api.example.com
服务器公网 IP203.0.113.10
后端监听地址127.0.0.1
后端端口9119
后端协议HTTP

动手前,建议先在服务器上确认后端确实能返回内容:

curl -I http://127.0.0.1:9119

如果能看到 HTTP/1.1 200 OK,说明后端本身是通的,可以继续检查 1Panel。

如果这里都访问失败,就先处理容器端口、进程监听或服务器防火墙,不要急着申请证书。

第一步:在 1Panel 创建网站​

进入:

1Panel → 网站 → 网站

新建一个反向代理网站,主域名填写:

app.example.com

如果网站已经创建,可以直接进入网站配置,不需要重复添加。

同时确认 DNS 服务商中的 A 记录已经指向服务器公网 IP:

app.example.com → 203.0.113.10

DNS 刚修改时可能需要等待一段时间。可以在本地执行:

nslookup app.example.com

或者:

dig +short app.example.com

返回的地址应该和服务器公网 IP 一致。

第二步:配置反向代理并修复 502​

进入:

1Panel → 网站 → app.example.com → 配置 → 反向代理

编辑代理配置,把代理地址填写为:

http://127.0.0.1:9119

如果之前写的是:

https://127.0.0.1:9119

而后端实际上只支持 HTTP,就要把协议改回 http://。

保存后先用 HTTP 测试:

http://app.example.com

只要页面能正常打开,或者请求返回 200,就说明反向代理已经打通。

为什么协议写错会出现 502​

1Panel 默认通过 OpenResty/Nginx 把请求转发到后端。代理地址写成 https:// 后,OpenResty 会尝试和上游进行 TLS 握手。

但 9119 端口提供的是普通 HTTP,无法完成 TLS 握手,于是网关只能返回 502。

这类问题不要只盯着端口。排查时要同时确认:

  • 后端进程是否运行;
  • 端口是否监听;
  • 监听地址是 127.0.0.1 还是 0.0.0.0;
  • 后端使用 HTTP 还是 HTTPS;
  • 1Panel 中的代理协议是否和后端一致。

第三步:创建 ACME 账户​

反向代理确认正常后,再开始申请证书。

进入:

1Panel → 网站 → 证书 → ACME 账户

alt text

创建一个新账户:

配置项建议值
CALet's Encrypt
邮箱填写自己的常用邮箱
密钥算法EC 256 或 RSA 2048

个人服务使用 EC 256 就够了。如果需要兼容非常老的客户端,也可以选择 RSA 2048。

第四步:使用 HTTP 验证申请证书​

进入:

1Panel → 网站 → 证书 → 申请证书

alt text

填写:

配置项内容
主域名app.example.com
ACME 账户选择刚创建的账户
验证方式HTTP 验证
自动续签开启
推送证书不需要

提交申请前,必须确认服务器的 80/TCP 可以从公网访问。

如果使用 Oracle Cloud,需要同时检查:

  1. Oracle Cloud 网络安全列表或网络安全组;
  2. 服务器系统防火墙;
  3. 1Panel 防火墙;
  4. 1Panel/OpenResty 是否监听 80 端口。

云平台入站规则可以按下面的方式配置:

配置项内容
来源0.0.0.0/0
协议TCP
目标端口80

证书申请期间先不要开启“HTTP 强制跳转到 HTTPS”。等证书签发成功,再开启跳转,排查起来会简单很多。

第五步:给网站启用 HTTPS​

证书签发成功后,进入:

1Panel → 网站 → app.example.com → HTTPS

设置:

  • HTTPS:开启;
  • 证书来源:选择已有证书;
  • 证书:选择 app.example.com 对应的证书;
  • HTTP 选项:重定向到 HTTPS;
  • HTTP/2:开启。

保存后访问:

https://app.example.com

我判断配置成功会看这几个结果:

  • 浏览器地址栏显示 HTTPS;
  • 证书域名与当前访问域名一致;
  • HTTP 访问会自动跳转到 HTTPS;
  • 页面不再出现 502;
  • 后端服务日志能收到代理过来的请求。

也可以用命令检查跳转和证书:

curl -I http://app.example.com
curl -I https://app.example.com

第一条通常应该返回 301 或 308,并跳转到 HTTPS;第二条应该返回后端服务的正常状态码。

第六步:给第二个服务配置 HTTPS​

如果还有另一个域名,例如:

api.example.com

不要直接复用第一个网站的配置。应该先为它创建独立的网站,并确保它能通过 80 端口响应 HTTP 请求。

推荐顺序是:

  1. 添加 api.example.com 网站;
  2. 配置正确的本机反向代理地址;
  3. 确认 http://api.example.com 能到达 1Panel/OpenResty;
  4. 使用 HTTP 验证申请 api.example.com 的证书;
  5. 证书签发后启用 HTTPS;
  6. 如果之前使用自签证书,再替换成新申请的 Let's Encrypt 证书。

如果这个域名没有独立的 80 端口网站配置,HTTP 请求可能会落到 OpenResty 默认页面。这样即使 DNS 正确,ACME 验证路径也可能无法正常工作。

HTTP 验证失败怎么排查​

1. 检查 80 端口是否真正开放​

云服务器开放端口通常不只改一个地方。云平台安全组放行了,系统防火墙仍然可能拦截。

可以从另一台设备测试:

curl -I http://app.example.com

如果一直超时,优先检查安全组、路由和防火墙。

2. 检查域名 A 记录​

确认:

app.example.com → 203.0.113.10

如果解析到了旧服务器,Let's Encrypt 会在错误的机器上查找验证文件,证书自然申请失败。

3. Cloudflare 暂时改为“仅 DNS”​

如果域名托管在 Cloudflare,可以在排查阶段把代理状态暂时改成“仅 DNS”,也就是灰色云朵。

证书签发完成、源站 HTTPS 正常后,再根据自己的架构决定是否重新开启代理。

4. 删除错误的 AAAA 记录​

如果域名存在 AAAA 记录,Let's Encrypt 可能通过 IPv6 访问。

服务器没有正确配置 IPv6,而 DNS 中却保留了 AAAA 记录时,就可能出现 IPv4 正常、证书验证却失败的情况。不使用 IPv6,就不要留一条错误的 AAAA 记录。

5. 测试 ACME 验证路径​

在浏览器或其他设备访问:

http://app.example.com/.well-known/acme-challenge/test

返回 404 Not Found 不一定有问题,它至少证明请求已经到达 Web 服务器。

真正需要处理的是:

  • 连接超时;
  • 域名无法解析;
  • 请求落到另一台服务器;
  • 被错误跳转或拦截;
  • 80 端口根本没有监听。

踩坑记录​

1. 对外 HTTPS,不等于上游也要写 HTTPS​

我一开始看到网站要启用 HTTPS,下意识把反向代理地址也写成了 https://127.0.0.1:9119。

但本机服务并没有配置 TLS,直接导致 502。把上游协议改回 HTTP 后,请求马上恢复正常。

2. 手动 DNS 验证容易卡在 TXT 记录​

手动 DNS 验证并不是不能用,但它依赖 TXT 记录填写正确并及时生效。记录名、记录值、DNS 缓存或操作时间有一个环节不对,就可能验证超时。

对于已经能开放 80 端口的普通网站,我更倾向于直接使用 HTTP 验证,步骤少,也方便自动续签。

3. 顺序反了,问题会缠在一起​

如果反向代理还在报 502,就急着开 HTTPS、强制跳转和 Cloudflare 代理,排查链路会越来越长。

最稳的顺序始终是:

检查本机后端
→ 配置 HTTP 反向代理
→ 确认域名 HTTP 可访问
→ 申请证书
→ 开启 HTTPS
→ 开启 HTTP 到 HTTPS 跳转

总结​

用 1Panel 给自部署服务配置反向代理和 HTTPS,本身并不复杂。真正容易出错的是协议、端口和操作顺序。

记住三个判断就够了:

  1. 先用 curl 确认后端到底是 HTTP 还是 HTTPS;
  2. HTTP 验证前,确保域名解析正确且公网能访问 80 端口;
  3. 证书签发成功后,再开启强制 HTTPS 跳转。

这套流程不只适用于某一个服务。以后给 Docker 容器、AI 接口、个人面板或其他自部署应用绑定域名,都可以按同样的顺序处理。