[Logwatch] IPTables support

Stephan Borg osgiliath@consultant.com
27 Jul 2002 21:05:49 +1000


--=-EGUtNSUSlMFl7MXXkCIO
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hello all,

I currently use LogWatch 2.6 that comes with Redhat 7.3. I looked around
for someone elses postings for a modified kernel script to accept
IPTables entries but couldn't find one (maybe its just me).

I've attached a modified script and a diff for future use.

The only pre-requisites are:
- in your IPTables config, include a --log-prefix with the word REJ or
DROP. Anything else is considered an ACCEPT.
- although not necessary, follow the --log-prefix with a space eg, 
--log-prefix "ICMP_PONG "

I'm sure its not perfect - so feel free to modify.

Regards,
-- 

Stephan Borg
Osgiliath P/L (ACN: 095 048 981)
Mobile: 0402 789 788
Email: osgiliath@consultant.com

--=-EGUtNSUSlMFl7MXXkCIO
Content-Description: 
Content-Disposition: attachment; filename=logwatch.diff
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1

114,133d113
<    } elsif( ($chain,$if,$ip,$proto,$port) =3D ( $ThisLine =3D~ /(.*)IN=3D=
(\w+) .*SRC=3D(\S*) .*PROTO=3D(\w+) .*DPT=3D([0-9]+)/ ) ){
<       for ($chain) {
<                s/^\s+//;
<                s/\s+$//;
<            };
<       $host =3D LookupIP($ip);
<       $proto =3D lc($proto);
<       $port =3D LookupService($port, $proto);
<       if ($port ne "auth") { # don't care about auth
<          if ($chain =3D~ /REJ/) {
<              $RejectCount{$host}++;
<              $Rejected{$host}{"$port\t\($proto,$if,$chain\)"}++;
<          } elsif ($chain =3D~ /DROP/) {
<              $DenyCount{$host}++;
<              $Denied{$host}{"$port\t\($proto,$if,$chain\)"}++;
<          } else {
<              $AcceptCount{$host}++;
<              $Accepted{$host}{"$port\t\($proto,$if,$chain\)"}++;
<          }
<       }

--=-EGUtNSUSlMFl7MXXkCIO
Content-Description: 
Content-Disposition: attachment; filename=kernel
Content-Transfer-Encoding: quoted-printable
Content-Type: text/x-perl; charset=ISO-8859-1

#!/usr/bin/perl -w
##########################################################################
# $Id: kernel,v 1.8 2002/03/28 05:00:00 kirk Exp $
##########################################################################
# $Log: kernel,v $
# Revision 1.8  2002/03/28 05:00:00  kirk
# - Implemented several bug fixes and patches that have been sent in
# - Fixed a possible root exploit using a race condition in /tmp
# - Fixed bugs 46371, 56191, 58578, 61202, 61829, 61831, 61832 from bugzill=
a.redhat.com
#
# Revision 1.7  2000/09/22 15:59:05  kirk
# Prepping for Version 2.0.1
#
# Revision 1.6  2000/09/22 14:47:04  kirk
# *** empty log message ***
#
# Revision 1.5  1999/02/23 00:39:54  kirk
# Added code written by Fabrizio Zeno Cornelli <zeno@filibusta.crema.unimi.=
it>.
#
# Revision 1.4  1998/04/08 18:32:03  kirk
# Applied changes submitted by Luuk de Boer <luuk_de_boer@pi.net>.. Thanks!
#
# Revision 1.3  1998/02/23 01:16:57  kirk
# Getting ready for a first distribution
#
# Revision 1.2  1998/02/22 22:36:28  kirk
# Created named...
#
# Revision 1.1  1998/02/22 21:45:41  kirk
# Added kernel message processing
#
##########################################################################

########################################################
# This was written and is maintained by:
#    Kirk Bauer <kirk@kaybee.org>
#
# Please send all comments, suggestions, bug reports,
#    etc, to kirk@kaybee.org.
#
########################################################

$Detail =3D $ENV{'LOGWATCH_DETAIL_LEVEL'};
#$MaxFlood =3D $ENV{'MAXFLOOD'};
$MaxFlood =3D 10;
$MaxNum =3D0;

sub LookupIP {
   my ($name, $a1, $a2,$a3,$a4,$PackedAddr,$Addr);
   $Addr =3D $_[0];
   ($a1,$a2,$a3,$a4) =3D split /\./,$Addr;
   $PackedAddr =3D pack('C4',$a1,$a2,$a3,$a4);
   if ($name =3D gethostbyaddr ($PackedAddr,2)) {
      return ($name . " (" . $Addr . ")");
   } else {
      return ($Addr);
   }
}

sub LookupService {
   my ($port, $proto, $service);
   ($port, $proto) =3D ($_[0], $_[1]);
   if ($service =3D getservbyport ($port, $proto)) {
      return ($service);
   }
   return ($port);
}

sub LookupProtocol {
   my ($proto, $name);
   $proto =3D $_[0];
   if ($name =3D getprotobynumber ($proto)) {
      return ($name);
   }
   return ($proto);
}

while (defined($ThisLine =3D <STDIN>)) {
   chomp($ThisLine);
   next if ($ThisLine eq "");
   if ( ($from,$on) =3D ( $ThisLine =3D~ /^Warning: possible SYN flood from=
 ([^ ]+) on ([^ ]+):.+ Sending cookies/ ) ) {
      $Fullfrom =3D LookupIP($from);
      $Fullon =3D LookupIP($on);
      $SYNflood{$Fullon}{$Fullfrom}++;
   } elsif( ($TU,$from,$port,$on) =3D ( $ThisLine =3D~ /IP fw-in deny \w+ (=
\w+) ([^:]+):\d+ ([^:]+):(\d+) / ) ){
      if($MaxNum < ++$TCPscan{$TU}{$from}) {
         $MaxNum =3D $TCPscan{$TU}{$from}
      }
      $port=3D0;
   } elsif ( ($chain,$if,$proto,$ip,$port) =3D ( $ThisLine =3D~ /^Packet lo=
g: (\w+) REJECT (\w+) PROTO=3D([0-9]+) ([^:]+):[0-9]+ [^:]+:([0-9]+)/ ) ){
      $host =3D LookupIP($ip);
      $proto =3D LookupProtocol($proto);
      $port =3D LookupService($port,$proto);
      if ($port ne 'auth') {
         $RejectCount{$host}++;
         $Rejected{$host}{"$port\t\($proto,$if,$chain\)"}++;
      }
   } elsif( ($chain,$if,$proto,$ip,$port) =3D ( $ThisLine =3D~ /^Packet log=
: (\w+) DENY (\w+) PROTO=3D([0-9]+) ([^:]+):[0-9]+ [^:]+:([0-9]+)/ ) ){
      $host =3D LookupIP($ip);
      $proto =3D LookupProtocol($proto);
      $port =3D LookupService($port,$proto);
      if ($port ne "auth") { # don't care about auth
         $DenyCount{$host}++;
         $Denied{$host}{"$port\t\($proto,$if,$chain\)"}++;
      }
   } elsif( ($chain,$if,$proto,$ip,$port) =3D ( $ThisLine =3D~ /^Packet log=
: (\w+) ACCEPT (\w+) PROTO=3D([0-9]+) ([^:]+):[0-9]+ [^:]+:([0-9]+)/ ) ){
      $host =3D LookupIP($ip);
      $proto =3D LookupProtocol($proto);
      $port =3D LookupService($port,$proto);
      if ($port ne "auth") { # don't care about auth
         $AcceptCount{$host}++;
         $Accepted{$host}{"$port\t\($proto,$if,$chain\)"}++;
      }
   } elsif( ($chain,$if,$ip,$proto,$port) =3D ( $ThisLine =3D~ /(.*)IN=3D(\=
w+) .*SRC=3D(\S*) .*PROTO=3D(\w+) .*DPT=3D([0-9]+)/ ) ){
      for ($chain) {
               s/^\s+//;
               s/\s+$//;
           };
      $host =3D LookupIP($ip);
      $proto =3D lc($proto);
      $port =3D LookupService($port, $proto);
      if ($port ne "auth") { # don't care about auth
         if ($chain =3D~ /REJ/) {
             $RejectCount{$host}++;
             $Rejected{$host}{"$port\t\($proto,$if,$chain\)"}++;
         } elsif ($chain =3D~ /DROP/) {
             $DenyCount{$host}++;
             $Denied{$host}{"$port\t\($proto,$if,$chain\)"}++;
         } else {
             $AcceptCount{$host}++;
             $Accepted{$host}{"$port\t\($proto,$if,$chain\)"}++;
         }
      }
   } else{
      # For now, going to ignore all other kernel messages as there
      # are practically an infinite number and most of them are obviously
      # not parsed here at this time.
      #$Kernel{$ThisLine}++;
   }
}

   if (   (keys %SYNflood)
         or (($MaxNum > $MaxFlood) and (keys %TCPscan))
         or (keys %Rejected) or (keys %Denied)
         or (($Detail >=3D 5) and (keys %Kernel)) ) {

      print "\n\n ---------------------- Kernel Begin ---------------------=
---- \n\n";

      if (keys %SYNflood) {
         print "\nWarning: SYN flood on:\n";
         foreach $ThisOne (sort {$a cmp $b} keys %SYNflood) {
            print "   " . $ThisOne . " from:\n";
            foreach $Next (sort {$a cmp $b} keys %{$SYNflood{$ThisOne}}) {
               print "      " . $Next . ": $SYNflood{$ThisOne}{$Next} Time(=
s)\n";
            }
         }
      }
      if (keys %TCPscan and $MaxNum>$MaxFlood) {
         print "\nWarning: ipfwadm scan detected on:\n";
         foreach $ThisOne (sort {$a cmp $b} keys %TCPscan) {
            print "   " . $ThisOne . " from:\n";
            foreach $Next (sort {$a cmp $b} keys %{$TCPscan{$ThisOne}}) {
               $TCPscan{$ThisOne}{$Next}>$MaxFlood &&
                  print "      " . LookupIP($Next). ": $TCPscan{$ThisOne}{$=
Next} Time(s)\n";
            }
         }
      }

      if (keys %Rejected) {
         foreach $host (keys %Rejected) {
            print "\nRejected packets from $host.\n";
            foreach $ThisOne (keys %{$Rejected{$host}}) {
               print "  Port $ThisOne: $Rejected{$host}{$ThisOne} packet(s)=
.\n";
            }
            print "Total of $RejectCount{$host} packet(s).\n";
         }
      }

      if (keys %Denied) {
         foreach $host (keys %Denied) {
            print "\nDenied packets from $host.\n";
            foreach $ThisOne (keys %{$Denied{$host}}) {
               print "  Port $ThisOne: $Denied{$host}{$ThisOne} packet(s).\=
n";
            }
            print "Total of $DenyCount{$host} packet(s).\n";
         }
      }

      if (keys %Accepted) {
         foreach $host (keys %Accepted) {
            print "\nAccepted packets from $host.\n";
            foreach $ThisOne (keys %{$Accepted{$host}}) {
               print "  Port $ThisOne: $Accepted{$host}{$ThisOne} packet(s)=
.\n";
            }
            print "Total of $AcceptCount{$host} packet(s).\n";
         }
      }

      if ( ($Detail >=3D 5) and (keys %Kernel) ) {
         print "\n";
         foreach $ThisOne (sort {$a cmp $b} keys %Kernel) {
            print $Kernel{$ThisOne} . " Time(s): " . $ThisOne . "\n";
         }
      }

      print "\n\n ---------------------- Kernel End -----------------------=
-- \n\n";

   }


   exit(0);



--=-EGUtNSUSlMFl7MXXkCIO--