"Fossies" - the Fresh Open Source Software Archive

Member "checksuite-3.3/checksyn" (3 Jun 2010, 4972 Bytes) of package /linux/privat/checksuite-3.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Perl source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 #!/usr/bin/perl -w
    2 ########################################################
    3 # SYN Flood Monitor by Larry Long - larry@djslyde.com  #
    4 # [checksyn] - 7/9 programs in checksuite v3.3         #
    5 #                                                      #
    6 # This greps from the 'netstat' command for connections#
    7 # that have a SYN_RECV state and if we see the same IP #
    8 # multiple times, block it. For use only with Kernel   #
    9 # version 2.2.x and 2.4.x.                             #
   10 ########################################################
   11 use strict;
   12 use Getopt::Std;
   13 use Net::SMTP;
   14 
   15 $ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin';
   16 
   17 # Options: -h (help) -l (log) -o (output to screen) -t (threshold) -e (email)
   18 my %opt;getopts('hlot:e:', \%opt);
   19 usage_info() unless defined @ARGV;
   20 usage_info() if exists $opt{h};
   21 
   22 # Localize variables throughout the rest of the program
   23 my($fw,$email,$host,$total,$chains,$whatfw,$logfile,$logdate,$logsnip,$notify,@chains,@synlist,@nastyips,$ip,@note,$verifychain,$block,$cookie,$ips,%hash,$count,$blockips,@blockips,$synlist,$script,$subject,$threshold);
   24 
   25 # Are we root?
   26 if($> != 0)
   27   {
   28   print STDERR "\n$0: This program HAS to be ran as root!!!\n\nPlease su to root
   29  or use 'sudo $0'!\n";
   30   exit 2;
   31   }
   32 
   33 # Kernel tweaking section... yum!
   34 # Let's enable SYN cookies if the kernel supports it
   35 $cookie = `/bin/ls /proc/sys/net/ipv4/|grep tcp_syncookies`;
   36 if($cookie eq "tcp_syncookies")
   37    {
   38    system("/bin/echo 1 > /proc/sys/net/ipv4/tcp_syncookies");
   39    }
   40 
   41 # Let's bump up the socket queue so the system will have less chance of 
   42 # being overwhelmed with bogus connection requests prior to us blocking them
   43 system("/bin/echo 1280 > /proc/sys/net/ipv4/tcp_max_syn_backlog");
   44 
   45 # Additional optimizations to reduce chances of being DoS'ed
   46 system("/bin/echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout");
   47 system("/bin/echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_time");
   48 system("/bin/echo 1 > /proc/sys/net/ipv4/tcp_window_scaling");
   49 system("/bin/echo 0 > /proc/sys/net/ipv4/tcp_sack");
   50 
   51 # Let's get to it...
   52 # IPTables or IPChains? Let the kernel decide...
   53 # Note, checksyn does not support kernel 2.0 and lower
   54 $whatfw = `uname -r`;
   55 if($whatfw lt 2.4)
   56    {
   57    $fw = "/sbin/ipchains";$block = "DENY";
   58    }
   59 else
   60    {
   61    $fw = "/sbin/iptables";$block = "DROP";
   62    }
   63 
   64 # Define variables
   65 $email = $opt{e};$email = 'root@localhost' unless defined $opt{e};
   66 $threshold = $opt{t};$threshold = '5' unless defined $opt{t};
   67 $host = `hostname`;
   68 $logfile = "/var/log/checksuite.d/checksyn";
   69 $logdate = `date '+%m/%d/%Y %H:%M:%S' `;
   70 $script = " - [checksuite] checksyn\n";
   71 $logsnip = "----\n";
   72 $notify = 0;
   73 $subject = "[checksuite] advisory - possible SYN flood on $host";
   74 chomp $host;chomp $logdate;chomp $script;chomp $subject;
   75 
   76 # Setup the chain...
   77 system("$fw -N SYN >> /dev/null 2>&1");
   78 system("$fw -F SYN >> /dev/null 2>&1");
   79 
   80 # Let's block these guys
   81 @synlist = `netstat -na|grep SYN_RECV`;
   82 foreach $ips (@synlist)
   83    {
   84    @nastyips = split(/\s+/, $ips);
   85    $ip = $nastyips[4];
   86    $ip =~ s/\:\D+//g;
   87    $ip =~ s/\:\d+//g;
   88    $hash{$ip} = $count++;
   89    push @blockips, $ip;
   90    }
   91 for($count = 0; $count < @blockips; $count++)
   92    {
   93    $hash{$blockips[$count]} = $count + 1;
   94    }
   95 foreach $synlist (sort keys %hash)
   96    {
   97    my $total = `netstat -na|grep SYN_RECV|grep $synlist|wc -l`;
   98    if($total >= $threshold)
   99       {
  100       system("$fw -A SYN -s $synlist -j $block");
  101       if($synlist ne "")
  102          {
  103          $notify++;
  104          }
  105       }
  106    }
  107 
  108 @chains = `$fw -nL SYN`;
  109 push(@note, "\n");
  110 push(@note, "\nCurrent list of blocked SYN flooders:\n@chains\n");
  111 
  112 # Define where the output goes
  113 if($notify > 0)
  114    {
  115    log_data() if exists $opt{l};
  116    email_data() if exists $opt{e};
  117    screen_data() if exists $opt{o};
  118    }
  119 
  120 # Subroutines
  121 sub usage_info
  122    {
  123    my $usage = "
  124 Usage: $0 [-h | -lo] [-t <threshold>] [-e <email>]
  125 Options:
  126 -h              display this help
  127 -l              log the output to /var/log/checksuite.d/checksyn
  128 -o              force output to screen
  129 -t      threshold for # of IP entries required for blocking
  130 -e              e-mail the output to a specified e-mail address
  131 Where:
  132 <email>         e-mail address of the recipient of the notification
  133         default is 'root'
  134 \n";
  135    die $usage;
  136    }
  137 
  138 sub log_data
  139    {
  140    open(LOG, ">>$logfile") or die "Uh oh! Can't open logfile!\n";
  141    print LOG $logdate,$script,@note,$logsnip;
  142    close(LOG);
  143    }
  144 
  145 sub screen_data
  146    {
  147    print STDERR @note;
  148    }
  149 
  150 sub email_data
  151    {
  152    my $smtp = Net::SMTP->new($host);
  153    if(! ref($smtp))
  154       {
  155       log_die("Cannot connect to SMTP\n");
  156       }
  157    $smtp->mail($email);
  158    $smtp->to($email);
  159    $smtp->data();
  160    $smtp->datasend("To: " . $email . "\n");
  161    $smtp->datasend("From: Checksuite Notification <root\@$host>\n");
  162    $smtp->datasend("Return-Path: " . $email. "\n");
  163    $smtp->datasend("Subject: " . $subject . "\n");
  164    $smtp->datasend("\n");
  165    $smtp->datasend(@note);
  166    $smtp->datasend();
  167    $smtp->quit();
  168    }