Reputation: 229
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
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
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
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
Reputation: 229
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
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