Set correct REMOTE_ADDR in PHP-FPM called from Apache

We want to switch from mod_php to fastCGI + PHP-FPM on our Apache server.

We got everyhting in place and working except one thing:

Value in our $_SERVER['REMOTE_ADDR'] is always 127.0.0.1 not IP of client. Is there any way how to configure server to set this variable to client real IP?

We have client real IP in X-Forwarded-For header (passed from proxy)

Basically we need Apache alternative for nginx config:

fastcgi_param REMOTE_ADDR $http_x_forwarded_for;

( as described here Nginx replace REMOTE_ADDR with X-Forwarded-For)

Upvotes: 6

Views: 12993

Answers (5)

Richard Kiefer
Richard Kiefer

Reputation: 1954

With apache 2.4 you can use apache's mod_remoteip module. It will set the expected client IP in apache logs as well as forward that information to php-fpm without any changes in php-fpm. Tested with the official httpd and php-fpm docker images.

Here is an example configuration part for your httpd.conf:

LoadModule remoteip_module modules/mod_remoteip.so

RemoteIPHeader X-Forwarded-For
RemoteIPProxiesHeader X-Forwarded-By
# 0.0.0.0/0 is not accepted
RemoteIPInternalProxy 172.0.0.0/8

The otherwise mentioned mod_rpaf is no longer available with apache 2.4.

Upvotes: 1

Alex
Alex

Reputation: 51

If you want to see the real IP in logs, use %{REMOTE_ADDR} in access.format directive. In php-fpm.conf of your pool.

Upvotes: 5

TomKeegasi
TomKeegasi

Reputation: 210

Since I just spend a few good hours on this, I'd like to point out that mod_rpaf does not seems to work correctly when using mod_proxy + mod_proxy_fcgi instead of mod_fcgi (at least on Debian Jessie)

While mod_rpaf will indeed fix the apache access-log when both mod_rpaf and the load-balancer are configured correctly, it will sadly not fix PHPs $_SERVER['REMOTE_ADDR'] variable.

Some people suggest manually overwriting REMOTE_ADDR using:

SetEnvIf X-Real-IP "^(\d{1,3}+\.\d{1,3}+\.\d{1,3}+\.\d{1,3}+).*" REMOTE_ADDR=$1
RequestHeader set REMOTE-ADDR %{REMOTE_ADDR}e env=REMOTE_ADDR

and while you can ADD custom entries to $_SERVER (with and without HTTP prefix) this way, it does not work for REMOTE_ADDR...

On the other hand using mod_remoteip passes the correct ip to $_SERVER['REMOTE_ADDR'], but it seems like the apache access-log is showing the load-balancers ip again...

[EDIT: Nevermind, replace %h with %a in the access-log format definition (apache2.conf) and it works]

Upvotes: 0

Solved by adding directive to php.ini:

auto_prepend_file = /etc/php5/rpaf.php

which enable execution of this simple PHP script to normalize headers:

<?php

$trustedProxies = array(
  '127.0.0.1'  
);

$remote = $_SERVER['REMOTE_ADDR'];

$allowedHeaders = array(
  'HTTP_X_FORWARDED_FOR' => 'REMOTE_ADDR',
  'HTTP_X_REAL_IP' => 'REMOTE_HOST',
  'HTTP_X_FORWARDED_PORT' => 'REMOTE_PORT',
  'HTTP_X_FORWARDED_HTTPS' => 'HTTPS',
  'HTTP_X_FORWARDED_SERVER_ADDR' => 'SERVER_ADDR',
  'HTTP_X_FORWARDED_SERVER_NAME' => 'SERVER_NAME',
  'HTTP_X_FORWARDED_SERVER_PORT' => 'SERVER_PORT',
);

if(in_array($remote, $trustedProxies)) {
  foreach($allowedHeaders as $header => $serverVar) {
    if(isSet($_SERVER[$header])) {
      if(isSet($_SERVER[$serverVar])) {
        $_SERVER["ORIGINAL_$serverVar"] = $_SERVER[$serverVar];
      }
      $_SERVER[$serverVar] = $_SERVER[$header];
    }
  }
}

Upvotes: 4

Tan Hong Tat
Tan Hong Tat

Reputation: 6864

Set it in the nginx config.

# Set the client remote address to the one sent in the X_FORWARDED_FOR header from trusted addresses.
set_real_ip_from                127.0.0.1;
real_ip_header                  X-Forwarded-For;
real_ip_recursive               on;

Source: http://nginx.org/en/docs/http/ngx_http_realip_module.html

--

Update for Apache

For Apache, install module mod_rpaf, and configure it.

LoadModule              rpaf_module modules/mod_rpaf.so
RPAF_Enable             On
RPAF_ProxyIPs           127.0.0.1 10.0.0.0/24
RPAF_SetHostName        On
RPAF_SetHTTPS           On
RPAF_SetPort            On
RPAF_ForbidIfNotProxy   Off

Source: https://github.com/gnif/mod_rpaf

Upvotes: 0

Related Questions