This only needs to work on a single subnet and is not for malicious use.
I have a load testing tool written in Python that basically blasts HTTP requests at a URL. I need to run performance tests against an IP-based load balancer, so the requests must come from a range of IP's. Most commercial performance tools provide this functionality, but I want to build it into my own.
The tool uses Python's urllib2 for transport. Is it possible to send HTTP requests with spoofed IP addresses for the packets making up the request?
This is a misunderstanding of HTTP. The HTTP protocol is based on top of TCP. The TCP protocol relies on a 3 way handshake to initialize requests.
alt text http://upload.wikimedia.org/wikipedia/commons/archive/c/c7/20051221162333!300px-Tcp-handshake.png
Needless to say, if you spoof your originating IP address, you will never get past the synchronization stage and no HTTP information will be sent (the server can't send it to a legal host).
If you need to test an IP load balancer, this is not the way to do it.
You want to set the source address used for the connection. Googling "urllib2 source address" gives http://bugs.python.org/file9988/urllib2_util.py. I havn't tried it.
The system you're running on needs to be configured with the IPs you're testing from.
Quick note, as I just learned this yesterday:
I think you've implied you know this already, but any responses to an HTTP request go to the IP address that shows up in the header. So if you are wanting to see those responses, you need to have control of the router and have it set up so that the spoofed IPs are all routed back to the IP you are using to view the responses.
I suggest seeing if you can configure your load balancer to make it's decision based on the X-Forwarded-For header, rather than the source IP of the packet containing the HTTP request. I know that most of the significant commercial load balancers have this capability.
If you can't do that, then I suggest that you probably need to configure a linux box with a whole heap of secondary IP's - don't bother configuring static routes on the LB, just make your linux box the default gateway of the LB device.
You could just use IP aliasing on a Linux box and set up as many IP addresses as you want. The catch is that you can't predict what IP will get stamped in the the IP header unless you set it to another network and set an explicit route for that network. i.e. -
current client address on eth0 = 192.168.1.10/24
server-side:
ifconfig eth0:1 172.16.1.1 netmask 255.255.255.0
client-side:
ifconfig eth0:1 172.16.1.2 netmask 255.255.255.0
route add -net 172.16.1.0/24 gw 172.16.1.1 metric 0
Repeat for as many subnets as you want. Restart apache to set listeners on all the new alias interfaces and you're off and running.