java
Java-Monitor Forum > Forum > Java Administration » Getting the remote IP address from behind an Apache server
Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 30-08-2008, 11:57
kjkoster kjkoster is offline
Forum Operator
 
Join Date: Jul 2008
Posts: 1,136
Default Getting the remote IP address from behind an Apache server

Dear All,

Many applications use and log the IP addresses of the browsers that connect to their JSP applications. The easiest way to get that address is to use request.getRemoteAddr().

Unfortunately, that address is defined to be the address of the system that is making the connection to Tomcat. If you have Tomcat running behind an Apache HTTP server, that Apache is always the one to make the Tomcat requests, and all your requests appear to come from the machine running Apache.

If you want to get the browser's IP address (or at least the last visible public IP address leading back to that person) you can use the HTTP header "x-forwarded-for", which Apache sets.

The code now looks like this:
Code:
    /**
     * Read the remote IP of a servlet request. This may be in one of two
     * places. If we are behind an Apache server with mod_proxy_http, we get the
     * remote IP address from the request header x-forwarded-for. In that case
     * the remote ip of the requestor is always that of the Apache server, since
     * that is the last proxy, as per spec.
     * <p>
     * If this header is missing, we're probably running locally for testing. In
     * that case we can just use the remote IP from the request object itself.
     * 
     * @param request
     *            The request to get the remote IP from.
     * @return The remote IP address.
     * @throws UnknownHostException
     *             When the remote IP could not be resolved.
     */
    public static InetAddress remoteIp(final HttpServletRequest request)
            throws UnknownHostException {
        if (request.getHeader("x-forwarded-for") != null) {
            return InetAddress.getByName(request.getHeader("x-forwarded-for"));
        }
    
        return InetAddress.getByName(request.getRemoteAddr());
    }
As you can see I fall back to using request.getRemoteAddr() in case the Apache header is not set. That makes it easier to test these servlets.

Does anyone know of any downsides to working this way?

Kees Jan

UPDATE: here is more robust x-forwarded-for handling code.

Last edited by kjkoster; 27-05-2009 at 07:11. Reason: Added link to followup article with less buggy version of this code
Reply With Quote
  #2  
Old 13-09-2008, 22:22
holeinone holeinone is offline
Junior Member
 
Join Date: Sep 2008
Posts: 29
Default Looking for problems

Just guessing here: load-balancing? Happens before Apache sometimes
(hardware load-balancing for instance).

Maybe you want to ask yourself what question you want to answer. I've been in an scenario where the question actually was: requests for a user. Which of course is slightly different from request per IP.
When I found that out I connected to the Single Sign-on application to get the user as an aspect of a method call.
management thought they knew technicks*1 and wanted requests per IP because they thought it was more feasible. I was able to exceed their expectations just by understanding the real question.

So what is your real question?

*1 The magic language of machines
Reply With Quote
  #3  
Old 14-09-2008, 03:38
sippykup sippykup is offline
Junior Member
 
Join Date: Jul 2008
Posts: 9
Default

I think that problem only exists if you're using mod_proxy. mod_jk should preserve the client address.
Reply With Quote
  #4  
Old 14-09-2008, 11:15
kjkoster kjkoster is offline
Forum Operator
 
Join Date: Jul 2008
Posts: 1,136
Default

Dear holeinone,

In this case, the real question is that I want to know the IP address of the machine that the request came from, not what client it did the request for. So the code above works for me.

Good point, though. I think my case is an exceptional one. Most people will want to know what user the request came from. How did you end up identifying the user?

Kees Jan
Reply With Quote
  #5  
Old 05-05-2009, 19:50
kjkoster kjkoster is offline
Forum Operator
 
Join Date: Jul 2008
Posts: 1,136
Default

Dear All,

Just a quick follow up: this code will also work for the F5 BIG IP load balancer, provided it is configured to insert the "x-forwarded-for" header into the requests that it balances.

Kees Jan
Reply With Quote
  #6  
Old 22-05-2009, 14:39
Barry Barry is offline
Moderator
 
Join Date: Jul 2008
Posts: 106
Default

For those of us who are using NGINX as a simple proxy based loadbalancer, you will need to add the following to your configuration (courtesy to http://blog.kovyrin.net/2007/08/05/u...ations-faster/)

Quote:
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Another example can be found here: http://blog.kovyrin.net/2006/05/18/n...reverse-proxy/
Reply With Quote
  #7  
Old 15-06-2012, 07:51
adheep adheep is offline
Junior Member
 
Join Date: Jun 2012
Posts: 1
Default Need Client Port

I was able to get the Client IP using the above mentioned code, but I was wondering if i could get all the information that HttpServletRequest object provides. Can any one show some light on this?

Thanks in advance!
Reply With Quote
  #8  
Old 16-06-2012, 22:42
kjkoster kjkoster is offline
Forum Operator
 
Join Date: Jul 2008
Posts: 1,136
Default

Dear adheep,

I have no idea what you are asking. What information do you want to get?

Kees Jan
Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump