Revision history for ddosDotPl
Additions:
# ddos.pl 2012.06.29
use constant MAXPERSEC => 25;
# CHAIN: Define whic iptables chain to add rules to
use constant CHAIN => "INPUT";
# $pkt{$IP}{$port}{start} = $tmr;
#$pkt{$IP}{$port}{"$bits[1].$bits[0]"}++;
if ($pkt{$IP}{$port}{count} eq "") { $pkt{$IP}{$port}{count} = THRESH; }
if ($pkt{$IP}{$port}{multi} eq "") { $pkt{$IP}{$port}{multi} = 0; }
$ipt_obj->delete_ip_rule($ip, '0.0.0.0/0', 'filter', CHAIN, 'DROP', {'protocol' => 'udp', 's_port' => $port});
$ipt_obj->delete_ip_rule($ip, '0.0.0.0/0', 'filter', CHAIN, 'DROP', {'protocol' => 'udp', 'd_port' => 53});
$ipt_obj->add_ip_rule($ip, '0.0.0.0/0', 1, 'filter', CHAIN, 'DROP', {'protocol' => 'udp', 's_port' => $port});
$ipt_obj->add_ip_rule($ip, '0.0.0.0/0', 1, 'filter', CHAIN, 'DROP', {'protocol' => 'udp', 'd_port' => 53});
use constant MAXPERSEC => 25;
# CHAIN: Define whic iptables chain to add rules to
use constant CHAIN => "INPUT";
# $pkt{$IP}{$port}{start} = $tmr;
#$pkt{$IP}{$port}{"$bits[1].$bits[0]"}++;
if ($pkt{$IP}{$port}{count} eq "") { $pkt{$IP}{$port}{count} = THRESH; }
if ($pkt{$IP}{$port}{multi} eq "") { $pkt{$IP}{$port}{multi} = 0; }
$ipt_obj->delete_ip_rule($ip, '0.0.0.0/0', 'filter', CHAIN, 'DROP', {'protocol' => 'udp', 's_port' => $port});
$ipt_obj->delete_ip_rule($ip, '0.0.0.0/0', 'filter', CHAIN, 'DROP', {'protocol' => 'udp', 'd_port' => 53});
$ipt_obj->add_ip_rule($ip, '0.0.0.0/0', 1, 'filter', CHAIN, 'DROP', {'protocol' => 'udp', 's_port' => $port});
$ipt_obj->add_ip_rule($ip, '0.0.0.0/0', 1, 'filter', CHAIN, 'DROP', {'protocol' => 'udp', 'd_port' => 53});
Deletions:
use constant MAXPERSEC => 40;
$ipt_obj->delete_ip_rule($ip, '0.0.0.0/0', 'filter', 'INPUT', 'DROP', {'protocol' => 'udp', 's_port' => $port});
$ipt_obj->delete_ip_rule($ip, '0.0.0.0/0', 'filter', 'INPUT', 'DROP', {'protocol' => 'udp', 'd_port' => 53});
$ipt_obj->add_ip_rule($ip, '0.0.0.0/0', 1, 'filter', 'INPUT', 'DROP', {'protocol' => 'udp', 's_port' => $port});
$ipt_obj->add_ip_rule($ip, '0.0.0.0/0', 1, 'filter', 'INPUT', 'DROP', {'protocol' => 'udp', 'd_port' => 53});
Additions:
%%
#!/usr/bin/perl
# ddos.pl 2012.05.23
use constant BLOCKFILE => "/root/ddos.dns";
use constant NETDEV => "eth0";
use constant NETMASK => [ "127.0.0.0/8", "10.0.0.0/8" ];
use constant DEBUG => 0;
use constant THRESH => 10;
use constant MAXPERSEC => 40;
use constant MAXCOUNT => 64;
use constant MAXMULTI => 8;
use constant MAXBLOCKS => 4;
use constant BASETIME => 225/128; # Approx. 2 seconds
my $lastReset;
# Reload array data every hour
$h = strftime("%H", localtime);
if ($lastReset != $h) {
$lastReset = $h;
getBlockfile(%pkt);
}
if ($pkt{$IP}{$port}{multi}>MAXMULTI) { $pkt{$IP}{$port}{multi}=MAXMULTI; }
sub getBlockfile {
if (-e BLOCKFILE) {
# Read blockfile into memory
open FH, BLOCKFILE; my @LINES = <FH>; close(FH);
foreach $line (@LINES) {
@data = split(/[ \t]+/, $line);
if (($data[0]) && ($data[0] ne "#IP:Port")) {
@tmp = split(/:/, $data[0]);
$IP = $tmp[0]; $IP =~ s/^\#//;
$port = $tmp[1];
$pkt{$IP}{$port}{multi} = $data[1];
if ($pkt{$IP}{$port}{multi} eq "") { $pkt{$IP}{$port}{multi} = 0; }
$pkt{$IP}{$port}{count} = $data[2];
if ($pkt{$IP}{$port}{count} == 0) { $pkt{$IP}{$port}{count} = THRESH; }
if (! $pkt{$IP}{$port}{timer}) { $pkt{$IP}{$port}{timer} = $pkt{$IP}{$port}{count}; }
if (! $pkt{$IP}{$port}{start}) { $pkt{$IP}{$port}{start} = $data[3]; }
$pkt{$IP}{$port}{block} = 1;
if (substr($data[0], 0, 1) eq "#") {
$pkt{$IP}{$port}{block} = 2;
$pkt{$IP}{$port}{count} = 0;
iptUpdate($IP, $port, "I");
if (DEBUG) { print "Loading ($pkt{$IP}{$port}{block}) $IP:$port\n"; }
} else {
# Create new blockfile
open FH, ">", BLOCKFILE;
print FH "#IP:Port #Multi #Count #Start #Expires\n";
close(FH);
print FH setLen("$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start} $expire\n";
print FH setLen("#$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start} $expire\n";
print FH setLen("$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start} $expire\n";
if (length $str < 16) { $str .= " "; }
%%
#!/usr/bin/perl
# ddos.pl 2012.05.23
use constant BLOCKFILE => "/root/ddos.dns";
use constant NETDEV => "eth0";
use constant NETMASK => [ "127.0.0.0/8", "10.0.0.0/8" ];
use constant DEBUG => 0;
use constant THRESH => 10;
use constant MAXPERSEC => 40;
use constant MAXCOUNT => 64;
use constant MAXMULTI => 8;
use constant MAXBLOCKS => 4;
use constant BASETIME => 225/128; # Approx. 2 seconds
my $lastReset;
# Reload array data every hour
$h = strftime("%H", localtime);
if ($lastReset != $h) {
$lastReset = $h;
getBlockfile(%pkt);
}
if ($pkt{$IP}{$port}{multi}>MAXMULTI) { $pkt{$IP}{$port}{multi}=MAXMULTI; }
sub getBlockfile {
if (-e BLOCKFILE) {
# Read blockfile into memory
open FH, BLOCKFILE; my @LINES = <FH>; close(FH);
foreach $line (@LINES) {
@data = split(/[ \t]+/, $line);
if (($data[0]) && ($data[0] ne "#IP:Port")) {
@tmp = split(/:/, $data[0]);
$IP = $tmp[0]; $IP =~ s/^\#//;
$port = $tmp[1];
$pkt{$IP}{$port}{multi} = $data[1];
if ($pkt{$IP}{$port}{multi} eq "") { $pkt{$IP}{$port}{multi} = 0; }
$pkt{$IP}{$port}{count} = $data[2];
if ($pkt{$IP}{$port}{count} == 0) { $pkt{$IP}{$port}{count} = THRESH; }
if (! $pkt{$IP}{$port}{timer}) { $pkt{$IP}{$port}{timer} = $pkt{$IP}{$port}{count}; }
if (! $pkt{$IP}{$port}{start}) { $pkt{$IP}{$port}{start} = $data[3]; }
$pkt{$IP}{$port}{block} = 1;
if (substr($data[0], 0, 1) eq "#") {
$pkt{$IP}{$port}{block} = 2;
$pkt{$IP}{$port}{count} = 0;
iptUpdate($IP, $port, "I");
if (DEBUG) { print "Loading ($pkt{$IP}{$port}{block}) $IP:$port\n"; }
} else {
# Create new blockfile
open FH, ">", BLOCKFILE;
print FH "#IP:Port #Multi #Count #Start #Expires\n";
close(FH);
print FH setLen("$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start} $expire\n";
print FH setLen("#$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start} $expire\n";
print FH setLen("$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start} $expire\n";
if (length $str < 16) { $str .= " "; }
%%
Deletions:
# ddos.pl 2012.04.09
use constant BLOCKFILE => "/root/ddos.dns";
use constant NETDEV => "eth0";
use constant NETMASK => [ "127.0.0.0/8", "10.0.0.0/8" ];
use constant DEBUG => 0;
use constant THRESH => 10;
use constant MAXPERSEC => 40;
use constant MAXCOUNT => 64;
use constant MAXMULTI => 8;
use constant MAXBLOCKS => 4;
use constant BASETIME => 225/128; # Approx. 2 seconds
#------------ Initialize array with stored data ------------#
if (-e BLOCKFILE) {
# Read blockfile into memory
open FH, BLOCKFILE; my @LINES = <FH>; close(FH);
@data = split(/[ \t]+/, $line);
if (($data[0]) && ($data[0] ne "#IP:Port")) {
@tmp = split(/:/, $data[0]);
$IP = $tmp[0]; $IP =~ s/^\#//;
$port = $tmp[1];
$pkt{$IP}{$port}{multi} = $data[1];
if ($pkt{$IP}{$port}{multi} eq "") { $pkt{$IP}{$port}{multi} = 0; }
$pkt{$IP}{$port}{count} = $data[2];
if ($pkt{$IP}{$port}{count} == 0) { $pkt{$IP}{$port}{count} = THRESH; }
$pkt{$IP}{$port}{timer} = $pkt{$IP}{$port}{count};
$pkt{$IP}{$port}{start} = $data[3];
$pkt{$IP}{$port}{block} = 1;
if (substr($data[0], 0, 1) eq "#") {
$pkt{$IP}{$port}{block} = 2;
$pkt{$IP}{$port}{count} = 0;
iptUpdate($IP, $port, "I");
if (DEBUG) { print "Loading ($pkt{$IP}{$port}{block}) $IP:$port\n"; }
} else {
# Create new blockfile
print FH "#IP:Port #Multi #Count #Start #Expires\n";
# $pkt{$IP}{$port}{start} = $tmr;
#$pkt{$IP}{$port}{"$bits[1].$bits[0]"}++;
if ($pkt{$IP}{$port}{multi}>MAXMULTI) { $pkt{$IP}{$port}{multi}=MAXMULTI; }
print FH setLen("$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start} $expire\n";
print FH setLen("#$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start} $expire\n";
print FH setLen("$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start} $expire\n";
if (length $str < 16) { $str .= " "; }
}%%
Revision [2858]
Edited on 2012-04-16 13:18:33 by JeffTaylor [Updates to default values and timeouts]Additions:
# ddos.pl 2012.04.09
use constant NETMASK => [ "127.0.0.0/8", "10.0.0.0/8" ];
use constant THRESH => 10;
$pkt{$IP}{$port}{count} = 0;
open DUMP, "$netrules" or die "Invalid tcpdump defined\n";
$pkt{$IP}{0}{block} = 0;
# $pkt{$IP}{$port}{start} = $tmr;
$expire = $pkt{$IP}{$port}{start} + ((($pkt{$IP}{$port}{block} + 1) ** $pkt{$IP}{$port}{multi}) * $pkt{$IP}{$port}{timer} * BASETIME);
if ($pkt{$IP}{$port}{count} < 1) { $pkt{$IP}{$port}{count} = 0; }
use constant NETMASK => [ "127.0.0.0/8", "10.0.0.0/8" ];
use constant THRESH => 10;
$pkt{$IP}{$port}{count} = 0;
open DUMP, "$netrules" or die "Invalid tcpdump defined\n";
$pkt{$IP}{0}{block} = 0;
# $pkt{$IP}{$port}{start} = $tmr;
$expire = $pkt{$IP}{$port}{start} + ((($pkt{$IP}{$port}{block} + 1) ** $pkt{$IP}{$port}{multi}) * $pkt{$IP}{$port}{timer} * BASETIME);
if ($pkt{$IP}{$port}{count} < 1) { $pkt{$IP}{$port}{count} = 0; }
Deletions:
use constant NETMASK => [ "127.0.0.0/8", "10.0.0.0/8", "192.168.0.0/16" ];
use constant THRESH => 6;
open DUMP, "$netrules" or die;
$pkt{$IP}{$port}{start} = $tmr;
$expire = $pkt{$IP}{$port}{start} + ((($pkt{$IP}{$port}{block} * 2) ** $pkt{$IP}{$port}{multi}) * $pkt{$IP}{$port}{timer} * BASETIME);
if ($pkt{$IP}{$port}{count} < 1) { $pkt{$IP}{$port}{count} = 1; }
Additions:
# ddos.pl 2012.04.04
# by Jeff Taylor (Shdwdrgn)
# BLOCKFILE: where to store IP and port information
# NETDEV: device your DNS service listens on
# NETMASK: add a mask for your server's real or local IP
use constant NETMASK => [ "127.0.0.0/8", "10.0.0.0/8", "192.168.0.0/16" ];
# DEBUG: 0=off, 1=show debug info
use constant DEBUG => 0;
# THRESH: maximum queries on a single port
# MAXPERSEC: maximum number of queries per second
# MAXCOUNT: limits the queries/sec that we observe
# MAXMULTI: Limits how high the multiplier can go
use constant MAXMULTI => 8;
# MAXBLOCKS: If blocking this number of ports or more
# for an IP, start blocking all DNS queries from IP
# BASETIME: used to calculate how long an IP is blocked
use constant BASETIME => 225/128; # Approx. 2 seconds
# Adjust the path to iptables for your system
my $h; my $m; my $s;
my $expire;
my $max;
my $portcount;
my $netrules;
$SIG{__DIE__} = 'INT_handler';
if (DEBUG) { print "\nEnding script...\n"; }
close(DUMP);
if (DEBUG) { print "* Unloading $IP:$port\n"; }
if (DEBUG) { print "Loading ($pkt{$IP}{$port}{block}) $IP:$port\n"; }
$netrules="";
foreach $IP (@{+NETMASK}) {
if ($netrules) { $netrules .= " and "; }
$netrules .= "not src net $IP";
$netrules = "tcpdump -pnt -i ".NETDEV." $netrules and not udp src port 53 and udp dst port 53 and '(ip[2:2] != 0)' 2>/dev/null |";
open DUMP, "$netrules" or die;
#$url = ($data[5] eq "[1au]") ? $data[7] : $data[6];
if (($pkt{$IP}{$port}{block} > 0) && (DEBUG)) { print "WARNING! $IP:$port adding existing block\n"; }
if (DEBUG) { print "$hms Count: ", scalar(keys %pkt), " \r"; }
if (DEBUG) { print "$hms [$pkt{$IP}{$port}{multi}] ",$max,"Blocking $IP:$port - $pkt{$IP}{$port}{count} hits\n"; }
if (DEBUG) { print "$hms Deleting $IP:$port after $blocked seconds\n"; }
if (DEBUG) { print "$hms Unblocking $IP:$port after $blocked seconds\n"; }
if ($pkt{$IP}{$port}{multi}>MAXMULTI) { $pkt{$IP}{$port}{multi}=MAXMULTI; }
if (($pkt{$IP}{$port}{timer} > 0) && (DEBUG)) { print "WARNING! Removed $IP:$port from array [$pkt{$IP}{$port}{block}]\n"; }
if (($pkt{$IP}{0}{portblock} > 0) && (DEBUG)) { print "WARNING! [$pkt{$IP}{0}{portblock}] Cleanup $IP:port\n"; }
print "Error: tcpdump not found or bad NETMASK defined\n";
}%%
# by Jeff Taylor (Shdwdrgn)
# BLOCKFILE: where to store IP and port information
# NETDEV: device your DNS service listens on
# NETMASK: add a mask for your server's real or local IP
use constant NETMASK => [ "127.0.0.0/8", "10.0.0.0/8", "192.168.0.0/16" ];
# DEBUG: 0=off, 1=show debug info
use constant DEBUG => 0;
# THRESH: maximum queries on a single port
# MAXPERSEC: maximum number of queries per second
# MAXCOUNT: limits the queries/sec that we observe
# MAXMULTI: Limits how high the multiplier can go
use constant MAXMULTI => 8;
# MAXBLOCKS: If blocking this number of ports or more
# for an IP, start blocking all DNS queries from IP
# BASETIME: used to calculate how long an IP is blocked
use constant BASETIME => 225/128; # Approx. 2 seconds
# Adjust the path to iptables for your system
my $h; my $m; my $s;
my $expire;
my $max;
my $portcount;
my $netrules;
$SIG{__DIE__} = 'INT_handler';
if (DEBUG) { print "\nEnding script...\n"; }
close(DUMP);
if (DEBUG) { print "* Unloading $IP:$port\n"; }
if (DEBUG) { print "Loading ($pkt{$IP}{$port}{block}) $IP:$port\n"; }
$netrules="";
foreach $IP (@{+NETMASK}) {
if ($netrules) { $netrules .= " and "; }
$netrules .= "not src net $IP";
$netrules = "tcpdump -pnt -i ".NETDEV." $netrules and not udp src port 53 and udp dst port 53 and '(ip[2:2] != 0)' 2>/dev/null |";
open DUMP, "$netrules" or die;
#$url = ($data[5] eq "[1au]") ? $data[7] : $data[6];
if (($pkt{$IP}{$port}{block} > 0) && (DEBUG)) { print "WARNING! $IP:$port adding existing block\n"; }
if (DEBUG) { print "$hms Count: ", scalar(keys %pkt), " \r"; }
if (DEBUG) { print "$hms [$pkt{$IP}{$port}{multi}] ",$max,"Blocking $IP:$port - $pkt{$IP}{$port}{count} hits\n"; }
if (DEBUG) { print "$hms Deleting $IP:$port after $blocked seconds\n"; }
if (DEBUG) { print "$hms Unblocking $IP:$port after $blocked seconds\n"; }
if ($pkt{$IP}{$port}{multi}>MAXMULTI) { $pkt{$IP}{$port}{multi}=MAXMULTI; }
if (($pkt{$IP}{$port}{timer} > 0) && (DEBUG)) { print "WARNING! Removed $IP:$port from array [$pkt{$IP}{$port}{block}]\n"; }
if (($pkt{$IP}{0}{portblock} > 0) && (DEBUG)) { print "WARNING! [$pkt{$IP}{0}{portblock}] Cleanup $IP:port\n"; }
print "Error: tcpdump not found or bad NETMASK defined\n";
}%%
Deletions:
use constant NETMASK => "10.0.0.0/16";
use constant MAXMULTI => 16;
use constant BASETIME => 450/256;
#$SIG{__DIE__} = 'INT_handler';
print "\nEnding script...\n";
print "* Unloading $IP:$port\n";
print "Loading ($pkt{$IP}{$port}{block}) $IP:$port\n";
open DUMP, "tcpdump -pnt -i ".NETDEV." not src net ".NETMASK." and not udp src port 53 and udp dst port 53 and '(ip[2:2] != 0)' 2>/dev/null |" or die;
$url = ($data[5] eq "[1au]") ? $data[7] : $data[6];
if ($pkt{$IP}{$port}{block} > 0) { print "WARNING! $IP:$port adding existing block\n"; }
print "$hms Count: ", scalar(keys %pkt), " \r";
print "$hms [$pkt{$IP}{$port}{multi}] ",$max,"Blocking $IP:$port - $pkt{$IP}{$port}{count} hits\n";
print "$hms Deleting $IP:$port after $blocked seconds\n";
print "$hms Unblocking $IP:$port after $blocked seconds\n";
if ($pkt{$IP}{$port}{multi}>MAXMULTI) {$pkt{$IP}{$port}{multi}=MAXMULTI;}
if ($pkt{$IP}{$port}{timer} > 0) { print "WARNING! Removed $IP:$port from array [$pkt{$IP}{$port}{block}]\n"; }
if ($pkt{$IP}{0}{portblock} > 0) { print "WARNING! [$pkt{$IP}{0}{portblock}] Cleanup $IP:port\n"; }
%%
Additions:
#--- REQUIRED PERL LIBRARIES ---#
if ($pkt{$IP}{$port}{count} == 0) { $pkt{$IP}{$port}{count} = THRESH; }
print FH "#IP:Port #Multi #Count #Start #Expires\n";
if (($portcount <= 1) && ($pkt{$IP}{0}{block} == 0)) {
if ($pkt{$IP}{0}{portblock} > 0) { print "WARNING! [$pkt{$IP}{0}{portblock}] Cleanup $IP:port\n"; }
my $expire = int($pkt{$IP}{$port}{start} + ((($pkt{$IP}{$port}{block} * 2) ** $pkt{$IP}{$port}{multi}) * $pkt{$IP}{$port}{timer} * BASETIME));
print FH setLen("$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start} $expire\n";
print FH setLen("#$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start} $expire\n";
print FH setLen("$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start} $expire\n";
%%
if ($pkt{$IP}{$port}{count} == 0) { $pkt{$IP}{$port}{count} = THRESH; }
print FH "#IP:Port #Multi #Count #Start #Expires\n";
if (($portcount <= 1) && ($pkt{$IP}{0}{block} == 0)) {
if ($pkt{$IP}{0}{portblock} > 0) { print "WARNING! [$pkt{$IP}{0}{portblock}] Cleanup $IP:port\n"; }
my $expire = int($pkt{$IP}{$port}{start} + ((($pkt{$IP}{$port}{block} * 2) ** $pkt{$IP}{$port}{multi}) * $pkt{$IP}{$port}{timer} * BASETIME));
print FH setLen("$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start} $expire\n";
print FH setLen("#$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start} $expire\n";
print FH setLen("$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start} $expire\n";
%%
Deletions:
if ($portcount <= 1) {
if ($pkt{$IP}{0}{portblock} > 0) { print "$hms [$pkt{$IP}{0}{portblock}] Cleanup $IP:port\n"; }
print FH setLen("$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start}\n";
print FH setLen("#$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start}\n";
print FH setLen("$IP:$port"), " $pkt{$IP}{$port}{multi} $pkt{$IP}{$port}{count} $pkt{$IP}{$port}{start}\n";
}%%
Additions:
use constant BLOCKFILE => "/root/ddos.dns";