I am writing an application in Java that serves a web page with data from an underlying database. I am limiting access to the web page based on some IP restrictions. Basically any IP that falls into the 'Accepted' range will be allowed to access the web page and any IP outside of this range will be redirected to an error page. To get the IP address of the user attempting to access the page I am using the following:
String userIPAddress = request.getRemoteAddr();
Where 'request' is my HttpServletRequest Object.
The issue I am running into is that this web page is being proxied through an Apache Web Server.
When this happens, it loses the clients IP address and adopts the IP address of our firewall. So when I access request.getRemoteAddr(), it will return the same IP no matter where the customer attempts to access the web page from.
When accessing the web page internally via direct IP address my IP check works just fine. The issue presents itself when you access through the proxy.
Is there anything that I can do programmatically to access the clients actual IP address? Or is this something that has to be done/changed via the Apache web server to allow this information to pass through? In that case I can post to Server Fault if that would be a better forum.
Your help is greatly appreciated.
Best Regards.
When acting in a reverse-proxy mode (using the ProxyPass directive, for example), Apache mod_proxy_http adds several request headers in order to pass information to the origin server, one of them being the X-Forwarded-For
which will contain the IP address of the client.
Keep in mind that, if the original request already contained this header (which is not unusual at all), Apache will append the client IP address to existig value(s) so you will get comma+space separated list of IP addresses. The last (rightmost) IP address is always the IP address that connects to the last proxy (your Apache), which means that is the one you want to test against.
I don't think it is possible to do this programmatically. I don't think it is even possible to change something in the Apache web server.
Is sounds like your firewall is masquerading incoming IP addresses. I think the solution is in the configuration of your firewall.
You are able to use the AJP protocol instead of HTTP in the Apache proxy.
Apparently this retains the client's IP address. Does anyone have any ideas why?
Use:
ProxyPass /APPLICATION_NAME ajp://IP_ADDRESS:8009/APPLICATION_NAME
Instead of:
<Location "/APPLICATION_NAME">
ProxyPass http://IP_ADDRESS:8080/APPLICATION_NAME
ProxyPassReverse http://IP_ADDRESS:8080/APPLICATION_NAME
</Location>
In the .conf proxy file.
This enabled me to grab the IP from the client without it being overwritten during the proxy. I did not have to change any code either. After changing to AJP in the Apache proxy file, the following contained the correct IP address:
String userIPAddress = request.getRemoteAddr();