If you use a reverse proxy, servers behind that proxy will likely see traffic as coming from the proxy’s IP. The problem with this is that if you have an application that logs traffic or uses IPs for any other purpose, a reverse proxy can break that functionality.
A reverse proxy is a piece of software that sits between a client and a server. The client connects to the proxy, and the proxy connects to the server. The proxy then forwards the client’s request to the server and forwards the server’s response back to the client. Reverse proxies are often used to add additional functionality to a backend application stack such as load balancing, caching, SSL termination, etc.
The problem comes when a reverse proxy forwards a client’s request to a backend server. The backend server will see the request as coming from the proxy’s IP address, not the client’s IP address. This is because the client is connecting to the proxy, not the backend server.
There are a few ways to pass a client’s IP address to a proxied server. The most common way is to use the X-Forwarded-For
header. This header is set by the proxy and contains the client’s IP address. The backend server can then read this header to get the client’s IP address with some additional configuration.
Nginx can be configured to pass the X-Forwarded-For
header to the reverse proxy. This is done by using the proxy_set_header directive to set the header in the server
block:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Apache can be configured to pass the X-Forwarded-For
header to the reverse proxy. This is done by using the RequestHeader directive to set the header in the VirtualHost
block:
RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}s"
For nginx, the ngx_http_realip_module
module must be loaded. This allows nginx to read the X-Forwarded-For
header and use it as the client’s IP address by adding the following line to the server
block:
real_ip_header X-Forwarded-For;
To define the IP from which to trust the X-Forwarded-For
header, this line must also be included in the server
block:
set_real_ip_from X.X.X.X;
where X.X.X.X
is the proxy server’s IP address.
By default, Apache is loaded with the mod_remoteip
module which accomplishes the same thing as the ngx_http_realip_module
above for nginx.
To enable the module itself, run the following command:
a2enmod remoteip
This module can then be configured by adding the following line to the VirtualHost
block:
RemoteIPHeader X-Forwarded-For
And to define the IP from which to trust the X-Forwarded-For
header, this line must also be included in the VirtualHost
block:
RemoteIPTrustedProxy X.X.X.X
where X.X.X.X
is the proxy server’s IP address.
If you are running WordPress in Docker, the configuration to allow it to read the X-Forwarded-For
header is likely already done for you. You can see this in the Dockerfile
for the WordPress image (latest version as of this writing).