[GH-ISSUE #4886] [Feature Request] 请问一下,httpproxy代理给FRPS获取不到真实IP #3854

Closed
opened 2026-05-05 14:27:49 -06:00 by gitea-mirror · 9 comments
Owner

Originally created by @metplato on GitHub (Jul 19, 2025).
Original GitHub issue: https://github.com/fatedier/frp/issues/4886

先解释下一下我为什么要安装一个httpproxy来转发,因为外网用户直接访问FRP暴露的公网端口,来源IP全部是127.0.0.1,就有一个巨大安全隐患,SYN洪水攻击没法过滤,全部是本地同一个地址,过滤掉的话正常业务就会中断,所以我需要一个httpproxy获取真实IP转发给FRPS,如果有SYN洪水攻击,我可以进行过滤

httpproxy转发给FRPS的端口,获取不到真实IP
下面是我httpproxy的配置,这样子FRPS接收不到
如果去除accept-proxy send-proxy-v2便可以转发,但是不是公网IP
`frontend frp_frontend
bind :51999 accept-proxy
mode tcp
option tcplog
use_backend bk_51999

backend bk_51999
mode tcp
server FRP21999 127.0.0.1:21999 send-proxy-v2`

这是FRP服务端的配置,请问服务端需要单独开启什么?服务端版本0.63.0

bindAddr = "0.0.0.0"
bindPort = 17000

auth.method = "token"
auth.token = "60d8a83c544e6168db@!123"

webServer.addr = "0.0.0.0"
webServer.port = 17500
webServer.user = "admin"
webServer.password = "qsssss"

Originally created by @metplato on GitHub (Jul 19, 2025). Original GitHub issue: https://github.com/fatedier/frp/issues/4886 先解释下一下我为什么要安装一个httpproxy来转发,因为外网用户直接访问FRP暴露的公网端口,来源IP全部是127.0.0.1,就有一个巨大安全隐患,SYN洪水攻击没法过滤,全部是本地同一个地址,过滤掉的话正常业务就会中断,所以我需要一个httpproxy获取真实IP转发给FRPS,如果有SYN洪水攻击,我可以进行过滤 httpproxy转发给FRPS的端口,获取不到真实IP 下面是我httpproxy的配置,这样子FRPS接收不到 如果去除accept-proxy send-proxy-v2便可以转发,但是不是公网IP `frontend frp_frontend bind :51999 accept-proxy mode tcp option tcplog use_backend bk_51999 backend bk_51999 mode tcp server FRP21999 127.0.0.1:21999 send-proxy-v2` 这是FRP服务端的配置,请问服务端需要单独开启什么?服务端版本0.63.0 bindAddr = "0.0.0.0" bindPort = 17000 auth.method = "token" auth.token = "60d8a83c544e6168db@!123" webServer.addr = "0.0.0.0" webServer.port = 17500 webServer.user = "admin" webServer.password = "qsssss"
gitea-mirror 2026-05-05 14:27:49 -06:00
Author
Owner

@recolic commented on GitHub (Jul 20, 2025):

我刚刚解决一个类似的问题。就用自带的https2http 或者 https2https就可以,它会设置x forwarded for header, 然后在你的nginx或其他服务器log里面打出来就好了。

服务端啥配置都不用,客户端类似这样

[[proxies]]
name = "my_service"
type = "https"
customDomains = ["xx.example.com"]
[proxies.plugin]
type = "https2https"
localAddr = "127.0.0.1:443"        # your first local HTTPS server
crtPath = "/srv/conf/acme-sh/xxx.net/fullchain.cer"
keyPath = "/srv/conf/acme-sh/xxx.net/drive.recolic.net.key"
#skipVerify = true                  # ignore local HTTPS cert errors
#hostHeaderRewrite = "127.0.0.1"    # optional

然后这个header自然就会有

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "PROXY=$http_x_forwarded_for"';

        access_log /var/log/nginx/access.log main;
<!-- gh-comment-id:3092666425 --> @recolic commented on GitHub (Jul 20, 2025): 我刚刚解决一个类似的问题。就用自带的https2http 或者 https2https就可以,它会设置x forwarded for header, 然后在你的nginx或其他服务器log里面打出来就好了。 服务端啥配置都不用,客户端类似这样 ``` [[proxies]] name = "my_service" type = "https" customDomains = ["xx.example.com"] [proxies.plugin] type = "https2https" localAddr = "127.0.0.1:443" # your first local HTTPS server crtPath = "/srv/conf/acme-sh/xxx.net/fullchain.cer" keyPath = "/srv/conf/acme-sh/xxx.net/drive.recolic.net.key" #skipVerify = true # ignore local HTTPS cert errors #hostHeaderRewrite = "127.0.0.1" # optional ``` 然后这个header自然就会有 ``` log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "PROXY=$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; ```
Author
Owner

@metplato commented on GitHub (Jul 20, 2025):

我刚刚解决一个类似的问题。就用自带的https2http 或者 https2https就可以,它会设置x forwarded for header, 然后在你的nginx或其他服务器log里面打出来就好了。

服务端啥配置都不用,客户端类似这样

[[proxies]]
name = "my_service"
type = "https"
customDomains = ["xx.example.com"]
[proxies.plugin]
type = "https2https"
localAddr = "127.0.0.1:443"        # your first local HTTPS server
crtPath = "/srv/conf/acme-sh/xxx.net/fullchain.cer"
keyPath = "/srv/conf/acme-sh/xxx.net/drive.recolic.net.key"
#skipVerify = true                  # ignore local HTTPS cert errors
#hostHeaderRewrite = "127.0.0.1"    # optional

然后这个header自然就会有

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "PROXY=$http_x_forwarded_for"';

        access_log /var/log/nginx/access.log main;

谢谢你!这种方式支持TCP批量端口段吗?我查看了文档,好像不支持TCP这样操作

<!-- gh-comment-id:3094221957 --> @metplato commented on GitHub (Jul 20, 2025): > 我刚刚解决一个类似的问题。就用自带的https2http 或者 https2https就可以,它会设置x forwarded for header, 然后在你的nginx或其他服务器log里面打出来就好了。 > > 服务端啥配置都不用,客户端类似这样 > > ``` > [[proxies]] > name = "my_service" > type = "https" > customDomains = ["xx.example.com"] > [proxies.plugin] > type = "https2https" > localAddr = "127.0.0.1:443" # your first local HTTPS server > crtPath = "/srv/conf/acme-sh/xxx.net/fullchain.cer" > keyPath = "/srv/conf/acme-sh/xxx.net/drive.recolic.net.key" > #skipVerify = true # ignore local HTTPS cert errors > #hostHeaderRewrite = "127.0.0.1" # optional > ``` > > 然后这个header自然就会有 > > ``` > log_format main '$remote_addr - $remote_user [$time_local] "$request" ' > '$status $body_bytes_sent "$http_referer" ' > '"$http_user_agent" "PROXY=$http_x_forwarded_for"'; > > access_log /var/log/nginx/access.log main; > ``` 谢谢你!这种方式支持TCP批量端口段吗?我查看了文档,好像不支持TCP这样操作
Author
Owner

@metplato commented on GitHub (Jul 20, 2025):

现在有个很严重的问题,就是代理的TCP端口,只要知道这个公网TCP端口,随便发一点SYN包,连接池就占满了,根本无法过滤,因为来自IP全是本机127.0.0.1
如果过滤127.0.01,那么会把自己也过滤掉了

<!-- gh-comment-id:3094294495 --> @metplato commented on GitHub (Jul 20, 2025): 现在有个很严重的问题,就是代理的TCP端口,只要知道这个公网TCP端口,随便发一点SYN包,连接池就占满了,根本无法过滤,因为来自IP全是本机127.0.0.1 如果过滤127.0.01,那么会把自己也过滤掉了
Author
Owner

@recolic commented on GitHub (Jul 20, 2025):

现在有个很严重的问题,就是代理的TCP端口,只要知道这个公网TCP端口,随便发一点SYN包,连接池就占满了,根本无法过滤,因为来自IP全是本机127.0.0.1 如果过滤127.0.01,那么会把自己也过滤掉了

你这种情况,我一般是在后端(nginx)那边看看log,然后去frps那边把他的ip block了。
如果frps服务器不是你的... 那或许你可以让nginx config里面检查这个x forwarded for header,如果match到某个ip就立即返回403,这样tcp conn会被立即断掉。

<!-- gh-comment-id:3094436988 --> @recolic commented on GitHub (Jul 20, 2025): > 现在有个很严重的问题,就是代理的TCP端口,只要知道这个公网TCP端口,随便发一点SYN包,连接池就占满了,根本无法过滤,因为来自IP全是本机127.0.0.1 如果过滤127.0.01,那么会把自己也过滤掉了 你这种情况,我一般是在后端(nginx)那边看看log,然后去frps那边把他的ip block了。 如果frps服务器不是你的... 那或许你可以让nginx config里面检查这个x forwarded for header,如果match到某个ip就立即返回403,这样tcp conn会被立即断掉。
Author
Owner

@metplato commented on GitHub (Jul 20, 2025):

现在有个很严重的问题,就是代理的TCP端口,只要知道这个公网TCP端口,随便发一点SYN包,连接池就占满了,根本无法过滤,因为来自IP全是本机127.0.0.1 如果过滤127.0.01,那么会把自己也过滤掉了

你这种情况,我一般是在后端(nginx)那边看看log,然后去frps那边把他的ip block了。 如果frps服务器不是你的... 那或许你可以让nginx config里面检查这个x forwarded for header,如果match到某个ip就立即返回403,这样tcp conn会被立即断掉。

手工的方式我知道,我是转发的数据是TCP游戏服务,FRPS实时转发给我游戏网关的数据是全部来自127..0.0.1,我游戏网关没法去BLOCK,因为只有一个127.0.0.1,并无真实IP

或者我换个简单的表达方式:
FRPS能不能直接透传真实IP给后端服务?

<!-- gh-comment-id:3094453044 --> @metplato commented on GitHub (Jul 20, 2025): > > 现在有个很严重的问题,就是代理的TCP端口,只要知道这个公网TCP端口,随便发一点SYN包,连接池就占满了,根本无法过滤,因为来自IP全是本机127.0.0.1 如果过滤127.0.01,那么会把自己也过滤掉了 > > 你这种情况,我一般是在后端(nginx)那边看看log,然后去frps那边把他的ip block了。 如果frps服务器不是你的... 那或许你可以让nginx config里面检查这个x forwarded for header,如果match到某个ip就立即返回403,这样tcp conn会被立即断掉。 手工的方式我知道,我是转发的数据是TCP游戏服务,FRPS实时转发给我游戏网关的数据是全部来自127..0.0.1,我游戏网关没法去BLOCK,因为只有一个127.0.0.1,并无真实IP 或者我换个简单的表达方式: FRPS能不能直接透传真实IP给后端服务?
Author
Owner

@recolic commented on GitHub (Jul 20, 2025):

现在有个很严重的问题,就是代理的TCP端口,只要知道这个公网TCP端口,随便发一点SYN包,连接池就占满了,根本无法过滤,因为来自IP全是本机127.0.0.1 如果过滤127.0.01,那么会把自己也过滤掉了

你这种情况,我一般是在后端(nginx)那边看看log,然后去frps那边把他的ip block了。 如果frps服务器不是你的... 那或许你可以让nginx config里面检查这个x forwarded for header,如果match到某个ip就立即返回403,这样tcp conn会被立即断掉。

手工的方式我知道,我是转发的数据是TCP游戏服务,FRPS实时转发给我游戏网关的数据是全部来自127..0.0.1,我游戏网关没法去BLOCK,因为只有一个127.0.0.1,并无真实IP

或者我换个简单的表达方式: FRPS能不能直接透传真实IP给后端服务?

TCP的话... 据我所知是没办法的。
我只是一个普通frp用户,可以看看其他人(例如贡献者)有没有建议。

<!-- gh-comment-id:3094810226 --> @recolic commented on GitHub (Jul 20, 2025): > > > 现在有个很严重的问题,就是代理的TCP端口,只要知道这个公网TCP端口,随便发一点SYN包,连接池就占满了,根本无法过滤,因为来自IP全是本机127.0.0.1 如果过滤127.0.01,那么会把自己也过滤掉了 > > > > > > 你这种情况,我一般是在后端(nginx)那边看看log,然后去frps那边把他的ip block了。 如果frps服务器不是你的... 那或许你可以让nginx config里面检查这个x forwarded for header,如果match到某个ip就立即返回403,这样tcp conn会被立即断掉。 > > 手工的方式我知道,我是转发的数据是TCP游戏服务,FRPS实时转发给我游戏网关的数据是全部来自127..0.0.1,我游戏网关没法去BLOCK,因为只有一个127.0.0.1,并无真实IP > > 或者我换个简单的表达方式: FRPS能不能直接透传真实IP给后端服务? TCP的话... 据我所知是没办法的。 我只是一个普通frp用户,可以看看其他人(例如贡献者)有没有建议。
Author
Owner

@github-actions[bot] commented on GitHub (Aug 4, 2025):

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

<!-- gh-comment-id:3148830755 --> @github-actions[bot] commented on GitHub (Aug 4, 2025): Issues go stale after 14d of inactivity. Stale issues rot after an additional 3d of inactivity and eventually close.
Author
Owner

@fsj2009yx commented on GitHub (Aug 6, 2025):

现在有个很严重的问题,就是代理的TCP端口,只要知道这个公网TCP端口,随便发一点SYN包,连接池就占满了,根本无法过滤,因为来自IP全是本机127.0.0.1 如果过滤127.0.01,那么会把自己也过滤掉了

你这种情况,我一般是在后端(nginx)那边看看log,然后去frps那边把他的ip block了。 如果frps服务器不是你的... 那或许你可以让nginx config里面检查这个x forwarded for header,如果match到某个ip就立即返回403,这样tcp conn会被立即断掉。

手工的方式我知道,我是转发的数据是TCP游戏服务,FRPS实时转发给我游戏网关的数据是全部来自127..0.0.1,我游戏网关没法去BLOCK,因为只有一个127.0.0.1,并无真实IP

或者我换个简单的表达方式: FRPS能不能直接透传真实IP给后端服务?

可以配置proxy protocol,但是需要你的游戏服务端支持该协议

<!-- gh-comment-id:3158709874 --> @fsj2009yx commented on GitHub (Aug 6, 2025): > > > 现在有个很严重的问题,就是代理的TCP端口,只要知道这个公网TCP端口,随便发一点SYN包,连接池就占满了,根本无法过滤,因为来自IP全是本机127.0.0.1 如果过滤127.0.01,那么会把自己也过滤掉了 > > > > > > 你这种情况,我一般是在后端(nginx)那边看看log,然后去frps那边把他的ip block了。 如果frps服务器不是你的... 那或许你可以让nginx config里面检查这个x forwarded for header,如果match到某个ip就立即返回403,这样tcp conn会被立即断掉。 > > 手工的方式我知道,我是转发的数据是TCP游戏服务,FRPS实时转发给我游戏网关的数据是全部来自127..0.0.1,我游戏网关没法去BLOCK,因为只有一个127.0.0.1,并无真实IP > > 或者我换个简单的表达方式: FRPS能不能直接透传真实IP给后端服务? 可以配置proxy protocol,但是需要你的游戏服务端支持该协议
Author
Owner

@github-actions[bot] commented on GitHub (Aug 22, 2025):

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

<!-- gh-comment-id:3212576459 --> @github-actions[bot] commented on GitHub (Aug 22, 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#3854
No description provided.