« November 2008 | Main | January 2009 »

7 posts from December 2008

12/17/2008

Using Groovy to Verify the X-Forwarded-For Header

I love and hate scripting languages. Mostly, it is due to me not knowing which one to really spend a lot of time getting proficient with. Perl, Python, Ruby, Groovy? They all have their appeal and that's half the problem for me. I can't decide. PowerShell aside, my life as an IIS administrator prior to moving to apache, tomcat, jboss, etc. in addition to IIS, meant not having to drop down to the command line all that often—usually just to register DLLs. Sure, VBScript was there but that wasn't all that sexy enough to get me to use it. Also, what I'm looking for in a scripting language is the ability to quickly write things that I can use to pull stats, parse logs, scrape data from web pages, automate deployments—things like that but I don't want to have to store binaries across hundreds of different servers. I just want to run them all locally.

Any how, one common question that comes up at work a lot involves testing applications that reside behind proxies that insert X-Forwarded-For headers. I don't really know how much a BigIP LTM costs but we don't utilize them across all environments—there is little point load-balancing development boxes when those boxes could be developer workstations or single servers. Since the BigIP is, however, inserting headers into the request in order to record the IP address of the client machine, developers do need a way to mimic this behavior in order to be able to test their own applications as well as to simply understand what is going on when the BigIP does this. I've been surprised by the amount of traffic google has referred to this site by folks searching for "X-Forwarded-For". 350 visits over the past 4 months for the search queries containing "x-forwarded-for".

The X-Forwarded-For header is a mechanism for proxies that mask the incoming IP address of the client to provide that IP address of the client to the upstream server. Proxies make requests on behalf of the client that is requesting access to a particular resource—a client does not pass-through a proxy. The trouble with proxies in the past prior to creation of the X-Forwarded-For header was that the web or application server sitting behind the proxy only saw the IP address of the proxy—not the browser. This makes it tough to restrict access to a particular resource if your tens of thousands of users scattered all over the world all share the same IP of your local proxy or load-balancing proxy. It also makes it difficult to geo-locate the IP address for that credit card transaction.

The trouble with proxies after development of the X-Forwarded-For header is that the web server still only sees the IP address of the proxy machine. The web or application server needs modifications made in order to pull the IP address out of the request header. Take something simple such as logging a URI request in an access log. In a previous article, I detailed changes that need to be made to the Tomcat access log valve in order to replace the host IP with the IP address stored in the X-Forwarded-For header. Similar changes need to be made to the Apache web server CustomLog format but this article will stick with tomcat because that is probably what you are running on your local workstation.

The following groovy script can be used to mimic the behavior of a BigIP that is inserting an X-Forwarded-For header in a browser request. The script and tomcat access log valve changes below are only used for illustrative purposes only and you will need to use your imagination to some extent because all I'm really trying to accomplish here is an attempt to convey what actually occurs in this type of infrastructure.

If your tomcat server is currently utilizing a combined or common log file pattern, you'll change it to utilize the following pattern instead, (which is the combined log file pattern with the addition of x-forwarded-for logging).

  pattern="%h %{X-Forwarded-For}i %l %u %{User-Agent}i %t %r %s %b %{Referer}i"

What this pattern would provide on a production server is the IP address of the requesting host (in this case the BigIP) and the IP address(es) stored in the X-Forwarded-For header that the BigIP inserts into the request. For our testing purposes, we're going to pretend that your local machine address (127.0.0.1) is the "BigIP proxy" and that the IP address in the groovy script is your actual machine address. Again, this is simply for illustrative purposes only but it does convey what is actually occurring in production. Now for the script:


#!/usr/bin/env groovy
// setup connection
def url = new URL("http://localhost:8080/")
def connection = url.openConnection()
connection.setRequestProperty("X-Forwarded-For","192.168.254.100")
connection.setRequestProperty("User-Agent","benevolent-robot/allsortsandnotions.blogspot.com")

if(connection.responseCode == 200){
println "Connection successful"
}
else{
println "Ouchy! Error!"
}


As you can see, all this script does is send a single HTTP GET to my local tomcat instance and inserts an X-Forwarded-For header into the HTTP Request. In this case, the IP address that I'm pretending is my actual machine address is 192.168.254.100. Tail your tomcat access logs (assuming your running linux, OS X, or cygwin locally), and you'll see what gets recorded in the log files:


$ tail -f localhost_access_log.2008-12-16.txt
127.0.0.1 192.168.254.100 - - benevolent-robot/allsortsandnotions.blogspot.com [
16/Dec/2008:19:43:41 -0500] GET / HTTP/1.1 200 7857 null


The addresses showing up in the log file are 127.0.0.1, which I am pretending represents my proxy server/bigip address in this example and 192.168.254.100, which is the X-Forwarded-For proxy inserted IP address. Using similar code, you can script your own tests inserting any address into the X-Forwarded-For section in order to validate whatever it is that your code needs to validate. If you were to apply the same pattern to your production tomcat access log setting, the first IP address you would see would be the IP address of the BigIP. The second IP address you would see would be the IP Address of your customer.

12/05/2008

JBoss Application Server 5.0 GA Released

The 5.0 release of the JBoss Application Server went gold today. Run, don't walk, to the JBoss community site and grab your copy today!

There are lots of new features and changes—the release notes are very complete.

12/04/2008

Apache Tomcat 4.1.39 Stable Released

Yesterday I got the news that tomcat 4.1.39 stable was released. There are a couple of important security vulnerabilities addressed in this release. One is an Information Disclosure vulnerability and the other is a Directory Traversal vulnerability.

There are two additional vulnerabilities addressed in this release, one related to cross-site scripting which is rated low risk and the other moderately risky—but rather ominous sounding—session hijacking vulnerability.

Downloads are available at a tomcat mirror near you. Release notes also detail bug fixes included in this release.