Is there a way to collect the IP address of a client connected to your website through a proxy server?
The entire setup is an internal LAN and through the sysadmin, I have control over the proxy machine as well. I am using PHP5 for the website server side.
I tried $_SERVER['REMOTE_ADDR']
in PHP but this variable just stores the IP address of the proxy.
Any ideas?
The standard solution (in php) is:
if ($_SERVER['HTTP_X_FORWARDED_FOR']){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
else{
$ip = $_SERVER['REMOTE_ADDR'];
}
But as the first answer says this all depends on the header actually being set.
It depends on the proxy. Some proxies add a header which gives the original IP address, the X-Forwarded-For header, but given that most companies uses proxies to hide the internal network structure that's rare. If this is the case then you're not going to be able to do it easily.
If you have control over the proxy then it's time to read the proxy documentation to see how to add that header.
X-Forwarded-For
is the only way to get client's IP address. Check if there is a way to enable that in your proxy.
On some proxy, it gives you option how to handle existing XFF header (when request passes through multiple proxies). Here is what you need to consider,
- If the client address is for security/trust purposes (like ACL or rate-limiting), existing XFF header should be dropped by proxy.
- If the address is for information only (logging, debugging), you should append peer address to existing XFF, separated by comma. The first IP on the list would be the client's IP.
This code can be used to get the client's IP address who's connecting through a proxy.
public static String getClientIpAddr(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
But it detects only when proxy is transparent.
Below is the information on HTTP proxy:
Not using any proxy server:
request.getRemoteAddr()
= IP address of client
request.getHeader("HTTP_X_FORWARDED_FOR")
= No value or No display
Use Transparent Proxies:
HTTP_X_FORWARDED_FOR
= Real IP address of client
Use Normal Anonymous Proxies:
request.getRemoteAddr()
= IP address of proxy server
HTTP_X_FORWARDED_FOR
= IP address of proxy server