0

I have a Magento store on an Ngix behind Sucuri firewall and we hide prices if the IP is outside of UK. A bruteforce attack was bypassing the firewall so the hosting added the following rules to prevent bypass:

     location / {
            allow 192.88.134.0/23;
           allow 185.93.228.0/22;
          allow 2a02:fe80::/29;
          allow 66.248.200.0/22;
          deny all;
           # Existing NGINX rules
            }

This works fine except that all IPs are transalted as the firewall one based in UK. To get the real IP Sucuri suggested to add the following:

  # Define header with original client IP
  real_ip_header X-Forwarded-For;
  # Define trusted Firewall IPs
  set_real_ip_from 192.88.134.0/23;
  set_real_ip_from 185.93.228.0/22;
  set_real_ip_from 66.248.200.0/22;
   set_real_ip_from 2a02:fe80::/29; # this line can be removed if IPv6 is 
  disabled

This second rule causes a problem. Once the IP is translated and if it is different than the allowed Sucuri IP addresses, the requests is restricted with 403 Forbidden error.

Is it impossible to have the store behind a firewall and still get the real IP. I am sure that this is not the only store in the world behind a firewall, which needs to server different content depending on the IP. The code in Magento that gets the IP of the client is something like this:

        $geoIP = Mage::getSingleton('geoip/country'); 

        if ($geoIP->isCountryAllowed()) {....

Any alternative? SOlution? My hosting provider is useless..

  • Does that mean the users' real IP is now received in the $_SERVER variable under the header $_SERVER['HTTP_X_FORWARDED_FOR'] whereas the $_SERVER[“REMOTE_ADDR”] is the WAF IP(Web Application Firewall IP) - If yes, Magento can be configured to work correctly. – Dilhan Maduranga Mar 11 '18 at 15:15
  • Can you elaborate and explain how please? – Shakamal Mar 11 '18 at 19:30
1

For all those who come across the same issue and try to get an answer from sucuri or hopeless hosting providers like siteground, this is what worked for me. I put the following code at the very beginning of Magento index.php:

if(isset($_SERVER['HTTP_X_SUCURI_CLIENTIP']))
 {
     $_SERVER["REMOTE_ADDR"] = $_SERVER['HTTP_X_SUCURI_CLIENTIP'];
| improve this answer | |
  • Worked perfectly. – Marisa May 21 at 19:48
1

We hit the same issue, when trying to apply the suggested "Block Sucuri Bypass"

location / {
    # Block everything that isn't sucuri
    allow 192.88.134.0/23;
    allow 185.93.228.0/22;
    allow 2a02:fe80::/29;
    allow 66.248.200.0/22;
    deny all;

    # other nginx config
}

As this was below the already configured:

# Define header with original client IP
real_ip_header X-Forwarded-For;
# Define trusted IPs
set_real_ip_from 192.88.134.0/23;
set_real_ip_from 185.93.228.0/22;
set_real_ip_from 66.248.200.0/22;
set_real_ip_from 2a02:fe80::/29;

Magento 1

So long as the code uses the core method:

Mage::helper('core/http')->getRemoteAddr()

You can add a list of headers to app/etc/local.xml inside of config->global node that are used to determine the "real" ip. Something like:

<remote_addr_headers>
    <header1>HTTP_X_SUCURI_CLIENTIP</header1>
    <header2>HTTP_X_REAL_IP</header2>
    <header3>HTTP_X_FORWARDED_FOR</header3>
</remote_addr_headers>

Then you can remove the real_ip_header and set_real_ip_from from the nginx config. Allowing all traffic not from Sucuri to be blocked and still able to obtain the true IP within magento. You can test this with something like:

define('MAGENTO_ROOT', getcwd());
$mageFilename = MAGENTO_ROOT . '/app/Mage.php';
require MAGENTO_ROOT . '/app/bootstrap.php';
require_once $mageFilename;

Mage::app('admin');
print_r($_SERVER);
echo 'address: '.Mage::helper('core/http')->getRemoteAddr();

Magento 2

This appears to a little harder, I haven't dug as deep but on initial look.
- vendor/magento/framework/Session/Validator.php
is sensitive to configuration, on if it should use: http_x_forwarded_for or remote_addr
- vendor/magento/framework/HTTP/PhpEnvironment/Request.php:725
has the method getClientIp which appears to use the first it finds from HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR, REMOTE_ADDR
- vendor/magento/magento2-base/pub/errors/processor.php:312
had the method _getClientIp which uses REMOTE_ADDR and if that isn't found returns undefined

If we exclude the error page. We can configure Magento to look for additional headers, by passing the arguments into the class Magento\Framework\HTTP\PhpEnvironment\RemoteAddress. As this configuration is installation specific, I have done this in the file: app/etc/custom/di.xml this allows us to override/append the base DI for Magento.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\HTTP\PhpEnvironment\RemoteAddress">
        <arguments>
            <argument name="alternativeHeaders" xsi:type="array">
                <item name="sucuri" xsi:type="string">HTTP_X_SUCURI_CLIENTIP</item>
                <item name="real_ip" xsi:type="string">HTTP_X_REAL_IP</item>
            </argument>
        </arguments>
    </type>
</config>

After doing this you will need to re-compile Magento and flush cache. Magento will then search for the headers specified here first, before falling back to core behaviour.

| improve this answer | |

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.