changeset 83:532169789f52 maltfilter-0.19.0

Add automatic temporary suspension of DroneBL submissions if enough HTTP connection or other errors occur (thresholds and suspension time can be set in configuration file.)
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 30 Aug 2009 01:47:40 +0300
parents 0c9d8dc3f70c
children dceadab0ebc1
files README example.conf maltfilter
diffstat 3 files changed, 61 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/README	Sat Aug 29 06:12:04 2009 +0300
+++ b/README	Sun Aug 30 01:47:40 2009 +0300
@@ -1,4 +1,4 @@
-Malicious Attack Livid Termination Filter daemon (maltfilter) v0.18.1
+Malicious Attack Livid Termination Filter daemon (maltfilter) v0.19.0
 =====================================================================
 Programmed by Matti 'ccr' Hämäläinen <ccr@tnsp.org>
 (C) Copyright 2009 Tecnic Software productions (TNSP)
--- a/example.conf	Sat Aug 29 06:12:04 2009 +0300
+++ b/example.conf	Sun Aug 30 01:47:40 2009 +0300
@@ -199,7 +199,7 @@
 DRONEBL_THRESHOLD    = 5
 
 ## Maximum age of hits counted towards DroneBL submission threshold.
-## NOTICE! Value this is in minutes!
+## NOTICE! Value this is in _minutes_!
 DRONEBL_MAX_AGE      = 60
 
 ## Your personal RPC key. This _MUST_ be set to a valid value, if you
@@ -209,3 +209,14 @@
 
 ## RPC2 submission URI, usually you do not need to change this.
 #DRONEBL_RPC_URI      = "http://dronebl.org/RPC2"
+
+## Number of errors are tolerated in submission / HTTP connection
+## before submissions are suspended?
+#DRONEBL_MAX_ERRORS   = 5
+
+## Number of Maltfilter maintenance "rounds" to suspend submissions for.
+## Currently maintenances happen approximately every 60 seconds.
+## Thus value of 10 would mean suspending for about 10 minutes.
+## (the times are not exact, because maintenances include operations
+## which vary in duration.)
+#DRONEBL_SUSPEND      = 10
--- a/maltfilter	Sat Aug 29 06:12:04 2009 +0300
+++ b/maltfilter	Sun Aug 30 01:47:40 2009 +0300
@@ -13,7 +13,7 @@
 use LWP::UserAgent;
 use IO::Seekable;
 
-my $progversion = "0.18.1";
+my $progversion = "0.19.0";
 my $progbanner =
 "Malicious Attack Livid Termination Filter daemon (maltfilter) v$progversion\n".
 "Programmed by Matti 'ccr' Hamalainen <ccr\@tnsp.org>\n".
@@ -61,6 +61,8 @@
   "DRONEBL_MAX_AGE"     => 30, # in minutes
   "DRONEBL_RPC_URI"     => "http://dronebl.org/RPC2",
   "DRONEBL_RPC_KEY"     => "",
+  "DRONEBL_MAX_ERRORS"  => 5,
+  "DRONEBL_SUSPEND"     => 10,
 );
 
 # List loopback and private netblocks by default here
@@ -177,39 +179,13 @@
 #############################################################################
 ### Status output functionality
 #############################################################################
-sub urlencode($)
+## Return string expressing given UNIX timestamp or "?" if not valid
+sub get_time_str($)
 {
-  my $value = $_[0];
-  $value =~ s/([^a-zA-Z_0-9 ])/"%" . uc(sprintf "%lx" , unpack("C", $1))/eg;
-  $value =~ tr/ /+/;
-  return $value;
+  return ($_[0] >= 0) ? (scalar localtime($_[0])) : "?";
 }
 
-my %entities = (
-  "<" => "lt",
-  ">" => "gt",
-  "&" => "amp",
-);
-
-sub htmlentities($)
-{
-  my $value = $_[0];
-#  $value =~ s/([keys %entities])/"&".$entities{$1}.";"/eg;
-  foreach my $val (keys %entities) {
-    $value =~ s/$val/\&$entities{$val}\;/g;
-  }
-  return $value;
-}
-
-sub get_time_str($)
-{
-  if ($_[0] >= 0) {
-    return scalar localtime($_[0]);
-  } else {
-    return "?";
-  }
-}
-
+## Return string expressing how long ago given UNIX timestamp is from current time
 my @paskat = (30*24*60*60, 7*24*60*60, 24*60*60, 60*60, 60);
 my @opaskat = ("months", "weeks", "days", "hours", "minutes");
 my @upaskat = ("month", "week", "day", "hour", "minute");
@@ -239,6 +215,30 @@
   }
 }
 
+## Convert non-alphanumeric characters in strong to hex-coded URI style
+sub urlencode($)
+{
+  my $value = $_[0];
+  $value =~ s/([^a-zA-Z_0-9 ])/"%" . uc(sprintf "%lx" , unpack("C", $1))/eg;
+  $value =~ tr/ /+/;
+  return $value;
+}
+
+my %entities = (
+  "<" => "lt",
+  ">" => "gt",
+  "&" => "amp",
+);
+
+## Convert special characters to HTML/XML entities
+sub htmlentities($)
+{
+  my $value = $_[0];
+  $value =~ s/$_/\&$entities{$_}\;/g foreach (keys %entities);
+  return $value;
+}
+
+
 sub printH($$$$)
 {
   my $fh = $_[1];
@@ -525,8 +525,12 @@
 #############################################################################
 ### DroneBL submission support
 #############################################################################
+my $dronebl_errors = 0;
+my $dronebl_suspend = 0;
+
 sub dronebl_process
 {
+  return if ($dronebl_suspend-- > 0);
   return unless ($settings{"DRONEBL"} > 0);
 
   # Create submission data
@@ -534,8 +538,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=\"1\" />\n";
+      $xml .= "<add ip=\"".$ip."\" type=\"".$entry->{"type"}."\" />\n";
+#      $xml .= "<add ip=\"".$ip."\" type=\"1\" />\n";
       $entries++;
     }
   }
@@ -574,6 +578,7 @@
     
     if ($type eq "success") {
         mlog(1, "[DroneBL] Succesfully submitted $entries entries.\n$msg\n");
+        $dronebl_errors = 0;
         while (my ($ip, $entry) = each(%dronebl)) {
           $entry->{"sent"} = 1;
           $statlist{$ip}{"dronebl"} = 2 if defined($statlist{$ip});
@@ -583,15 +588,24 @@
       if ($msg =~ /<code>403<\/code>/) {
         mlog(-1, "Disabling DroneBL submission due to invalid key.\n");
         $settings{"DRONEBL"} = 0;
+      } else {
+        $dronebl_errors++;
       }
       # Log error message mangled
       $msg =~ s{\s*</?[^>]+>}{ }g;
       mlog(-1, "[DroneBL] Error in submission: $msg\n");
     } else {
       mlog(-1, "[DroneBL] Unsupported response message ".$str."\n");
+      $dronebl_errors++;
     }
   } else {
     mlog(-1, "[DroneBL] HTTP request failed: [".$res->code."] ".$res->message."\n");
+    $dronebl_errors++;
+  }
+
+  if ($dronebl_errors >= $settings{"DRONEBL_MAX_ERRORS"}) {
+    mlog(-1, "Temporarily disabling DroneBL submissions due to too many errors for next ".$settings{"DRONEBL_SUSPEND"}. " rounds.\n");
+    $dronebl_suspend = $settings{"DRONEBL_SUSPEND"};
   }
   
   # Clean up expired entries, warn/note about unsubmitted ones.
@@ -1104,7 +1118,7 @@
     foreach my $filename (keys %filehandles) {
       seek($filehandles{$filename}, $filepos{$filename}, 0);
     }
-    if ($counter < 0 || $counter >= (60*5)) {
+    if ($counter < 0 || $counter >= 60) {
       # Every once in a while, execute maintenance functions
       $counter = 0;
       malt_maintenance();