Determine Client IP on Apache Httpd Configuration
Posted in Know-How, PHP on December 3rd, 2008 – Tags: apache – Be the first to commentSometime REMOTE_ADDR not return the real client IP address value. This is true when the server was behind the firewall, or server use application like Squid, or the client accesses the server trough the proxy (like Google WebAccelerator); so the REMOTE_ADDR become the IP of the firewall server, the Squid server or proxy server.
Anda dapat membaca versi Indonesia tulisan ini disini: Mendapatkan IP Pengunjung pada Apache.
On PHP
On PHP it’s simply by creating a function, eg ‘get_real_client_ip’, like below:
function get_real_client_ip() {
$ip = false;
if (isset($_SERVER)) {
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
} else {
if (getenv('HTTP_X_FORWARDED_FOR')) {
$ip = getenv('HTTP_X_FORWARDED_FOR');
} elseif (getenv('HTTP_CLIENT_IP')) {
$ip = getenv('HTTP_CLIENT_IP');
} else {
$ip = getenv('REMOTE_ADDR');
}
}
//watch this line below
if ($ip) {
$ipa = explode(',', $ip);
$ip = trim($ipa[0]);
}
return $ip;
}
and we can get the value like below:
$ip = get_real_client_ip();
If the request come from many proxy, it’s possible that the HTTP_X_FORWARDED_FOR has some IP with comma separated. Therefor on example function above, we have to explode()-ed the string to get the first IP, that suppose to be the real one.
On Apache
On Apache, especially when we want to create log, this can be done using SetEnvIf directive, and then overwrite REMOTE_ADDR value. Here we did not use ‘HTTP_X_FORWARDED_FOR’ because all HTTP header on Apache translated to %{HTTP:X-Forwarded-For} format; where the the underscore (“_”) replaced by dash (“-”).
As we have mentioned above, HTTP_X_FORWARDED_FOR may return more than one IP. On Apache, we use regex with SetEnvIf. If the value match, it will return the right IP.
SetEnvIf X-Forwarded-For "([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3})" REMOTE_ADDR=$1$2$3$4
So, with this syntax, the REMOTE_ADDR become the valid IP address of the client. This usefull, example for Apache log that we can find in httpd.conf file:
LogFormat "%h %u %t" common
where %h is the remote_host, %u is the remote_user and %t is time acces
Others…
Some proxy or firewall will set the IP of the client on others variable. But right now the common was HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP. Below are the list:
HTTP_X_FORWARDED_FOR
HTTP_CLIENT_IP
HTTP_X_COMING_FROM
HTTP_X_FORWARDED
HTTP_FORWARDED_FOR
HTTP_FORWARDED
HTTP_FROM
HTTP_VIA
HTTP_COMING_FROM
On Apache, all these must be check with %{HTTP:variable-name} format.
