Page 1 of 1

Regarding the client IP address and user.getIpAddress()

Posted: 09 Jan 2026, 06:06
by snrhcn
Hello..

My architecture is:

Client -> CloudFront -> Nginx -> SFS

CloudFront automatically adds the X-Forwarded-For header, and my Nginx also forwards the X-Forwarded-For header.

My other HTTP backend in Nginx can retrieve the client's real IP using X-Forwarded-For. However, in SFS, the retrieved IP is 127.0.0.1.

Why is this?


I have already enabled the following in my web server:

p2.png
(18.73 KiB) Not downloaded yet

How does SFS obtain the client's real IP address?

If the HTTP header contains X-Forwarded-For, is it retrieved first?

Re: Regarding the client IP address and user.getIpAddress()

Posted: 09 Jan 2026, 09:32
by Lapo
Hello.
Premise: the detection of the original IP works only with Websocket connections, not with the TCP SFS2X protocol.
Client -> CloudFront -> Nginx -> SFS
It depends on what Nginx is sending to SFS. If Nginx is sending the "x-forwarded-for" header correctly, SFS2X will detect the original address. Since the first node in the chain is CloudFront, it should send the x-f-f param with the client address to Nginx. Then Nginx should add the CloudFront address to the x-f-f header (as comma separated values) and finally send it to SFS2X.

By the way, you didn't say which version of SFS2X you're using. We recommend to update to the latest release as we have improved this aspect of IP detection since 2.20. Currently the latest update is 2.20.5

Updates are available here:
https://www.smartfoxserver.com/download#p=updates

Cheers

Re: Regarding the client IP address and user.getIpAddress()

Posted: 10 Jan 2026, 08:27
by snrhcn
I'm using Version 2.20.5. Unfortunately, I can't get the real IP address.

Below is part of my Nginx configuration:

Code: Select all

    upstream websocket_backend {
        server 127.0.0.1:8443;
        keepalive 32;
    }
    
    upstream api_backend {
        server 127.0.0.1:8090;
        keepalive 32;
    }

        location /BlueBox/websocket {	
            proxy_pass https://websocket_backend;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $http_x_forwarded_for;
            
            proxy_read_timeout 86400;
            proxy_send_timeout 86400;
        }
        
        location /api/ {
            proxy_pass http://api_backend;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $http_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Original-URI $request_uri;

            add_header Cache-Control "no-cache, must-revalidate";
        }
 
As you can see, both my WEB API and WebSocket forward XFF.

However, in my API, I use:

Code: Select all

    public static String getClientIp(HttpServletRequest request) {
        if (request == null) return "127.0.0.1";

        String[] headers = {
                "X-Forwarded-For",
                "Proxy-Client-IP",
                "WL-Proxy-Client-IP",
                "HTTP_CLIENT_IP",
                "HTTP_X_FORWARDED_FOR"
        };

        String ip = "";
        for (String header : headers) {
            String value = request.getHeader(header);
            if (isValidIpv4(value)) {
                ip = value;
                break;
            }
        }

        if (ip.contains(",")) {
            String[] ips = ip.split("\\s*,\\s*");
            for (String candidate : ips) {
                if (isValidPublicIpv4(candidate)) {
                    ip = candidate;
                    break;
                }
            }
        }

        if (!isValidIpv4(ip)) {
            ip = request.getRemoteAddr();
            if (ip.contains(":")) {
                ip = "127.0.0.1";
            } else if ("127.0.0.1".equals(ip)) {
                try {
                    ip = InetAddress.getLocalHost().getHostAddress();
                } catch (UnknownHostException e) {
                }
            }
        }

        return ip;
    }
This can retrieve the real IP address.

However, when using the JoinZoneHandler on the SFS server:

Code: Select all

trace("User " + user.getName() + " JoinZone " + zone.getName(), " IP ", user.getIpAddress());
The printed result is:

User xxxx Joined zone XXX Zone IP 127.0.0.1

Re: Regarding the client IP address and user.getIpAddress()

Posted: 10 Jan 2026, 15:20
by Lapo
Since 2.20.5 we have added the ability to access custom http headers.
See here for more details:
https://docs2x.smartfoxserver.com/Advan ... tp-headers

Let us know if this helps solving your use case.
Cheers

Re: Regarding the client IP address and user.getIpAddress()

Posted: 12 Jan 2026, 13:23
by snrhcn
OK, thanks, the management tool allows X-Forwarded-For

Code: Select all

Map<String, String> headers = (Map<String,String>) session.getSystemProperty(SFSConstants.SESSION_HTTP_HEADERS);
if (headers != null && headers.containsKey("X-Forwarded-For")) { 
    user.setProperty("ip", headers.get("X-Forwarded-For"));
} else { 
    user.setProperty("ip", user.getIpAddress());
}
:D