views:

1101

answers:

8

I have written an ASP.NET application, and in this application I log the request IP address. And I also serve different content according to different IP range.

My question is, in my limited test environment, I only have 5 machines, each machine has only 1 IP address, I want to test fully about the function of my IP address based ASP.NET, so in my situation how to create HTTP request which contains arbitrary IP address beyond the 5 IP address of my test machines?

Solution in .Net/C# is appreciated. But any existing tool is appreciated as well.

EDIT1: I am writing a school education web application which serve different content to student from different cities. Different cities have different classes/seminar/training and I want to display the most revelant content according to (proxy) address of the branch of the school in specific city.

+1  A: 

The IP comes from the TCP/IP headers, not the "real" body of the HTTP request. So it's non trivial to forge. But if you're on a LAN, you can just use static IPs to test.

Matthew Flaschen
@Matthew, sorry I am not on a LAN. The web site is for some distributed areas, and based on the different IP from the different areas I serve different content. Any ideas to make the test easy?
George2
@George2: If you are not on a LAN how do your 5 machines connect to each other??
AnthonyWJones
My bad English, I mean currently my 5 machines are from the same LAN, but I want to test scenarios when machines are not in a LAN, e.g. a machine which is from England connects to my server located in U.S. something like this. Any ideas.
George2
Like I said, since your machines are on a LAN, just manually set test static IPs. That will allow you as close a real world test as you're going to get, and hopefully prepare for when you have real far-flung users. Or, just unit-test the part of the code that actually decides what to serve? E.g. make a method:HttpResponse getCustomizedHTTPResponse(IPAddress userIP)Then, just unit test that method.
Matthew Flaschen
@Matthew, I agree. But I want to simulate real scenarios as much as possible. Any solutions?
George2
Why not static IPs?
Matthew Flaschen
+2  A: 

You should not depend on IP addresses. If one of your clients is behind any sort of proxy server or Network Address Transalation device, then they will not have the IP address range you expect. Even if your current network has no such devices, it makes little sense for your application to restrict the ways in which the network can change in the future.

You should use a real authentication mechanism to determine who your clients really are. IP addresses are explicitly not designed to identify computers.


EDIT in response to George's edit.

Your scenario is one in which you should definitely not depend on IP addresses. You want to depend on the IP address as a stand-in for the geographic location. That's just lazy design. The fact that IP addresses happen to have some indirect correspondence to geographic location is nothing more than an artifact of the process with which they are (currently) assigned.

Instead, if geographic location matters, then your clients should tell the server what their location is! Then it will always be accurate, even if the network changes.

John Saunders
@John, I agree with your points in general senses. But in my situation proxy is fine, for the same proxy I just return the same content, and it is by design. BTW: could we come to my original question? Any ideas? :-)
George2
@George: Hi again, and it's not fine for a piece of software to so tightly restrict the network infrastructure. If your Network people want to change the network, for legitimate purposes, your software will stop working. You should keep the "Application" layer independant of the "Network" layer. As to how to test it, unit testing would solve most of the problem. Beside that, try virtual machines, where you can construct the network between them as you like. You can even reproduce what will happen to your code when the network changes.
John Saunders
I assume he's just doing geolocation. E.g. if you get a customer in Spain, serve them a website in Spanish by default. Obviously, this is not safe to use for authentication.
Matthew Flaschen
+1  A: 

Spoofing IP addresses is not possible (or at least not easy at all) in windows because of the raw socket limitations .. etc.

You might use hping tool under linux, or WinPcap library for windows to generate raw packets, but you gonna spend lots of time for nothing.

I guess the best way is to set the IPs of your 5 machines manually into different IPs (one from each range you use).

Aziz
@Aziz, why using winpcap to generate raw package will "spend lots of time for nothing"?
George2
because you'll spend time learning how to use it, then realize that it only sends ethernet-layer packets, so you have to implement IP, TCP, and HTTP yourself! ... just doesn't work :)
Aziz
+1  A: 

One option is to change your logic to look at IP Address or the X-Forwarded-For header. This header is often used to indicate the originating IP address when a request goes through a proxy server. While yes you don't need to take into account proxies here but doing so will give you a very very easy way to test your logic.

I think this will be your quickest route rather then trying to spoof IP addresses.

Edit

        Uri uriObj = new Uri("http://localhost");
        HttpWebRequest request =
         (HttpWebRequest)WebRequest.CreateDefault(uriObj);

        request.Headers.Add("X-Forwarded-For", "125.125.125.125");

        WebResponse response = request.GetResponse();
        StreamReader reader = new StreamReader(response.GetResponseStream());
        Console.WriteLine(reader.ReadToEnd());

Edit

You need to change your server side logic to look like:

    string ip = Request.Headers.Get("X-Forwarded-For");
    if (string.IsNullOrEmpty(ip))
    {
        ip = Request.UserHostAddress;
    }

This basically says if the header is included then use that otherwise use the IP address they tell me. This way both your test code and real users will be picked up.

JoshBerke
Cool, Josh! Any .Net sample code?
George2
@Josh, I have tested using X-Forwarded-For won't work. What we got from server is the actual IP address of requesting client, not the value we put in referer. Here is my code used at ASP.Net server side. Any comments or anything wrong? HttpContext.Current.Request.UserHostAddress
George2
+1  A: 

Set up your site on a lan, create virtual machines, and assign those machines different static IP addresses on the lan. Change the IP ranges in your app to those on the lan, make sure it works, then set the ranges to what you want in the production version of your app. You should have a development version of the site, and there's no reason that can't be on a lan.

Jared
+2  A: 

Here at work we use virtual machines. You can have as many ips as you want. They are several products around. We mostly use http://www.virtualbox.org/ (its free...lol).

Just build one and then copy/paste. Configure the fixed ips. And thats it; you can even test all in the same physical pc!

Hope this help... :)

Lucas
+1  A: 

ooops. wrong stuff

wrong for what?? :-)
George2
A: 

Perhaps you can test your logic by simply sending an http "referer" header. For example:

Dim request As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create("www.MySite.com")
request.Referer = "http://1.2.3.4"
Dim response As System.Net.HttpWebResponse = request.GetResponse()
CB
Thanks CB, you mean put arbitrary IP address in MyIpAddress header?
George2
You could also put the _location_ in a header, and not use IP addresses at all...
John Saunders
Yes. You can put any IP address in the header.
CB
Then at server side, I could get original request's IP address from ASP.Net http request object instance, which is the same I set in Referer header?
George2
Don't overload referer, that is header with a specific purpose.
JoshBerke
Yes. You can then get the Referer from your "Request.UrlReferrer".I tried it - it works...
CB
It only works if it's been set. It will not be set, for instance, if the request is generated by JavaScript. Do not use the Referrer header for anything but its intended purpose. Read the HTTP specifications. You'll also learn whether there is a header intended to convey geographic location.
John Saunders
I'm not sure what's wrong with manually setting the "referer" header just for testing purposes - such as George2 needed here.
CB
Hi CB, I have tested using referer won't work. What we got from server is the actual IP address of requesting client, not the value we put in referer. Here is my code used at ASP.Net server side. Any comments or anything wrong?HttpContext.Current.Request.UserHostAddress
George2
Hi George2. What you need is: HttpContext.Current.Request.UrlReferrer
CB