Nginx: How to Find out Real Source of HTTP Request

In a recent project using Nginx as reversed proxy server, I got into an interesting problem: how can the server behind the Nginx tell whether a HTTP request comes from remote host or local host? If I just look at the IP header of the request, they are all local because the reversed-proxied packets from remote seems to be sent from local as well. So I cannot really tell the source of a HTTP request.

Luckily, there is already an easy to do it with Nginx. While forwarding a packet to its destination defined in the configuration file, Nginx can add additional HTTP headers which can be read by the target server to tell whether the original source.

Lost VMs or Containers? Too Many Consoles? Too Slow GUI? Time to learn how to "Google" and manage your VMware and clouds in a fast and secure HTML5 App.

In the configuration, you can add proxy_set_header as follows: (For a full example of configuration file, check out this post)

http
{
  server
  {
    …
    location /
    {
         …
         proxy_set_header    X-Real-IP    $remote_addr;
        …
    }
  }
}

The HTTP request forwarded then has a new header with name like “X-Real-IP”. I actually see different variations for the header name with upper and lower cases, for example, “X-REAL-IP” or “x-real-ip”. It has not yet an issue for me because the API for retrieving the header value seems to be case insensitive. To be easy, I just assume it’s always lower cases. The value of the header can be “127.0.0.1” which indicates it’s from local; otherwise, it’s a different real IP address.

If you think a bit more, you would find a potential problem: what if a HTTP client fake a HTTP header? For example, a remote client adds a header with same name “x-real-ip” with “127.0.0.1”. Very fair concern and it seems to have been thought about. It turns out that if there is a header with the same name, Nginx would overwrite the value with a real source IP address. So this approach is pretty reliable.

Still, there is a potential problem. What if the client connects to the back end server directly? Then it can succeed to fool the back end server. To make sure it’s not the case, you want to block the back end server like Tomcat from responding direct requests as described in this article.

This entry was posted in Software Development and tagged , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

2 Comments

  1. Ben
    Posted February 20, 2014 at 6:42 am | Permalink

    > It has not yet an issue for me because the API for retrieving the header value seems to be case insensitive.

    The API *must* handle header field names case-insensitive. HTTP-1.1 requires this as described in http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html

    If you need similar features for Apache HTTP servers, take a look at X-Forwarded-For and/or ProxyPreserveHost, depending on your needs at the backend server.

  2. Posted February 20, 2014 at 11:54 am | Permalink

    Hi Ben,

    Thanks for the comment. You are right that the protocol itself says the header names are case sensitive. The API I used may have normalized the names so it gets me value regardless the cases in my header name. I felt a little strange while using it, but didn’t dig down.

    Steve

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

  • NEED HELP?


    My company has created products like vSearch ("Super vCenter"), vijavaNG APIs, EAM APIs, ICE tool. We also help clients with virtualization and cloud computing on customized development, training. Should you, or someone you know, need these products and services, please feel free to contact me: steve __AT__ doublecloud.org.

    Me: Steve Jin, VMware vExpert who authored the VMware VI and vSphere SDK by Prentice Hall, and created the de factor open source vSphere Java API while working at VMware engineering. Companies like Cisco, EMC, NetApp, HP, Dell, VMware, are among the users of the API and other tools I developed for their products, internal IT orchestration, and test automation.