4

My server architecture is like below

0.0.0.0:80  =>  127.0.0.1:6081  =>  127.0.0.1:82
  HAProxy          Varnish             Nginx

I trace real client IP by uncommenting these lines in local.xml

<remote_addr_headers><!-- list headers that contain real client IP if webserver is behind a reverse proxy -->
    <header1>HTTP_X_REAL_IP</header1>
    <header2>HTTP_X_FORWARDED_FOR</header2>
</remote_addr_headers>

It can get real client IP properly. In order information, Placed from IP shows only real client IP.

But, I watch system.log, every visit to the website, this log appends:

ERR (3): Warning: inet_pton(): Unrecognized address xxx.xxx.xxx.xxx, 127.0.0.1, 127.0.0.1  in /some/where/overtherainbow/app/code/core/Mage/Core/Helper/Http.php on line 149

xxx.xxx.xxx.xxx is real client IP.

Code snipet from Http.php (line 149 is return line)

 public function getRemoteAddr($ipToLong = false)
    {
        if (is_null($this->_remoteAddr)) {
            $headers = $this->getRemoteAddrHeaders();
            foreach ($headers as $var) {
                if ($this->_getRequest()->getServer($var, false)) {
                    $this->_remoteAddr = $_SERVER[$var];
                    break;
                }
            }

            if (!$this->_remoteAddr) {
                $this->_remoteAddr = $this->_getRequest()->getServer('REMOTE_ADDR');
            }
        }

        if (!$this->_remoteAddr) {
            return false;
        }

        return $ipToLong ? inet_pton($this->_remoteAddr) : $this->_remoteAddr;
    }

$this->_remoteAddr contains 3 IP addresses as string, it causes the warning log.

How to prevent this?

2

HTTP_X_FORWARDED_FOR can contain many IP addresses when forwarding multiple times. This is untested but try adding this to your index.php:

if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] != '') { 
    $arr = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
    $_SERVER['REMOTE_ADDR'] = trim($arr[0]);
} 

or if Magento is already using HTTP_X_FORWARDED_FOR, perhaps:

if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] != '') { 
    $arr = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
    $_SERVER['HTTP_X_FORWARDED_FOR'] = trim($arr[0]);
} 
1
  • I use phpinfo to inspect $_SERVE keys and find out your second code snipet should be used. Thank you. – Tran Dinh Khanh Jul 21 '15 at 12:13
1

This is now resolved as of Magento 1.9.3.9

app/code/core/Mage/Core/Helper/Http.php

Replace public function getRemoteAddr

with

    public function getRemoteAddr($ipToLong = false)
{
    if (is_null($this->_remoteAddr)) {
        $headers = $this->getRemoteAddrHeaders();
        foreach ($headers as $var) {
            if ($var != 'REMOTE_ADDR' && $this->_getRequest()->getServer($var, false)) {
                $this->_remoteAddr = $_SERVER[$var];
                break;
            }
        }

        if (!$this->_remoteAddr) {
            $this->_remoteAddr = $this->_getRequest()->getServer('REMOTE_ADDR');
        }
    }

    if (!$this->_remoteAddr) {
        return false;
    }

    if (strpos($this->_remoteAddr, ',') !== false) {
        $ipList = explode(',', $this->_remoteAddr);
        $this->_remoteAddr = trim(reset($ipList));
    }

    return $ipToLong ? inet_pton($this->_remoteAddr) : $this->_remoteAddr;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.