One way to prevent DOS attack is install mod_evasive for apache. I have write the article “Prevent DDoS Attack With mod_evasive in Apache 2“, a while ago.
And now if you want to check if the mod_evasive is working correctly, you can use the simple perl script below:
#!/usr/bin/perl # test.pl: small script to test mod_dosevasive's effectiveness use IO::Socket; use strict; for(0..100) { my($response); my($SOCKET) = new IO::Socket::INET( Proto => "tcp", PeerAddr=> "target.com:80"); if (! defined $SOCKET) { die $!; } print $SOCKET “GET /?$_ HTTP/1.0\r\nHost: 127.0.0.1\r\n\r\n”; $response = <$SOCKET>; print $response; close($SOCKET); }
To run the script:
perl filename.pl
This script will do 100 request to your webserver. And will return the response code. As you know it is return code 200 means it success to connect. But if it is 404 (not found) or 302 (redirect) means that the server block the request or maybe down. If you install mod_evasive for apache then you will see some of the code will return 200 and then later it will return 302, that means your mod_evasive is working correctly.
This perl script only a simple way to test web server security especially simulating DOS attack. There are still lot of way to stress test your web server to know how much request your web server can handle in a certain time.
Great script,but I got an “HTTP/1.1 403 Forbidden” error message instead of 302 code.
and I don’t know why https://boxman.cc isn’t a valid website url .
SSL supported script, try this… 😉
#!/usr/bin/perl
# evasiveTest.pl: small script to test mod_dosevasive’s effectiveness
use Getopt::Long;
use IO::Socket;
use IO::Socket::SSL;
use Parallel::ForkManager;
#use strict;
my $threads = new Parallel::ForkManager(50);
&GetOptions( “help”, “version”, “host|H=s”, “debug”, “port|p=s” );
if ($opt_help) {
print “\nevasiveTest.pl version 0.1\n”;
print “—\nUsage: evasiveTest.pl [Options] –host= –port=\n\n”;
print “OPTIONS:\n”;
print “\t–help\t\t-h Print this help screen\n”;
print “\t–version\t-v Print version number\n”;
print “\t–debug\t\t-d Enable debug option\n\n”;
print “\t–host\t-H IP Adddress or Hostname\n”;
print “\t–port\t\t-p TCP port e.g. 80 or 443\n”;
print “\npress control C to interupt…\n”;
exit 0;
}
if ($opt_version) {
print “\nevasiveTest.pl version 0.1\n”;
print “(C) 2015, foo bar\n\n”;
exit 0;
}
if ($opt_debug) {
print “\n\tDebug option is enabled\n”;
print “\twill create debug output\n”;
}
if ($opt_host && $opt_port) {
print “\npress control C to interupt…\n”;
sleep 3;
if ($opt_debug) {
print STDERR “\n\tDEBUG OUTPUT: Test on $opt_host:$opt_port with 100 connections/sec\n”;
}
for(0..100) {
$threads->start and next;
my($response);
if ($opt_port == “443”) {
my($SOCKET) = new IO::Socket::SSL(“$opt_host:$opt_port”);
if (! defined $SOCKET) { die $!; }
print $SOCKET “GET /?$_ HTTP/1.0\r\n\r\n”;
$response = ;
print $response;
close($SOCKET);
}
if ($opt_port == “80”) {
my($SOCKET) = new IO::Socket::INET( Proto => “tcp”, PeerAddr=> “$opt_host:$opt_port”);
if (! defined $SOCKET) { die $!; }
print $SOCKET “GET /?$_ HTTP/1.0nn”;
$response = ;
print $response;
close($SOCKET);
}
$threads->finish;
}
$threads->wait_all_children();
}
else {
print “ERROR: Usage evasiveTest.pl –help for more information\n”;
}
Please change line 13 “print $SOCKET “GET /?$_ HTTP/1.0nn”;” with print $SOCKET “GET /?$_ HTTP/1.0\n\n”;
I am getting HTTP/1.1 400 Bad Request..any idea why?
can you make sure the url exist?
Zoyo Red says:
June 19, 2015 at 4:05 pm
SSL supported script, try this…
I test your script, because, i have a error 500 with the default perl script.
For test with your script, i need install “Parallel::ForkManager”
perl -MCPAN -e ‘install Parallel::ForkManager’
Then, i test :
I replace all ” in your script.
Start your script
perl /usr/share/doc/libapache2-mod-evasive/examples/test1.pl
syntax error at /usr/share/doc/libapache2-mod-evasive/examples/test1.pl line 50, near “= ;”
syntax error at /usr/share/doc/libapache2-mod-evasive/examples/test1.pl line 58, near “= ;”
Execution of /usr/share/doc/libapache2-mod-evasive/examples/test1.pl aborted due to compilation errors.
nano /usr/share/doc/libapache2-mod-evasive/examples/test1.pl
add ” x2 to the line 50 et 58.
$response = “”;
perl /usr/share/doc/libapache2-mod-evasive/examples/test1.pl
ERROR: Usage evasiveTest.pl –help for more information
…
Then, i can’t test if mod_evasive work or not, to my VPS.
I have test to localhost with a Virtual Machine with Debian Stretch. Ok, work nice.
But, to my VPS, with Debian Sid, i can’t test if mod_evasive work.
I have error 500.
Because wrong virtualhost ?
Because redirect with https ?
Tutoriel for mod_evasive, in french
https://www.visionduweb.eu/wiki/index.php?title=Installer_Apache2_sur_Debian#Installer_mod_evasive
My VirtualHosts configuration.
https://www.visionduweb.eu/wiki/index.php?title=VirtualHosts_des_domaines_enregistr%C3%A9s#Configuration_de_l.27.C3.A9coute_du_port_HTTP_80_2
The error 500 with my VPS :
https://www.visionduweb.eu/wiki/index.php?title=Installer_Apache2_sur_Debian#Tester_mod_evasive
Change this:
print $SOCKET “GET /?$_ HTTP/1.0\n\n”;
into this:
print $SOCKET “GET /?$_ HTTP/1.0\r\nHost: 127.0.0.1\r\n\r\n”;
#!/usr/bin/perl
# evasiveTest.pl: small script to test mod_dosevasive’s effectiveness
use Getopt::Long;
use IO::Socket;
use IO::Socket::SSL;
use Parallel::ForkManager;
#use strict;
my $threads = new Parallel::ForkManager(50);
&GetOptions( “help”, “version”, “host|H=s”, “debug”, “port|p=s” );
if ($opt_help) {
print “\nevasiveTest.pl version 0.1\n”;
print “—\nUsage: evasiveTest.pl [Options] –host= –port=\n\n”;
print “OPTIONS:\n”;
print “\t–help\t\t-h Print this help screen\n”;
print “\t–version\t-v Print version number\n”;
print “\t–debug\t\t-d Enable debug option\n\n”;
print “\t–host\t-H IP Adddress or Hostname\n”;
print “\t–port\t\t-p TCP port e.g. 80 or 443\n”;
print “\npress control C to interupt…\n”;
exit 0;
}
if ($opt_version) {
print “\nevasiveTest.pl version 0.1\n”;
print “(C) 2015, foo bar\n\n”;
exit 0;
}
if ($opt_debug) {
print “\n\tDebug option is enabled\n”;
print “\twill create debug output\n”;
}
if ($opt_host && $opt_port) {
print “\npress control C to interupt…\n”;
sleep 3;
if ($opt_debug) {
print STDERR “\n\tDEBUG OUTPUT: Test on $opt_host:$opt_port with 100 connections/sec\n”;
}
for(0..100) {
$threads->start and next;
my($response);
if ($opt_port == “443”) {
my ($SOCKET) = new IO::Socket::SSL(PeerAddr => “$opt_host:$opt_port”,SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE);
if (! defined $SOCKET) { die $!; }
print $SOCKET “GET /?$_ HTTP/1.0\r\n\r\n”;
$response = ;
print $response;
close($SOCKET);
}
if ($opt_port == “80”) {
my($SOCKET) = new IO::Socket::INET( Proto => “tcp”, PeerAddr=> “$opt_host:$opt_port”);
if (! defined $SOCKET) { die $!; }
print $SOCKET “GET /?$_ HTTP/1.0\n\n”;
$response = ;
print $response;
close($SOCKET);
}
$threads->finish;
}
$threads->wait_all_children();
}
else {
print “ERROR: Usage evasiveTest.pl –help for more information\n”;
}
–> Disabled SSL certificate check as i am using self-signed certificate… in produciton environment, don’t disable it.