Unable to get actual remote IP address via REST

0
Hi all,   I'm trying to log the IP address of devices calling my REST service. I've already tried using the following code in a Java Action, but when running in the Sandbox environment, I got addresses starting with 10.10.x.x:   @java.lang.Override public java.lang.String executeAction() throws Exception { // BEGIN USER CODE IContext ctx = getContext(); if (ctx.getRuntimeRequest().isPresent()) { IMxRuntimeRequest req = ctx.getRuntimeRequest().get(); // https://stackoverflow.com/questions/16558869/getting-ip-address-of-client String xForwardedForHeader = req.getHeader("X-Forwarded-For"); if (xForwardedForHeader == null) { return req.getRemoteAddr(); } else { // As of https://en.wikipedia.org/wiki/X-Forwarded-For // The general format of the field is: X-Forwarded-For: client, // proxy1, proxy2 ... // we only want the client String forwardIp = new StringTokenizer(xForwardedForHeader, ",").nextToken().trim(); boolean validIP = checkIP(forwardIp); if (validIP) { return forwardIp; } else { Core.getLogger("JA_GetIPAddress").error("Could not parse X-Forwarded-for header to an IP address. Header: "+forwardIp); return ""; } } } else { return ""; } // END USER CODE } .. // BEGIN EXTRA CODE public static final boolean checkIP(final String ip) { boolean isIPv4; try { final InetAddress inet = InetAddress.getByName(ip); isIPv4 = inet.getHostAddress().equals(ip) && (inet instanceof Inet4Address || inet instanceof Inet6Address); } catch (final UnknownHostException e) { isIPv4 = false; } return isIPv4; } // END EXTRA CODE   (Shalemessly stolen from GetIP.java from HTTP Commons)    This is a related question, albeit without a useful answer.   The 10.10.x.x IP address range seems to originate from AWS, according to this article.   Thanks in advance! Andre
asked
2 answers
1

You could try to inspect the request headers to see if that gives you some clue.

    private Map<String, String> getRequestHeadersInMap(HttpServletRequest request) {

        Map<String, String> result = new HashMap<>();

        Enumeration headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            result.put(key, value);
        }

        return result;
    }

But as far as I know there is no bullet proof way to retrieve the client IP address.

 

Regards,

Ronald

 

answered
0

Good news! The cause of the problem appeared to be the sandbox environment, most probably the load balancer. I've tested it on a new licensed Mendix cloud environment and it works as intended. Got even more headers this time:

 

Ssl-Protocol: TLSv1.3
Sec-Ch-Ua-Platform: "Windows"
User-Agent: <snip>
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
X-Vcap-Request-Id: <snip>
Sec-Fetch-Mode: navigate
X-Cf-Instanceindex: 0
Upgrade-Insecure-Requests: 1
X-B3-Spanid: <snip>
Sec-Fetch-User: ?1
Cookie: <snip>
Sec-Ch-Ua: <snip>
X-Cf-Instanceid: <snip>
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
X-Forwarded-Proto: https
Sec-Fetch-Site: none
X-Request-Start: <snip>
Host: <snip>.mendixcloud.com
X-Forwarded-Port: 443
X-Amzn-Trace-Id: Root=<snip>
B3: <snip>
X-Cf-Applicationid: <snip>
Ssl-Cipher: TLS_AES_256_GCM_SHA384
X-Forwarded-For: <client ip>, <10.10.x.x (proxy 1)>, <10.10.x.x (proxy 2)>
X-B3-Traceid: <snip>
Accept-Language: en-US,en;q=0.9
Sec-Ch-Ua-Mobile: ?0
X-Forwarded-Scheme: https
X-Real-Ip: <client ip>

 

Thanks again.

 

Regards, Andre

answered