SafeLine icon indicating copy to clipboard operation
SafeLine copied to clipboard

[建议] 支持接收PROXY Protocol,方便的获取真实IP

Open cddqssc opened this issue 1 year ago • 15 comments

背景与遇到的问题

当waf的上游是端口转发(例如frp)或者负载均衡器的时候,waf无法获取真实IP,NGINX的PROXY Protocol就是解决这个问题的:https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/

建议的解决方案

实际上很简单:根据nginx文档只需要添加proxy_protocol字段到监听的端口后面,就能获取真实IP了 server { listen 80 proxy_protocol; listen 443 ssl proxy_protocol #... } 目前手动修改配置文件服务重启会被覆盖,也无法在custom的config添加这个字段 建议:能不能UI加一个选项,然后就能在配置文件中加上这个proxy_protocol

cddqssc avatar Oct 07 '23 13:10 cddqssc

目前waf可以从http header中获取真实IP(X-Real-IP),但是这样不太优雅,因为如果上游没有传递X-Real-IP(例如端口转发),就获取不到真实IP。而如果使用proxy_protocol,waf就能直接从网络连接中获取真实IP

cddqssc avatar Oct 07 '23 13:10 cddqssc

通过 Header 传递真实 IP 是 HTTP 下的标准解决方案,七层负载一般都支持,咋会不优雅。

proxy protocol 只在纯四层负载的情况下有意义,而且也不是很常用的方案(大多直接从网络层转发,不需要处理 IP。网络环境不支持的话也直接上七层负载),处理 SMTP、POP3、IMAP 这些协议的时候可能会用到,对代理 HTTP 的 WAF 来说使用场景似乎比较有限呀。

Lorna0 avatar Oct 11 '23 03:10 Lorna0

通过 Header 传递真实 IP 是 HTTP 下的标准解决方案,七层负载一般都支持,咋会不优雅。

proxy protocol 只在纯四层负载的情况下有意义,而且也不是很常用的方案(大多直接从网络层转发,不需要处理 IP。网络环境不支持的话也直接上七层负载),处理 SMTP、POP3、IMAP 这些协议的时候可能会用到,对代理 HTTP 的 WAF 来说使用场景似乎比较有限呀。

举个例子: 用户通过HTTPS访问服务器,服务器把HTTPS流量通过端口转发(或者负载均衡器)给WAF,如下图 image

这个时候,Header里面没有真实IP,WAF获取不到真实IP。想要在header里面添加XFF,就要在转发那一层解密后添加XFF后再传递给WAF,这样全程就不是HTTPS了,就造成了不安全因素,而且麻烦。 我希望到waf之前的流量全程都是HTTPS,然后WAF来解密处理,而且waf仅仅是添加一个proxy protocol就能获取真实IP,既安全又方便。

这种场景可能并不常见,但是也不能说很稀有吧,端口转发/负载均衡应该也是比较常见的吧?waf文档里面是支持这样的接入方式的,并且添加这个功能比较容易。

cddqssc avatar Oct 11 '23 04:10 cddqssc

通过 Header 传递真实 IP 是 HTTP 下的标准解决方案,七层负载一般都支持,咋会不优雅。 proxy protocol 只在纯四层负载的情况下有意义,而且也不是很常用的方案(大多直接从网络层转发,不需要处理 IP。网络环境不支持的话也直接上七层负载),处理 SMTP、POP3、IMAP 这些协议的时候可能会用到,对代理 HTTP 的 WAF 来说使用场景似乎比较有限呀。

举个例子: 用户通过HTTPS访问服务器,服务器把HTTPS流量通过端口转发(或者负载均衡器)给WAF,如下图 image

这个时候,Header里面没有真实IP,WAF获取不到真实IP。想要在header里面添加XFF,就要在转发那一层解密后添加XFF后再传递给WAF,这样全程就不是HTTPS了,就造成了不安全因素,而且麻烦。 我希望到waf之前的流量全程都是HTTPS,然后WAF来解密处理,而且waf仅仅是添加一个proxy protocol就能获取真实IP,既安全又方便。

这种场景可能并不常见,但是也不能说很稀有吧,端口转发/负载均衡应该也是比较常见的吧?waf文档里面是支持这样的接入方式的,并且添加这个功能比较容易。

如果是图上的这种方式,就算waf支持pp协议,从转口转发过来的数据如果做了源地址转换,waf是不是也无法获取到客户端的真实ip地址?

ac-sc avatar Oct 29 '23 09:10 ac-sc

在header里面添加XFF,再以https转给waf,这中间还是可以是加密的

Trenck avatar Oct 31 '23 10:10 Trenck

在header里面添加XFF,再以https转给waf,这中间还是可以是加密的

你是认真的吗?

cddqssc avatar Oct 31 '23 10:10 cddqssc

在header里面添加XFF,再以https转给waf,这中间还是可以是加密的

你是认真的吗?

一般正式网站确实是这样部的,最外层的设备放证书,源 IP 信息用 XFF 或 X-Real-IP 来传递。中间需要全程加密的话,就都走 HTTPS。例如证书放 CDN 上,CDN 给源站生成一个自己信任的自签证书,然后用 https 连源站,这样全程都是 HTTPS。

对于负载均衡来说,web 流量的目的端口都是 80,站点信息是放在 host 里,解了密才知道是哪个站。有时候还需要根据URL、UA 等进行负载,这些都需要解密。如果没有这些需求,想只通过目的端口进行转发,那也可以直接四层路由来转发和负载,比七层代理的方案性能还高些,所以一般正式网站的负载均衡都会解密。Proxy protocol 主要是用来代理 SMTP、POP3、IMAP 这些 TCP 协议,代理网站的情况比较少见。

我盲猜你的情况是个人自建了很多 TCP 服务,包括一个 http 服务,然后想要统一通过负载代理出去?这种情况企业级 waf 确实几乎没有,可能是社区版特有需求吧,看看大家反馈。

Lorna0 avatar Nov 06 '23 08:11 Lorna0

在header里面添加XFF,再以https转给waf,这中间还是可以是加密的

你是认真的吗?

一般正式网站确实是这样部的,最外层的设备放证书,源 IP 信息用 XFF 或 X-Real-IP 来传递。中间需要全程加密的话,就都走 HTTPS。例如证书放 CDN 上,CDN 给源站生成一个自己信任的自签证书,然后用 https 连源站,这样全程都是 HTTPS。

对于负载均衡来说,web 流量的目的端口都是 80,站点信息是放在 host 里,解了密才知道是哪个站。有时候还需要根据URL、UA 等进行负载,这些都需要解密。如果没有这些需求,想只通过目的端口进行转发,那也可以直接四层路由来转发和负载,比七层代理的方案性能还高些,所以一般正式网站的负载均衡都会解密。Proxy protocol 主要是用来代理 SMTP、POP3、IMAP 这些 TCP 协议,代理网站的情况比较少见。

我盲猜你的情况是个人自建了很多 TCP 服务,包括一个 http 服务,然后想要统一通过负载代理出去?这种情况企业级 waf 确实几乎没有,可能是社区版特有需求吧,看看大家反馈。

感谢答复,这个问题对我个人来说已经解决,之前不太清楚如何手动编辑conf文件,修改后老是自动被覆盖。 现在已经手动修改了,并且可以正常运行了,需要此功能的可以参考如何修改conf文件:https://waf-ce.chaitin.cn/docs/faq/other

cddqssc avatar Nov 06 '23 10:11 cddqssc

在header里面添加XFF,再以https转给waf,这中间还是可以是加密的

你是认真的吗?

一般正式网站确实是这样部的,最外层的设备放证书,源 IP 信息用 XFF 或 X-Real-IP 来传递。中间需要全程加密的话,就都走 HTTPS。例如证书放 CDN 上,CDN 给源站生成一个自己信任的自签证书,然后用 https 连源站,这样全程都是 HTTPS。 对于负载均衡来说,web 流量的目的端口都是 80,站点信息是放在 host 里,解了密才知道是哪个站。有时候还需要根据URL、UA 等进行负载,这些都需要解密。如果没有这些需求,想只通过目的端口进行转发,那也可以直接四层路由来转发和负载,比七层代理的方案性能还高些,所以一般正式网站的负载均衡都会解密。Proxy protocol 主要是用来代理 SMTP、POP3、IMAP 这些 TCP 协议,代理网站的情况比较少见。 我盲猜你的情况是个人自建了很多 TCP 服务,包括一个 http 服务,然后想要统一通过负载代理出去?这种情况企业级 waf 确实几乎没有,可能是社区版特有需求吧,看看大家反馈。

感谢答复,这个问题对我个人来说已经解决,之前不太清楚如何手动编辑conf文件,修改后老是自动被覆盖。 现在已经手动修改了,并且可以正常运行了,需要此功能的可以参考如何修改conf文件:https://waf-ce.chaitin.cn/docs/faq/other

谢谢,我也正在找这个解决方法。

guorenxi avatar Dec 04 '23 09:12 guorenxi

在header里面添加XFF,再以https转给waf,这中间还是可以是加密的

你是认真的吗

gospider007 avatar Dec 15 '23 06:12 gospider007

在header里面添加XFF,再以https转给waf,这中间还是可以是加密的

你是认真的吗?

一般正式网站确实是这样部的,最外层的设备放证书,源 IP 信息用 XFF 或 X-Real-IP 来传递。中间需要全程加密的话,就都走 HTTPS。例如证书放 CDN 上,CDN 给源站生成一个自己信任的自签证书,然后用 https 连源站,这样全程都是 HTTPS。 对于负载均衡来说,web 流量的目的端口都是 80,站点信息是放在 host 里,解了密才知道是哪个站。有时候还需要根据URL、UA 等进行负载,这些都需要解密。如果没有这些需求,想只通过目的端口进行转发,那也可以直接四层路由来转发和负载,比七层代理的方案性能还高些,所以一般正式网站的负载均衡都会解密。Proxy protocol 主要是用来代理 SMTP、POP3、IMAP 这些 TCP 协议,代理网站的情况比较少见。 我盲猜你的情况是个人自建了很多 TCP 服务,包括一个 http 服务,然后想要统一通过负载代理出去?这种情况企业级 waf 确实几乎没有,可能是社区版特有需求吧,看看大家反馈。

感谢答复,这个问题对我个人来说已经解决,之前不太清楚如何手动编辑conf文件,修改后老是自动被覆盖。 现在已经手动修改了,并且可以正常运行了,需要此功能的可以参考如何修改conf文件:https://waf-ce.chaitin.cn/docs/faq/other

proxy protocol 好像只能在server中修改listen设置,location下怎么处理呢,能给个配置参考一下吗,谢谢~

wuyue92tree avatar Mar 15 '24 02:03 wuyue92tree

目前我也碰到这个问题,希望能找到支持接收PROXY Protocol获取真实ip。希望后续能得到支持

1447262390 avatar Apr 09 '24 02:04 1447262390

楼主是怎么修改的nginx 模版文件支持 proxy protocol 能说明下吗?

zlq1503 avatar Jun 27 '24 07:06 zlq1503

楼主是怎么修改的nginx 模版文件支持 proxy protocol 能说明下吗?

找到一个 博客 里有教程,但是使用的是自建的FRP,也许需要挑着看,~~我也在找解决方法。~~

目前使用一个简单的办法解决这个问题:

  1. 在FRP服务商/自建FRP设 修改设置,使得它们使用 proxy_protocol_version = V2 协议来进行访问,否则你的访问会出现问题且能在NGINX error.log 里看到 broken header 字样
  2. 在机器内额外增加一个NGINX作为前置反代,端口避免使用80/443 (雷池默认监听,会冲突)
  3. 将流量使用HTTP反代理到本地的雷池(localhost:80),同时listen块增加proxy_protocol,并且增加proxy_set_header X-Real-IP $proxy_protocol_addr;
  4. 雷池修改获取IP地址的地方为 X-Real-IP

虽然稍微麻烦但是大概解决了问题,能看到地图上中国的地方出现颜色了。

QLozin avatar Jun 29 '24 06:06 QLozin

我也遇到了这个问题(我是FRP),我的解决方案是:每次启动WAF后手动修改配置文件IF_backend_XX,在配置里增加

server {
    listen 0.0.0.0:9444 ssl http2 proxy_protocol;
    listen [::]:9444 ssl http2 proxy_protocol;
}

修改完后,使用命令重新waf的nginx:

docker exec safeline-tengine nginx -s reload

能用,也是麻烦,期待支持这个特性,就和支持http2一样,应该难度不大吧。

sollyu avatar Aug 13 '24 09:08 sollyu

+1

shengjidaguai2 avatar Aug 26 '24 09:08 shengjidaguai2

为了解决frp+safeline 获取真实ip问题,我写了相关教程及脚本,一键添加或取消proxy_protocol 的支持,同时支持白名单,对加白的不做任何操作,希望能帮助更多这种环境下为传透真实ip而头疼的用户 https://joplinserver.chengyuyu.top/shares/dfZ3BIqY6MjKXysA0ZRJpl

1447262390 avatar Sep 13 '24 08:09 1447262390

问题建议反馈请移步 https://rivers.chaitin.cn/discussion

xbingW avatar Sep 19 '24 06:09 xbingW