Geo Location saving proxy server (load balancer) ip in database


I have configured the Piwik for our high volume site in KSA. Right now tag script is added to half of application servers and we are collecting 1.3 Million actions per day.

The problem is that we see high number of visitors from US and we are sure that we receive 95% of our traffic from within KSA. Please also note that there is no record for regions / cities in maps or database. I am using GeoLiteCity.dat (renamed to GeoIPCity.dat).

We also tried proxy_ips[] = (which is our load balancer ip, Big Pipe by F5) in global.ini.php but of no use.

Currently the stats shows that 10000+ unique visitors from USA and 548 unique visitors from KSA.

We have configured X-Forwarded-For header to pass through load balancer and we are logging the X-Forwarded-For in the Piwik’s Apache access logs. So we are receiving the real client IP in this header, but still Piwik seems not to record the real client ip in geo location databases.

Kindly advise how to make the geo location module to record the real client ip.

I would recommend getting the Maxmind Pro DB maybe it will be bring more accuracy? Otherwise it’s possible that maxmind DB is not accurate for your visitors IPs


I don’t know whether its a code bug or some mis-configuration from my side. But this is how I fixed it by slight modification of code.

I just added 2 lines in the __construct of Piwik/core/Tracker/Visit.php to fix my issue.
The new lines were added to get the IP from X-Forwarded-For header instead of getting client-ip. Following are the details of code-change.

Code File : Piwik/core/Tracker/Visit.php

Added lines :
if (empty($forcedIpString)) {
$forcedIpString = $_SERVER[‘HTTP_X_FORWARDED_FOR’];

/**  Above this code, the $forcedIpString was coming Empty.  The root cause could be to find out why $forcedIpString is coming empty at this location?.

Whole Function after change :
public function __construct($forcedIpString = null, $forcedDateTime = null, $authenticated = false)
$this->timestamp = time();
if (!empty($forcedDateTime)) {
if (!is_numeric($forcedDateTime)) {
$forcedDateTime = strtotime($forcedDateTime);
$this->timestamp = $forcedDateTime;

/* Start of : New code for fixing the real ip of geo-location */ 
if (empty($forcedIpString)) {
	$forcedIpString = $_SERVER['HTTP_X_FORWARDED_FOR'];
/* End of : New code for fixing the real ip of geo-location */ 

    $ipString = $forcedIpString;
    if (empty($ipString)) {
        $ipString = Piwik_IP::getIpFromHeader();
    $ip = Piwik_IP::P2N($ipString);
    $this->ip = $ip;

    $this->authenticated = $authenticated;