I am running NGINX as part of a Docker package. It is both a webserver and a reverse proxy, and the container has PHP bundled in with it. The front-end web application is built with Laravel. There are some instances where I want to get the client's IP address, and this seems to a little problematic in some cases. This isn't for the proxy, but for the web application served with NGINX and PHP.
On my development system at home I am getting an IP for the docker network when connecting with a browser from my local machine.
$_SERVER['SERVER_ADDR'] = 172.19.0.10
$_SERVER['REMOTE_ADDR'] = 172.19.0.1
On a Digital Ocean Dev server it has:
$_SERVER['SERVER_ADDR'] 172.27.0.16
$_SERVER['REMOTE_ADDR'] 213.225.x.xx, which is Austria, my IP
and on a Production server elsewhere I think it has:
$_SERVER['SERVER_ADDR'] ???
$_SERVER['REMOTE_ADDR'] = The WAN IP for the office where the server is installed.
This isn't the client IP, but the WAN address for the office itself.
The server at that office is behind I think a WatchGuard or Fortigate router / Firewall.
So, the Digital Ocean Dev server is actually "OK". I have access to what I need, but the office setup probably isn't setup to forward the client ip to the server that runs on their internet ?
It isnt' critical currently, but it would be nice to be able to capture to public client IP in all cases.
I could do a little more investigation with log files, etc., but pretty sure I'll have to:
- Possibly configure something in my NGINX config
and/or
- Have someone configure the firewall to pass through the client IP because it seems like it isn't doing that currently, or I'm not capturing what it is sending.
CodePudding user response:
The nginx proxy at the office can be configured to pass the client's IP address using the proxy_set_header
directive.
The nginx reverse proxy docs here show an example:
location /some/path/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://localhost:8000;
}
In the config block where the reverse proxy proxy_pass
directive is set, adding proxy_set_header X-Real-IP $remote_addr;
tells the proxy to inject a new HTTP header, X-Real-IP
, with the IP address of the client. In the Laravel app, you can use this to get the actual client IP. In your application, make sure only to use this header when it can be trusted1.
This is necessary because the proxy is taking and re-sending the client's request via the proxy server from its own network address. The only way the application can get the original client IP for the request being proxied is if that IP address is passed in the headers by the proxy.