mirror of
https://github.com/fatedier/frp.git
synced 2026-05-15 08:05:49 -06:00
[GH-ISSUE #4239] nginx 转发请求到 frps 的 HTTPS 时报错 502 #3337
Labels
No labels
In Progress
WIP
WaitingForInfo
bug
doc
duplicate
easy
enhancement
future
help wanted
invalid
lifecycle/stale
need-issue-template
need-usage-help
no plan
proposal
pull-request
question
todo
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: github-starred/frp#3337
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @ks4na on GitHub (May 24, 2024).
Original GitHub issue: https://github.com/fatedier/frp/issues/4239
Bug Description
由于 frp 内网穿透的 HTTPS 服务,需要携带
vhostHTTPSPort指定的端口号(例如:20443),所以想要在 frps 所在的机器上通过 nginx 反向代理来隐藏端口号。所以就有了如下的
nginx请求转发配置(*.frps.example.com已经配置了解析到当前服务器):想要实现当访问
https://web-https.frps.example.com时,转发请求到 frps 监听 HTTPS 服务的地址https://127.0.0.1:20443,然后根据frpc.toml中的配置:将请求转发到内网服务器。
但是这样做会报错
502, nginx 反向代理的日志输出如下:报错的原因是
unrecognized name。frps的日志输出如下(调整日志等级log.level = debug):对比携带
20443端口的请求时的日志输出:发现少了
host的值。frpc Version
0.52.3
frps Version
0.52.3
System Architecture
linux/amd64
Configurations
frps.toml:frpc.toml:Logs
No response
Steps to reproduce
...
Affected area
@ks4na commented on GitHub (May 24, 2024):
翻看了相关 issue,发现似乎并没有比较好的解决方案:
proxy_ssl_server_name on;,但是只加上这个配置也没有效果其他一些相关 issue ( #359, #520 )也没有给出解决方案。
查看源码 + 询问 chatgpt ,最终找到了解决方案,在此记录一下,方便后续有人出现同样问题时参考。
从源码找到获取
host的位置:https.go 48 行 的reqInfoMap["Host"] = clientHello.ServerName。 询问 chatgpt ,说是需要添加额外 nginx 配置以在反向代理请求时保留并传递客户端提供的 SNI 信息:解释:
proxy_ssl_server_name on;:启用 SNI 传递。proxy_ssl_name $host;:设置 SNI 名称为客户端请求的主机名。添加上面的配置项,reload nginx 之后,确实可以正常访问了。
之前的 issue #610 中作者回复中提到过使用
proxy_ssl_server_name on;,但是当时添加了测试无效,于是又查了一下 nginx 文档 proxy_ssl_name ,发现默认值是$proxy_host,By default, the host part of the proxy_pass URL is used.由于我这里 proxy_pass 填写的是 127.0.0.1,所以无法获取到
host,而chatgpt 的答案中proxy_ssl_name设置为客户端请求的主机名$host,所以 frp 可以正常获取到host。贴一篇博客供参考 - Nginx反向代理,当后端为Https时的一些细节和原理
@shyandsy commented on GitHub (Dec 10, 2024):
数据请求确实到了我内网,也到了我目标端口6443
但还是不通,哦 kubectl是双向加密鉴权证书,这个方法可能行不通
@MinionTim commented on GitHub (Dec 12, 2024):
这种改法成功与否,还跟nginx的版本有关。我在nginx/1.22.1 上运行,一直报错:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:SSL alert number 40) while SSL handshaking to upstream。
但是换成 nginx/1.27.3 和 nginx/1.23.4 这两个版本却都成功了,对应的系统分别是Debian12、Debian11。
@Z46I4W5476SJA commented on GitHub (May 8, 2025):
哇 兄弟 上班研究了一天 总是失败 直到看到你这条 加上了sni的配置 可以了 太感谢了