Simple Perl Script To Test Mod_Evasive On Your Apache Web Server

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.

Comments

  1. boxman says:

    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 .

  2. Zoyo Red says:

    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”;
    }

  3. BM says:

    Please change line 13 “print $SOCKET “GET /?$_ HTTP/1.0nn”;” with print $SOCKET “GET /?$_ HTTP/1.0\n\n”;

  4. apache tester says:

    I am getting HTTP/1.1 400 Bad Request..any idea why?

  5. 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

  6. 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”;

  7. siva jakkula says:

    #!/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.

Give me your feedback

This site uses Akismet to reduce spam. Learn how your comment data is processed.