This question already has an answer here:
I'm having some trouble with a simple problem. I would get the real client IP inside an HTTPServlet.
Since now I used:
request.getRemoteAddr()
But now it returns a false IP. eg: xxx.xxx.xxx.50 but my IP is something like xxx.xxx.xxx.159. (checked at http://whatismyipaddress.com/).
Now I tried to use:
request.getHeader("X-Forwarded-For")
It returns NULL.
I also took a probe with the following class:
public class IpUtils {
public static final String _255 = "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
public static final Pattern pattern = Pattern.compile("^(?:" + _255 + "\\.){3}" + _255 + "$");
public static String longToIpV4(long longIp) {
int octet3 = (int) ((longIp >> 24) % 256);
int octet2 = (int) ((longIp >> 16) % 256);
int octet1 = (int) ((longIp >> 8) % 256);
int octet0 = (int) ((longIp) % 256);
return octet3 + "." + octet2 + "." + octet1 + "." + octet0;
}
public static long ipV4ToLong(String ip) {
String[] octets = ip.split("\\.");
return (Long.parseLong(octets[0]) << 24) + (Integer.parseInt(octets[1]) << 16)
+ (Integer.parseInt(octets[2]) << 8) + Integer.parseInt(octets[3]);
}
public static boolean isIPv4Private(String ip) {
long longIp = ipV4ToLong(ip);
return (longIp >= ipV4ToLong("10.0.0.0") && longIp <= ipV4ToLong("10.255.255.255"))
|| (longIp >= ipV4ToLong("172.16.0.0") && longIp <= ipV4ToLong("172.31.255.255"))
|| longIp >= ipV4ToLong("192.168.0.0") && longIp <= ipV4ToLong("192.168.255.255");
}
public static boolean isIPv4Valid(String ip) {
return pattern.matcher(ip).matches();
}
public static String getIpFromRequest(HttpServletRequest request) {
String ip;
boolean found = false;
if ((ip = request.getHeader("x-forwarded-for")) != null) {
StringTokenizer tokenizer = new StringTokenizer(ip, ",");
while (tokenizer.hasMoreTokens()) {
ip = tokenizer.nextToken().trim();
if (isIPv4Valid(ip) && !isIPv4Private(ip)) {
found = true;
break;
}
}
}
if (!found) {
ip = request.getRemoteAddr();
}
return ip;
}
}
It also returned the xxx.xxx.xxx.50 IP. :(
Now I don't know how to get the real client IP. If somebody knows the solution please make an answer.
When you have NAT (Network Address Translation) device before your servlet container
request.getRemoteAddr()
returns the address of NAT , since it initiate a new connection.To solve your problem you should configure you NAT to send in a header the IP of the original client. Then, to take the header from the request. In case you configure in NAT X-Forwarded-For header use this code:
request.getHeader("X-Forwarded-For")
You function is correct, you can use it when you configure NAT.
Java
JSP
If the jsp is deployed in local server and accessing this jsp returns 0:0:0:0:0:0:0:1. If accessing the application locally with ip then it returns IP.
RESTful Web Services with Jersey
using JavaScript to find IP
I suppose that your problem is that you are running server somewhere in local network, so you get your IP in that network. However when you are trying to use online service that discovers your IP address your IP is the IP of your service provider's router or something like this. Using
request.getRemoteAddr()
is correct. This is what such services do and they do not have other facilities.