XTLS / Xray-core

Xray, Penetrates Everything. Also the best v2ray-core, with XTLS support. Fully compatible configuration.
https://t.me/projectXray
Mozilla Public License 2.0
24.19k stars 3.81k forks source link

使用Nginx监听443,用HTTPUpgrade到Xray时,Xray接收到的访问者IP为127.0.0.1 #3167

Closed chika0801 closed 5 months ago

chika0801 commented 5 months ago

补充:不用cdn时。

Nginx监听443端口 配置

Xray服务端 配置

Xray客户端和服务端文件都使用 [Update HTTPUpgrade spelling and proto]https://github.com/XTLS/Xray-core/commit/657c5c857080e4b5a00b7456ab96c47c2aa7d40f 版本

Xray服务端日志显示如下。

root@host-172-16-0-141:~# journalctl -u xray -o cat -f
2024/03/21 14:18:47 tcp:127.0.0.1:47544 accepted tcp:103.124.1.250:8080 [direct]
2024/03/21 14:18:50 tcp:127.0.0.1:47544 accepted tcp:203.10.99.1:8080 [direct]
2024/03/21 14:18:52 tcp:127.0.0.1:47528 accepted tcp:alive.github.com:443 [direct]

Nginx的access.log日志中是有访问者的真实IP的。

如果保持Nginx配置不变,将Xray配置换成 WebSocket-TLS配置 形式,127.0.0.1是显示的客户端访问者的真实IP。

PS测试了sing-box当服务端配置时,Nginx配置不变,sing-box日志中能显示访问者真实IP。

Fangliding commented 5 months ago

em 大概是proxyprotocol没有正确处理

egg1234 commented 5 months ago

其实xray处理nginx反代grpc也是显示接收127.0.0.1的访问而不能显示真实访问者ip,即使nginx按照R大的样板配置也一样,记得这个问题之前有开过issue,但后来也是不了了之

chika0801 commented 5 months ago

其实xray处理nginx反代grpc也是显示接收127.0.0.1的访问而不能显示真实访问者ip,即使nginx按照R大的样板配置也一样,记得这个问题之前有开过issue,但后来也是不了了之

我用的这套配置 https://github.com/chika0801/Xray-examples/tree/main/VLESS-gRPC-TLS

测试了 Xray日志中显示了访问者的真实IP。

egg1234 commented 5 months ago

@chika0801 谢谢回复!

因为xray 1.8.4服务器搭建后很久没有用这个协议连接了,测试了一下xray服务日志显示的是CF的ip,因为套了CF, 这个服务器的nginx配置里面已经有“grpc_set_header X-Real-IP $remote_addr;”的语句,如果想要显示真正的客户端ip地址,是否需要像你的样板配置里面的“map $remote_addr $proxy_forwarded_elem”及“map $http_forwarded $proxy_add_forwarded”配置模块? 还是说套了cf就不能显示客户端的真正ip?

chise0713 commented 5 months ago

em 大概是proxyprotocol没有正确处理

这里用的是 http 的 header X-Forwarded-For 来着

chika0801 commented 5 months ago

@chika0801 谢谢回复!

因为xray 1.8.4服务器搭建后很久没有用这个协议连接了,测试了一下xray服务日志显示的是CF的ip,因为套了CF, 这个服务器的nginx配置里面已经有“grpc_set_header X-Real-IP $remote_addr;”的语句,如果想要显示真正的客户端ip地址,是否需要像你的样板配置里面的“map $remote_addr $proxy_forwarded_elem”及“map $http_forwarded $proxy_add_forwarded”配置模块? 还是说套了cf就不能显示客户端的真正ip?

我是不用cdn,我说的是不用时的情况。 用了cdn,我没去研究它了。

chise0713 commented 5 months ago

找到问题了,就是单纯的没读 header 里的 X-Forwarded-For,我待会开个 PR

ZqinKing commented 5 months ago

找到问题了,就是单纯的没读 header 里的 X-Forwarded-For,我待会开个 PR

一看到这个iss就想到是没读X-Forwarded-For

chise0713 commented 5 months ago

@egg1234 我套 cdn 也能得到真实客户端的 IP,它也会发 X-Forwarded-For,你得正确配置

lxhao61 commented 5 months ago

已测试,大佬的 PR 已解决问题,期待最终合并及推出更新版本。

egg1234 commented 5 months ago

@chise0713 我服务器的nginx是下面这个配置,请教要加什么配置语句才能在套CF情况下让xray的日志显示客户端的真正ip地址?

location /grpc {
    if ($content_type !~ "application/grpc") {
                return 404;
            }
     client_max_body_size 0;
     client_body_buffer_size 512k;
     grpc_set_header X-Real-IP $remote_addr;
     client_body_timeout 52w;
     grpc_read_timeout 52w;
     grpc_pass grpc://127.0.0.1:11111;
    }

谢谢!

chise0713 commented 5 months ago

@egg1234 答案就在我的那句话里

chika0801 commented 5 months ago

@egg1234 答案就在我的那句话里

其实你知道他可能懂不起,不如你好人做到底,改下他发的配置。。。主要是我以前搞时还知道,现在忘记了,我也不会改,想抄个模板

chise0713 commented 5 months ago

@egg1234 答案就在我的那句话里

其实你知道他可能懂不起,不如你好人做到底,改下他发的配置。。。主要是我以前搞时还知道,现在忘记了,我也不会改,想抄个模板

问题是我不会 nginx,只知道他没把 X-Forwarded-For 传给 xray

chika0801 commented 5 months ago

@egg1234 答案就在我的那句话里

其实你知道他可能懂不起,不如你好人做到底,改下他发的配置。。。主要是我以前搞时还知道,现在忘记了,我也不会改,想抄个模板

~问题是我不会 nginx,只知道他没把 X-Forwarded-For 传给 xray~

我以前抄哪博客测试搞好过,后来反正我也不用CDN加整理模板,现在找不到那时的nginx和xray配置模板了,哦对了 https://github.com/lxhao61/integrated-examples 这位佬的仓库中应该有线索,我不去看了

chise0713 commented 5 months ago

如果一个 header 被赋值过,那么就继续使用这个值,否则使用 remote ip 类似 Makefile 的

X-Forwarded-For ?= $remote-ip

nginx 有这种逻辑吗

us254 commented 5 months ago

Nginx does not have a syntax similar to Makefiles for assigning default values to variables. However, Nginx provides a different way to achieve a similar functionality using the map directive and the $remote_addr variable.

Here's an example of how you can set the X-Forwarded-For header in Nginx based on the presence of an existing value or the remote IP address:

map $http_x_forwarded_for $proxy_add_x_forwarded_for {
    default $remote_addr;
    ~^$     $remote_addr; # If X-Forwarded-For is empty, use $remote_addr
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # Other proxy settings...
    }
}
  1. The map directive creates a new variable $proxy_add_x_forwarded_for based on the value of the $http_x_forwarded_for header (which contains the existing X-Forwarded-For value).
  2. If $http_x_forwarded_for is empty (~^$), the $proxy_add_x_forwarded_for variable is set to $remote_addr (the client's IP address).
  3. If $http_x_forwarded_for is not empty, the default rule is applied, and $proxy_add_x_forwarded_for is set to the existing X-Forwarded-For value.
  4. In the server block, the proxy_set_header directive sets the X-Forwarded-For header to the value of $proxy_add_x_forwarded_for when proxying the request to the backend.

This way, if the X-Forwarded-For header is already present, its value is preserved. If it's not present, the client's IP address ($remote_addr) is used as the value for the X-Forwarded-For header.

Fangliding commented 5 months ago

@us254 Please stop spamming with AI generated text

chika0801 commented 5 months ago

https://github.com/XTLS/Xray-core/commit/2cafb3ef89990e3b1088d6b0a3ce16d7c924a78c

已解决了