[GH-ISSUE #4748] 开启transport.proxyProtocolVersion = "v2"后无法访问 #3753

Closed
opened 2026-05-05 14:24:11 -06:00 by gitea-mirror · 12 comments
Owner

Originally created by @xiaowen-king on GitHub (Apr 7, 2025).
Original GitHub issue: https://github.com/fatedier/frp/issues/4748

Bug Description

#frp版本#

0.61.1

#穿透的服务#

Dufs

穿透的服务器的项目地址:https://github.com/sigoden/dufs

#环境#

公网服务器使用的阿里云香港的服务器,然后穿透到家里面,香港的服务器安装了宝塔面板,用来配置反向代理,从而实现80端口和443端口的复用

#问题#

使用的http代理,打开transport.proxyProtocolVersion = "v2"后无法访问,浏览器提示该网页无法正常运作HTTP ERROR 400,注释掉配置文件里面的transport.proxyProtocolVersion = "v2"后可以正常访问。

frpc Version

0.61.1

frps Version

0.61.1

System Architecture

linux/amd64

Configurations

#frpc配置文件#

serverAddr = "47..."
serverPort = 5
3
user = "MP73"
auth.method = "token"
auth.token = "T
J****e"
transport.tls.enable = true

proxies
name = "文件共享"
type = "http"
localIP = "127.0.0.1"
localPort = 5000
customDomains = ["file.ersansi.top"]
transport.proxyProtocolVersion = "v2"

#frps配置文件#

bindAddr = "0.0.0.0"
bindPort = 5***

kcpBindPort = 5***

quicBindPort = 2***

transport.tcpMux = true

vhostHTTPPort = 2***
vhostHTTPSPort = 2***

webServer.addr = "0.0.0.0"
webServer.port = 2***
webServer.user = ""
webServer.password = "
******"

log.to = "enable"
log.level = "info"
log.maxDays = 3

auth.method = "token"
auth.token = "T***************"

subDomainHost = "47...*"

custom404Page = "/usr/local/frps/frp_erro.html"

Logs

No response

Steps to reproduce

  1. 内网服务器安装Dufs并启动
  2. 使用frp穿透出去,穿透类型为http,开启transport.proxyProtocolVersion = "v2",到达公网服务器后使用反向代理加ssl
  3. 从公网访问dufs
    ...

Affected area

  • Docs
  • Installation
  • Performance and Scalability
  • Security
  • User Experience
  • Test and Release
  • Developer Infrastructure
  • Client Plugin
  • Server Plugin
  • Extensions
  • Others
Originally created by @xiaowen-king on GitHub (Apr 7, 2025). Original GitHub issue: https://github.com/fatedier/frp/issues/4748 ### Bug Description #frp版本# 0.61.1 #穿透的服务# Dufs 穿透的服务器的项目地址:https://github.com/sigoden/dufs #环境# 公网服务器使用的阿里云香港的服务器,然后穿透到家里面,香港的服务器安装了宝塔面板,用来配置反向代理,从而实现80端口和443端口的复用 #问题# 使用的http代理,打开transport.proxyProtocolVersion = "v2"后无法访问,浏览器提示该网页无法正常运作HTTP ERROR 400,注释掉配置文件里面的transport.proxyProtocolVersion = "v2"后可以正常访问。 ### frpc Version 0.61.1 ### frps Version 0.61.1 ### System Architecture linux/amd64 ### Configurations #frpc配置文件# serverAddr = "47.**.***.**" serverPort = 5**3 user = "MP73" auth.method = "token" auth.token = "T*****J********e" transport.tls.enable = true [[proxies]] name = "文件共享" type = "http" localIP = "127.0.0.1" localPort = 5000 customDomains = ["file.ersansi.top"] transport.proxyProtocolVersion = "v2" #frps配置文件# bindAddr = "0.0.0.0" bindPort = 5*** kcpBindPort = 5*** quicBindPort = 2*** transport.tcpMux = true vhostHTTPPort = 2*** vhostHTTPSPort = 2*** webServer.addr = "0.0.0.0" webServer.port = 2*** webServer.user = "*******" webServer.password = "*************" log.to = "enable" log.level = "info" log.maxDays = 3 auth.method = "token" auth.token = "T***************" subDomainHost = "47.**.***.**" custom404Page = "/usr/local/frps/frp_erro.html" ### Logs _No response_ ### Steps to reproduce 1. 内网服务器安装Dufs并启动 2. 使用frp穿透出去,穿透类型为http,开启transport.proxyProtocolVersion = "v2",到达公网服务器后使用反向代理加ssl 3. 从公网访问dufs ... ### Affected area - [ ] Docs - [ ] Installation - [ ] Performance and Scalability - [ ] Security - [ ] User Experience - [ ] Test and Release - [ ] Developer Infrastructure - [ ] Client Plugin - [ ] Server Plugin - [ ] Extensions - [x] Others
gitea-mirror 2026-05-05 14:24:11 -06:00
Author
Owner

@yeah-zihan commented on GitHub (Apr 8, 2025):

一般来说开启proxyProtocol是需要在服务端上开启对应的proxy功能才能正常使用的,像我的mc服务器反代就需要在配置文件里设置haproxy-protocol = true玩家才能正常进行连接

<!-- gh-comment-id:2785442802 --> @yeah-zihan commented on GitHub (Apr 8, 2025): 一般来说开启proxyProtocol是需要在服务端上开启对应的proxy功能才能正常使用的,像我的mc服务器反代就需要在配置文件里设置haproxy-protocol = true玩家才能正常进行连接
Author
Owner

@yeah-zihan commented on GitHub (Apr 8, 2025):

去看了一下你提到的项目,应该是个文件服务器且没有原生支持proxy protocol。虽然不太懂文件服务器为什么需要识别用户的真实ip,但如果想的话应该是有个方案可以实现的:在frpc和你的dufs中间加一层nginx,用来把proxy protocol解析到的真实ip直接修改到http流量里

<!-- gh-comment-id:2785454286 --> @yeah-zihan commented on GitHub (Apr 8, 2025): 去看了一下你提到的项目,应该是个文件服务器且没有原生支持proxy protocol。虽然不太懂文件服务器为什么需要识别用户的真实ip,但如果想的话应该是有个方案可以实现的:在frpc和你的dufs中间加一层nginx,用来把proxy protocol解析到的真实ip直接修改到http流量里
Author
Owner

@ghostLiulang commented on GitHub (Apr 8, 2025):

用nginx 或者是HAproxy代理一下呢?
或者是询问一下文件服务开发者?

<!-- gh-comment-id:2785726541 --> @ghostLiulang commented on GitHub (Apr 8, 2025): 用nginx 或者是HAproxy代理一下呢? 或者是询问一下文件服务开发者?
Author
Owner

@gexiaopeng commented on GitHub (Apr 9, 2025):

我的也有这个问题,希望能有nginx或者其他代理的详细配置

<!-- gh-comment-id:2788113285 --> @gexiaopeng commented on GitHub (Apr 9, 2025): 我的也有这个问题,希望能有nginx或者其他代理的详细配置
Author
Owner

@yeah-zihan commented on GitHub (Apr 9, 2025):

我的也有这个问题,希望能有nginx或者其他代理的详细配置

假设现在把想转发的本地服务(楼主的为文件服务器)的开放端口修改到5090端口,frpc配置保持楼主的不变,nginx可以像这样配置来实现上面说的功能

# 代码为 AI 生成
server {
    listen 5000 proxy_protocol;  # 启用 Proxy Protocol 以接收客户端的真实 IP
    server_name file.ersansi.top;  # 设置你的域名

    location / {
        # 设置真实 IP 地址到请求头 X-Real-IP 中
        set_real_ip_from 0.0.0.0/0;  # 允许从任意来源接收真实 IP
        real_ip_header X-Real-IP;  # 设置真实 IP 的请求头
        real_ip_recursive on;  # 启用递归查找真实 IP

        # 反向代理到你的文件服务器
        proxy_pass http://127.0.0.1:5090;  # 修改为文件服务器的本地地址
        proxy_set_header Host $host;  # 保持 Host 头部
        proxy_set_header X-Real-IP $remote_addr;  # 将真实的 IP 地址添加到请求头
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # 设置 X-Forwarded-For 头部
        proxy_set_header X-Forwarded-Proto $scheme;  # 设置协议(http 或 https)
        proxy_set_header Connection '';  # 关闭连接头
    }
}
<!-- gh-comment-id:2788126600 --> @yeah-zihan commented on GitHub (Apr 9, 2025): > 我的也有这个问题,希望能有nginx或者其他代理的详细配置 假设现在把想转发的本地服务(楼主的为文件服务器)的开放端口修改到5090端口,frpc配置保持楼主的不变,nginx可以像这样配置来实现上面说的功能 ```nginx # 代码为 AI 生成 server { listen 5000 proxy_protocol; # 启用 Proxy Protocol 以接收客户端的真实 IP server_name file.ersansi.top; # 设置你的域名 location / { # 设置真实 IP 地址到请求头 X-Real-IP 中 set_real_ip_from 0.0.0.0/0; # 允许从任意来源接收真实 IP real_ip_header X-Real-IP; # 设置真实 IP 的请求头 real_ip_recursive on; # 启用递归查找真实 IP # 反向代理到你的文件服务器 proxy_pass http://127.0.0.1:5090; # 修改为文件服务器的本地地址 proxy_set_header Host $host; # 保持 Host 头部 proxy_set_header X-Real-IP $remote_addr; # 将真实的 IP 地址添加到请求头 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 设置 X-Forwarded-For 头部 proxy_set_header X-Forwarded-Proto $scheme; # 设置协议(http 或 https) proxy_set_header Connection ''; # 关闭连接头 } } ```
Author
Owner

@gexiaopeng commented on GitHub (Apr 9, 2025):

我的也有这个问题,希望能有nginx或者其他代理的详细配置

假设现在把想转发的本地服务(楼主的为文件服务器)的开放端口修改到5090端口,frpc配置保持楼主的不变,nginx可以像这样配置来实现上面说的功能

代码为 AI 生成

server {
listen 5000 proxy_protocol; # 启用 Proxy Protocol 以接收客户端的真实 IP
server_name file.ersansi.top; # 设置你的域名

location / {
    # 设置真实 IP 地址到请求头 X-Real-IP 中
    set_real_ip_from 0.0.0.0/0;  # 允许从任意来源接收真实 IP
    real_ip_header X-Real-IP;  # 设置真实 IP 的请求头
    real_ip_recursive on;  # 启用递归查找真实 IP

    # 反向代理到你的文件服务器
    proxy_pass http://127.0.0.1:5090;  # 修改为文件服务器的本地地址
    proxy_set_header Host $host;  # 保持 Host 头部
    proxy_set_header X-Real-IP $remote_addr;  # 将真实的 IP 地址添加到请求头
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # 设置 X-Forwarded-For 头部
    proxy_set_header X-Forwarded-Proto $scheme;  # 设置协议(http 或 https)
    proxy_set_header Connection '';  # 关闭连接头
}

}

frpc代理的ssh怎么样用nginx配置proxy_protocol呢? 我的 frpc配置是:
proxies
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 5005
remotePort = 52223
transport.proxyProtocolVersion = "v2"

<!-- gh-comment-id:2788131522 --> @gexiaopeng commented on GitHub (Apr 9, 2025): > > 我的也有这个问题,希望能有nginx或者其他代理的详细配置 > > 假设现在把想转发的本地服务(楼主的为文件服务器)的开放端口修改到5090端口,frpc配置保持楼主的不变,nginx可以像这样配置来实现上面说的功能 > > # 代码为 AI 生成 > server { > listen 5000 proxy_protocol; # 启用 Proxy Protocol 以接收客户端的真实 IP > server_name file.ersansi.top; # 设置你的域名 > > location / { > # 设置真实 IP 地址到请求头 X-Real-IP 中 > set_real_ip_from 0.0.0.0/0; # 允许从任意来源接收真实 IP > real_ip_header X-Real-IP; # 设置真实 IP 的请求头 > real_ip_recursive on; # 启用递归查找真实 IP > > # 反向代理到你的文件服务器 > proxy_pass http://127.0.0.1:5090; # 修改为文件服务器的本地地址 > proxy_set_header Host $host; # 保持 Host 头部 > proxy_set_header X-Real-IP $remote_addr; # 将真实的 IP 地址添加到请求头 > proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 设置 X-Forwarded-For 头部 > proxy_set_header X-Forwarded-Proto $scheme; # 设置协议(http 或 https) > proxy_set_header Connection ''; # 关闭连接头 > } > } frpc代理的ssh怎么样用nginx配置proxy_protocol呢? 我的 frpc配置是: [[proxies]] name = "ssh" type = "tcp" localIP = "127.0.0.1" localPort = 5005 remotePort = 52223 transport.proxyProtocolVersion = "v2"
Author
Owner

@ghostLiulang commented on GitHub (Apr 9, 2025):

@gexiaopeng 代理SSH的话,用HAProxy不要用nginx代理这个,会有问题,昨天我研究了一下,nginx代理之后ssh无法正常解析TCP数据包,因为SSH对数据包的格式是有要求的,SSH 协议严格要求首个数据包是 SSH-2.0-xxxx,而 Proxy Protocol 会插入额外头信息,导致协议解析失败。HAProxy 专门优化了此场景,能正确分离 Proxy 头和原始流量。但是问题是即使能够正确处理转发的流量,FRP开启了 proxy_protocolV2 转发到服务器上的地址也还是127.0.0.1,不知道是不是因为我把HAProxy 放到目标服务器上的原因.

<!-- gh-comment-id:2788149061 --> @ghostLiulang commented on GitHub (Apr 9, 2025): @gexiaopeng 代理SSH的话,用HAProxy不要用nginx代理这个,会有问题,昨天我研究了一下,nginx代理之后ssh无法正常解析TCP数据包,因为SSH对数据包的格式是有要求的,SSH 协议严格要求首个数据包是 SSH-2.0-xxxx,而 Proxy Protocol 会插入额外头信息,导致协议解析失败。HAProxy 专门优化了此场景,能正确分离 Proxy 头和原始流量。但是问题是即使能够正确处理转发的流量,FRP开启了 proxy_protocolV2 转发到服务器上的地址也还是127.0.0.1,不知道是不是因为我把HAProxy 放到目标服务器上的原因.
Author
Owner

@yeah-zihan commented on GitHub (Apr 9, 2025):

@gexiaopeng 代理SSH的话,用HAProxy不要用nginx代理这个,会有问题,昨天我研究了一下,nginx代理之后ssh无法正常解析TCP数据包,因为SSH对数据包的格式是有要求的,SSH 协议严格要求首个数据包是 SSH-2.0-xxxx,而 Proxy Protocol 会插入额外头信息,导致协议解析失败。HAProxy 专门优化了此场景,能正确分离 Proxy 头和原始流量。但是问题是即使能够正确处理转发的流量,FRP开启了 proxy_protocolV2 转发到服务器上的地址也还是127.0.0.1,不知道是不是因为我把HAProxy 放到目标服务器上的原因.

haproxy具体是怎么配置的呢?看起来是没有对tcp流量的源ip修改,所以ssh感知不到

刚才查了一下,ssh默认是不支持proxy protocol的,也就是说想实现透明代理必须得通过类似NAT这样直接对流量包的源ip/目标ip进行修改才行,会比较麻烦

但我觉得做这些之前还是得从先需求角度出发,明确一下是不是必须要获取真实ip(),毕竟如果这是一个常见需求,一般已经会有人实现了,如果没人实现大概率是有更好的解决方案,小概率才是新的需求

<!-- gh-comment-id:2788617206 --> @yeah-zihan commented on GitHub (Apr 9, 2025): > [@gexiaopeng](https://github.com/gexiaopeng) 代理SSH的话,用HAProxy不要用nginx代理这个,会有问题,昨天我研究了一下,nginx代理之后ssh无法正常解析TCP数据包,因为SSH对数据包的格式是有要求的,SSH 协议严格要求首个数据包是 SSH-2.0-xxxx,而 Proxy Protocol 会插入额外头信息,导致协议解析失败。HAProxy 专门优化了此场景,能正确分离 Proxy 头和原始流量。但是问题是即使能够正确处理转发的流量,FRP开启了 proxy_protocolV2 转发到服务器上的地址也还是127.0.0.1,不知道是不是因为我把HAProxy 放到目标服务器上的原因. haproxy具体是怎么配置的呢?看起来是没有对tcp流量的源ip修改,所以ssh感知不到 刚才查了一下,ssh默认是不支持proxy protocol的,也就是说想实现透明代理必须得通过类似NAT这样直接对流量包的源ip/目标ip进行修改才行,会比较麻烦 但我觉得做这些之前还是得从先需求角度出发,明确一下是不是必须要获取真实ip(),毕竟如果这是一个常见需求,一般已经会有人实现了,如果没人实现大概率是有更好的解决方案,小概率才是新的需求
Author
Owner

@ghostLiulang commented on GitHub (Apr 9, 2025):

@gexiaopeng 代理SSH的话,用HAProxy不要用nginx代理这个,会有问题,昨天我研究了一下,nginx代理之后ssh无法正常解析TCP数据包,因为SSH对数据包的格式是有要求的,SSH 协议严格要求首个数据包是 SSH-2.0-xxxx,而 Proxy Protocol 会插入额外头信息,导致协议解析失败。HAProxy 专门优化了此场景,能正确分离 Proxy 头和原始流量。但是问题是即使能够正确处理转发的流量,FRP开启了 proxy_protocolV2 转发到服务器上的地址也还是127.0.0.1,不知道是不是因为我把HAProxy 放到目标服务器上的原因.

haproxy具体是怎么配置的呢?看起来是没有对tcp流量的源ip修改,所以ssh感知不到

刚才查了一下,ssh默认是不支持proxy protocol的,也就是说想实现透明代理必须得通过类似NAT这样直接对流量包的源ip/目标ip进行修改才行,会比较麻烦

但我觉得做这些之前还是得从先需求角度出发,明确一下是不是必须要获取真实ip(),毕竟如果这是一个常见需求,一般已经会有人实现了,如果没人实现大概率是有更好的解决方案,小概率才是新的需求

frontend ssh_proxy
    bind :1122 accept-proxy  # 启用 Proxy Protocol
    mode tcp
    default_backend ssh_real

backend ssh_real
    mode tcp
    server ssh_local 127.0.0.1:22

deepseek 是这么写的,我试了一下,这样是可以正确转发流量到SSH并且能够正常访问,但是网速会差一些. 如果只是为了避免网络攻击的话,建议使用STCP或者是XTCP来做防护. 安全和便捷总是要有取舍的.

<!-- gh-comment-id:2788648390 --> @ghostLiulang commented on GitHub (Apr 9, 2025): > > [@gexiaopeng](https://github.com/gexiaopeng) 代理SSH的话,用HAProxy不要用nginx代理这个,会有问题,昨天我研究了一下,nginx代理之后ssh无法正常解析TCP数据包,因为SSH对数据包的格式是有要求的,SSH 协议严格要求首个数据包是 SSH-2.0-xxxx,而 Proxy Protocol 会插入额外头信息,导致协议解析失败。HAProxy 专门优化了此场景,能正确分离 Proxy 头和原始流量。但是问题是即使能够正确处理转发的流量,FRP开启了 proxy_protocolV2 转发到服务器上的地址也还是127.0.0.1,不知道是不是因为我把HAProxy 放到目标服务器上的原因. > > haproxy具体是怎么配置的呢?看起来是没有对tcp流量的源ip修改,所以ssh感知不到 > > 刚才查了一下,ssh默认是不支持proxy protocol的,也就是说想实现透明代理必须得通过类似NAT这样直接对流量包的源ip/目标ip进行修改才行,会比较麻烦 > > 但我觉得做这些之前还是得从先需求角度出发,明确一下是不是必须要获取真实ip(),毕竟如果这是一个常见需求,一般已经会有人实现了,如果没人实现大概率是有更好的解决方案,小概率才是新的需求 ```bash frontend ssh_proxy bind :1122 accept-proxy # 启用 Proxy Protocol mode tcp default_backend ssh_real backend ssh_real mode tcp server ssh_local 127.0.0.1:22 ``` deepseek 是这么写的,我试了一下,这样是可以正确转发流量到SSH并且能够正常访问,但是网速会差一些. 如果只是为了避免网络攻击的话,建议使用STCP或者是XTCP来做防护. 安全和便捷总是要有取舍的.
Author
Owner

@yeah-zihan commented on GitHub (Apr 9, 2025):

frontend ssh_proxy
bind :1122 accept-proxy # 启用 Proxy Protocol
mode tcp
default_backend ssh_real

backend ssh_real
mode tcp
server ssh_local 127.0.0.1:22
deepseek 是这么写的,我试了一下,这样是可以正确转发流量到SSH并且能够正常访问,但是网速会差一些. 如果只是为了避免网络攻击的话,建议使用STCP或者是XTCP来做防护. 安全和便捷总是要有取舍的.

这个写法的话,只是简单的把解析完的流量转发到相应ssh端口,实际效果等效于没开proxy protocol且直接把frp接到ssh服务上,而且因为多了一层代理访问速度还会变慢

如果是想要更安全,可以在中间代理层做ip过滤防护,安全与否和ssh能否直接获取到真实ip其实关系不大

<!-- gh-comment-id:2788663278 --> @yeah-zihan commented on GitHub (Apr 9, 2025): > frontend ssh_proxy > bind :1122 accept-proxy # 启用 Proxy Protocol > mode tcp > default_backend ssh_real > > backend ssh_real > mode tcp > server ssh_local 127.0.0.1:22 > deepseek 是这么写的,我试了一下,这样是可以正确转发流量到SSH并且能够正常访问,但是网速会差一些. 如果只是为了避免网络攻击的话,建议使用STCP或者是XTCP来做防护. 安全和便捷总是要有取舍的. 这个写法的话,只是简单的把解析完的流量转发到相应ssh端口,实际效果等效于没开proxy protocol且直接把frp接到ssh服务上,而且因为多了一层代理访问速度还会变慢 如果是想要更安全,可以在中间代理层做ip过滤防护,安全与否和ssh能否直接获取到真实ip其实关系不大
Author
Owner

@gexiaopeng commented on GitHub (Apr 9, 2025):

对于frpc的http代理,没有必要加 transport.proxyProtocolVersion = "v2",只要请求 header 中带 X-Forwarded-For 就可以,我测试都正常的。

<!-- gh-comment-id:2788863424 --> @gexiaopeng commented on GitHub (Apr 9, 2025): 对于frpc的http代理,没有必要加 transport.proxyProtocolVersion = "v2",只要请求 header 中带 X-Forwarded-For 就可以,我测试都正常的。
Author
Owner

@github-actions[bot] commented on GitHub (Apr 24, 2025):

Issues go stale after 14d of inactivity. Stale issues rot after an additional 3d of inactivity and eventually close.

<!-- gh-comment-id:2825855353 --> @github-actions[bot] commented on GitHub (Apr 24, 2025): Issues go stale after 14d of inactivity. Stale issues rot after an additional 3d of inactivity and eventually close.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/frp#3753
No description provided.