简体   繁体   中英

How to get proxy value of nginx-key X-Real-IP in Ratchet websocket

i'm setting up a websocket application with ratchet websockets. My setup is the following: I (have to) use an nginx server as an reverse proxy forwarding requests to my websocket ratchet server:

    location /websocket {
        proxy_pass http://websocket;
        proxy_http_version 1.1;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_redirect off;
    }

Within my websocket app i need to get the value ($remote_addr) of X-Real-IP for IP filtering. Because i have to use this proxy solution i will always get the ip 127.0.0.1 as the remote ip when using the function stream_socket_get_name.

As far as i have investigated this problem ratchet starts a stream_socket_server and then starts to listen for incomming connections. These connections are already streams and not http-requests so i'm not able to use something like $_SERVER etc.

Does anybody know how to retrieve this value?

Regards

Marcus

on方法中传递的每个ConnectionInterface对象都包含一个Guzzle RequestInterface对象,其中包含来自初始请求的HTTP头:

$conn->WebSocket->request->getHeader('X-Real-IP');

I had the same issue, but even more complicated because I had 2 proxy servers in front of a load balancer and then another proxy, and then another one for the websocket... I spent some time to pass the headers properly, but things will get interesting when you proxy your WebSocket server...

I will share the function I made to get the real IP of the visitor inside the Ratchet server application, even if behind CloudFlare:

/**
     * Get the real visitor IP
     * @author nboros
     * @param Ratchet WebSocket $conn
     * @return string $ip
     */
    function GetRealUserIp($conn) {

        $HTTP_X_REAL_IP         = $conn->WebSocket->request->getHeader('X-Real-IP');
        $HTTP_X_FORWARDED_FOR   = $conn->WebSocket->request->getHeader('X-Forwarded-For');
        $HTTP_CF_CONNECTING_IP  = $conn->WebSocket->request->getHeader('CF_CONNECTING_IP');
        $REMOTE_ADDR            = $conn->remoteAddress;

        if(filter_var($HTTP_X_REAL_IP, FILTER_VALIDATE_IP))
        {
            $ip = $HTTP_X_REAL_IP;
        } 
        elseif(filter_var($HTTP_X_FORWARDED_FOR, FILTER_VALIDATE_IP))
        {
            $ip = $HTTP_X_FORWARDED_FOR;
        } 
        elseif(filter_var($HTTP_CF_CONNECTING_IP, FILTER_VALIDATE_IP))
        {
            $ip = $HTTP_CF_CONNECTING_IP;
        } 
        else
        {
            $ip = $REMOTE_ADDR;
        }

        return $ip;
    }

I normally cal the function in the "onOpen()" callback:

$this->GetRealUserIp($conn);

Makre sure you are passing one of the headers: X-Real-IP, X-Forwarded-For in NGINX.

Also add the CloudFlare IP's:

# CloudFlare IPs
# List from: https://www.cloudflare.com/ips-v4
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/12;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 199.27.128.0/21;

# List from: https://www.cloudflare.com/ips-v6
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2c0f:f248::/32;
set_real_ip_from 2a06:98c0::/29;

real_ip_header X-Real-IP;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

And the pass the headers:

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

I really hope this will help someone else in need, and if you think there is room for improvement do advise!

Cheers!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM