changeset 69:b090ddfccdab

Cleanups. Improve IP/host definitions.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 26 Aug 2009 15:19:08 +0300
parents bac5931b8312
children adb4795f451e
files README example.conf maltfilter
diffstat 3 files changed, 46 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/README	Tue Aug 18 03:47:16 2009 +0300
+++ b/README	Wed Aug 26 15:19:08 2009 +0300
@@ -1,4 +1,4 @@
-Malicious Attack Livid Termination Filter daemon (maltfilter) v0.16.0
+Malicious Attack Livid Termination Filter daemon (maltfilter) v0.16.2
 =====================================================================
 Programmed by Matti 'ccr' Hämäläinen <ccr@tnsp.org>
 (C) Copyright 2009 Tecnic Software productions (TNSP)
--- a/example.conf	Tue Aug 18 03:47:16 2009 +0300
+++ b/example.conf	Wed Aug 26 15:19:08 2009 +0300
@@ -22,11 +22,14 @@
 ## set this if you wish to have a surefire open channel from some host, even in
 ## the case someone tries to spoof IPs for denial of service.
 ##
-## NOTICE! This setting supports only IPv4 addresses, no IPv6 or DNS names.
-## You can have any number of NOACTION_IPS settings.
+## NOTICE! This setting supports only IPv4 addresses and address ranges, no
+## IPv6 or DNS names. You can have any number of NOACTION_IPS settings.
 #NOACTION_IPS = "192.121.86.15"
 #NOACTION_IPS = "74.125.45.100"
 
+## Also ranges defined via CIDR notation can be used:
+#NOACTION_IPS = "213.129.224.0/19"
+
 ## For how many hours to keep general information about IP. Affects from
 ## how long period statistics dump shows data. Also hitcount thresholds
 ## take the old data into account, meaning that if FILTER_MAX_AGE < GLOBAL_MAX_AGE
@@ -38,10 +41,10 @@
 ## settings below.
 #PASSWD = "/etc/passwd"
 
-## Set range of system account UIDs here, default is 1-100.
+## Set range of system account UIDs here, default is 1-999.
 ## Root account is handled by CHK_ROOT_SSH_PWD check.
 #SYSACCT_MIN_UID     = 1
-#SYSACCT_MAX_UID     = 100
+#SYSACCT_MAX_UID     = 999
 
 
 #############################################################################
--- a/maltfilter	Tue Aug 18 03:47:16 2009 +0300
+++ b/maltfilter	Wed Aug 26 15:19:08 2009 +0300
@@ -12,7 +12,7 @@
 use Net::DNS;
 use LWP::UserAgent;
 
-my $progversion = "0.16.0";
+my $progversion = "0.16.2";
 my $progbanner =
 "Malicious Attack Livid Termination Filter daemon (maltfilter) v$progversion\n".
 "Programmed by Matti 'ccr' Hamalainen <ccr\@tnsp.org>\n".
@@ -30,7 +30,7 @@
 
   "PASSWD"              => "/etc/passwd",
   "SYSACCT_MIN_UID"     => 1,
-  "SYSACCT_MAX_UID"     => 100,
+  "SYSACCT_MAX_UID"     => 999,
 
   "FILTER"              => 0,
   "FILTER_THRESHOLD"    => 3,
@@ -62,8 +62,12 @@
   "DRONEBL_RPC_KEY"     => "",
 );
 
+# List loopback and private netblocks by default here
 my @noaction_ips_def = (
-  "127.0.0.1",
+  "127.0.0.0/8",
+  "10.0.0.0/8",
+  "172.16.0.0/12",
+  "192.168.0.0/16"
 );
 
 my %systemacct = ();
@@ -141,7 +145,7 @@
 my $reportmode = 0;      # Full report mode
 my @scanfiles = ();      # Files to scan
 my @scanfiles_once = (); # Files to scan only once during startup or HUP (e.g. not continuously followed)
-my @noaction_ips = ();    # IPs not to block
+my @noaction_ips = ();   # IPs not to filter
 my %filehandles = ();    # Global hash holding opened scanned log filehandles
 my $pid_file = "";       # Name of Maltfilter daemon pid file
 my @configfiles = ();    # Array of configuration file names
@@ -156,6 +160,7 @@
 # "date1"    = timestamp of first hit
 # "date2"    = timestamp of latest hit
 # "hits"     = number of hits to this IP
+# "dronebl"  = 1 == queued for submission, 2 == submitted
 # $statlist{$ip}{"reason"}{$class}->
 #   "msg"    = reason message (array if $reportmode)
 #   "hits"   = hits to this class
@@ -526,7 +531,8 @@
   my $entries = 0;
   while (my ($ip, $entry) = each(%dronebl)) {
     if ($entry->{"sent"} == 0 && $entry->{"tries"} < 3) {
-      $xml .= "<add ip=\"".$ip."\" type=\"".$entry->{"type"}."\" />\n";
+#      $xml .= "<add ip=\"".$ip."\" type=\"".$entry->{"type"}."\" />\n";
+      $xml .= "<add ip=\"".$ip."\" type=\"1\" />\n";
       $entries++;
     }
   }
@@ -541,6 +547,7 @@
     mlog(1, "[DroneBL] Trying to submit $entries entries.\n");
   }
 
+if (0) {
   # Submit via HTTP XML-RPC
   my $tmp = LWP::UserAgent->new;
   $tmp->agent("Maltfilter/".$progversion);
@@ -552,16 +559,20 @@
   my $res = $tmp->request($req);
 
   if ($res->is_success) {
-    mlog(2, "[DroneBL] [".$res->code."] ".$res->message."\n");
+    mlog(3, "[DroneBL] [".$res->code."] ".$res->message."\n");
     print $res->content."\n";
+    
+
 #    while (my ($ip, $entry) = each(%dronebl)) {
 #      $entry->{"sent"} = 1;
+#      $statlist{$ip}{"dronebl"} = 2 if (defined($statlist{$ip}));
 #    }
   } else {
     mlog(-1, "[DroneBL] Submission failed: [".$res->code."] ".$res->message."\n");
   }
+}
   
-  # Remove submitted expired entries
+  # Clean up expired entries, warning about unsubmitted ones.
   while (my ($ip, $entry) = each(%dronebl)) {
     if (!check_time3($entry->{"date"})) {
       mlog(1, "[DroneBL] $ip submission expired.\n") unless ($entry->{"sent"} > 0);
@@ -573,12 +584,17 @@
 sub dronebl_queue($$$)
 {
   my ($mip, $mdate, $mtype) = @_;
+
+  return unless ($settings{"DRONEBL"} > 0);
+  return if check_hosts_array(\@noaction_ips, $mip);
+
   if (!defined($dronebl{$mip})) {
     mlog(3, "[DroneBL] Queueing $mip \@ $mdate ($mtype)\n");
     $dronebl{$mip}{"type"} = $mtype;
     $dronebl{$mip}{"date"} = $mdate;
     $dronebl{$mip}{"sent"} = 0;
     $dronebl{$mip}{"tries"} = 0;
+    $statlist{$mip}{"dronebl"} = 1 if (defined($statlist{$mip}));
   }
 }
 
@@ -699,15 +715,16 @@
   my $chk_host = $_[1];
   my $chk_ip = new Net::IP($chk_host);
   foreach my $host (@{$_[0]}) {
-    if ($chk_host eq $host) {
-      return 1;
-    }
     my $ip = new Net::IP($host);
     if (defined($chk_ip) && defined($ip)) {
-      if ($chk_ip->binip() eq $ip->binip()) {
-        return 1;
+      my $res = $chk_ip->overlaps($ip);
+      if (defined($res)) {
+        return 1 if ($res == $IP_IDENTICAL);
+        return 2 if ($res == $IP_B_IN_A_OVERLAP);
+        return 3 if ($res == $IP_A_IN_B_OVERLAP);
       }
     }
+    return 4 if ($chk_host eq $host);
   }
   return 0;
 }
@@ -849,6 +866,8 @@
 {
   my ($struct, $mip, $mdate, $mclass, $mreason, $addhits) = @_;
 
+  return if check_hosts_array(\@noaction_ips, $mip);
+
   $struct->{$mip} = {} unless defined($struct->{$mip});
   my $entry = $struct->{$mip};
   $entry->{"reason"}{$mclass} = {} unless defined($entry->{"reason"}{$mclass});
@@ -915,7 +934,7 @@
   }
 
   # Separate check for DroneBL
-  if ($settings{"DRONEBL"} > 0 && $mtype > 0 && $cnt >= $settings{"DRONEBL_THRESHOLD"} && check_time3($mdate)) {
+  if ($mtype > 0 && $cnt >= $settings{"DRONEBL_THRESHOLD"} && check_time3($mdate)) {
     dronebl_queue($mip, $mdate, $mtype);
   }
 }
@@ -1092,7 +1111,7 @@
       } elsif ($key eq "SCANFILE_ONCE") {
         push(@scanfiles_once, $value);
       } elsif ($key eq "NOACTION_IPS") {
-        push(@noaction_ips_def, $value);
+        push(@noaction_ips, $value);
       } elsif (defined($settings{$key})) {
         $settings{$key} = $value;
       } else {
@@ -1121,6 +1140,9 @@
 
   @scanfiles_once = ();
   undef(@scanfiles_once);
+  
+  @noaction_ips = ();
+  undef(@noaction_ips);
 
   foreach my $filename (@configfiles) {
     mdie("Errors in configuration file '$filename', bailing out.\n")
@@ -1135,7 +1157,8 @@
   @scanfiles_once = grep(!$saw{$_}++, @scanfiles_once);
 
   %saw = ();
-  @noaction_ips = grep(!$saw{$_}++, @noaction_ips_def);
+  push(@noaction_ips, @noaction_ips_def);
+  @noaction_ips = grep(!$saw{$_}++, @noaction_ips);
   undef(%saw);
 
   mlog(-1, "Not acting on IPs: ".join(", ", @noaction_ips)."\n");