предупреждение inet pton при использовании веб-сервера за обратным прокси-сервером


Моя архитектура сервера похожа на приведенную ниже

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

Я отслеживаю реальный IP-адрес клиента, раскомментировав эти строки в 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>

Он может правильно получить реальный IP-адрес клиента. В информации о заказе Placed from IP отображается только реальный IP-адрес клиента.

Но, я смотрю system.log, при каждом посещении веб-сайта этот журнал добавляет:

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 является реальным IP-адресом клиента.

Снипет кода из Http.php (строка 149 - это строка return)

 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 содержит 3 IP-адреса как string, это вызывает журнал предупреждений.

Как предотвратить это?

 4
Author: Tran Dinh Khanh, 2015-07-21

2 answers

HTTP_X_FORWARDED_FOR может содержать много IP-адресов при многократной пересылке. Это непроверено, но попробуйте добавить это в свой 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]);
} 

Или, если Magento уже использует HTTP_X_FORWARDED_FOR, возможно:

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]);
} 
 2
Author: Andrew Kett, 2015-07-21 10:40:52

Теперь это разрешено с версии Magento 1.9.3.9

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

Заменить публичная функция getRemoteAddr

С

    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;
}
 1
Author: hejhog, 2018-12-13 22:38:55