Here, we are dealing with 2 nginx servers. A front-end nginx, proxying request to another nginx-server running behind firewall. This backend-nginx is a WordPress setup, using PHP-FPM (fastcgi) on our case. Article is valid for any code/application running behind fastcgi upstream.
To manage security properly, we need to pass-on visitors real-IP to backend-nginx. In backend-nginx, WordPress do some stuff based on user-ip.
On Front-End Nginx
First, a portion of Nginx config from front-end proxy
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
With this config, backend-nginx receives extra HTTP Headers which are passed to fastcgi upstream (PHP/WordPress in our case).
If you see output of phpinfo()
you will see extra headers as highlighted below:
The problem with above setup is that fastcgi app running behind backend-nginx, uses REMOTE_ADDR
value whenever it needs to deal with visitor IP address.
A solution would be check existence ofHTTP_X_REAL_IP
and use that value instead. I think WordPress does this for itself but one of our custom plugin was not already doing that. We could either fix it in PHP code, but rather than modifying every piece of PHP code which rely on REMOTE_ADDR
, we added following lines inside backend-nginx conf:
location ~ \.php$ {
fastcgi_param REMOTE_ADDR $http_x_real_ip;
#...other rules
}
With this change phpinfo()
shows correct user IP forREMOTE_ADDR
value.
Now any piece of code, which depend onREMOTE_ADDR
value will work as it is!
Nginx’s HTTP Real IP Module
If you want to do some real-user IP-based stuff in backend, it will NOT work.
Nginx itself will not see real-user IP. Only application/codes behind fastcgi will benefit from above change.
For Nginx, you can simply use variable $http_x_real_ip
instead of IP-address.
Below is an example of $http_x_real_ip
usage to emulate allow/deny functionality:
if ($http_x_real_ip != 115.115.82.210) {
return 403;
}
There are cases when a workaround using $http_x_real_ip
may not be possible. In those caes, we can use Nginx’s Http Real IP Module.
You can fix real-ip andREMOTE_ADDR
by adding a line like below to your backend nginx-config:
set_real_ip_from 192.168.122.1;
Make sure you replace 192.168.122.1 with REMOTE_ADDR value that was being received originally. It is IP of proxy-nginx as seen by backend-nginx.
Advantage of Http Real IP Module is that it sets correct IP for nginx config as well as fastcgi backend app in one go. Apart form this, it is secure also.
You can use earlier way if your Nginx is not built with --with-http_realip_module
option.
If you have any questions, feel free to check our Nginx support forum.