Mercurial > hg > maltfilter
comparison maltfilter @ 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 | 4e3f87470426 |
children | 4362bf9e52e4 |
comparison
equal
deleted
inserted
replaced
82:0c9d8dc3f70c | 83:532169789f52 |
---|---|
11 use Net::IP; | 11 use Net::IP; |
12 use Net::DNS; | 12 use Net::DNS; |
13 use LWP::UserAgent; | 13 use LWP::UserAgent; |
14 use IO::Seekable; | 14 use IO::Seekable; |
15 | 15 |
16 my $progversion = "0.18.1"; | 16 my $progversion = "0.19.0"; |
17 my $progbanner = | 17 my $progbanner = |
18 "Malicious Attack Livid Termination Filter daemon (maltfilter) v$progversion\n". | 18 "Malicious Attack Livid Termination Filter daemon (maltfilter) v$progversion\n". |
19 "Programmed by Matti 'ccr' Hamalainen <ccr\@tnsp.org>\n". | 19 "Programmed by Matti 'ccr' Hamalainen <ccr\@tnsp.org>\n". |
20 "(C) Copyright 2009 Tecnic Software productions (TNSP)\n"; | 20 "(C) Copyright 2009 Tecnic Software productions (TNSP)\n"; |
21 | 21 |
59 "DRONEBL" => 0, | 59 "DRONEBL" => 0, |
60 "DRONEBL_THRESHOLD" => 5, | 60 "DRONEBL_THRESHOLD" => 5, |
61 "DRONEBL_MAX_AGE" => 30, # in minutes | 61 "DRONEBL_MAX_AGE" => 30, # in minutes |
62 "DRONEBL_RPC_URI" => "http://dronebl.org/RPC2", | 62 "DRONEBL_RPC_URI" => "http://dronebl.org/RPC2", |
63 "DRONEBL_RPC_KEY" => "", | 63 "DRONEBL_RPC_KEY" => "", |
64 "DRONEBL_MAX_ERRORS" => 5, | |
65 "DRONEBL_SUSPEND" => 10, | |
64 ); | 66 ); |
65 | 67 |
66 # List loopback and private netblocks by default here | 68 # List loopback and private netblocks by default here |
67 my @noaction_ips_def = ( | 69 my @noaction_ips_def = ( |
68 "127.0.0.0/8", | 70 "127.0.0.0/8", |
175 | 177 |
176 | 178 |
177 ############################################################################# | 179 ############################################################################# |
178 ### Status output functionality | 180 ### Status output functionality |
179 ############################################################################# | 181 ############################################################################# |
180 sub urlencode($) | 182 ## Return string expressing given UNIX timestamp or "?" if not valid |
181 { | |
182 my $value = $_[0]; | |
183 $value =~ s/([^a-zA-Z_0-9 ])/"%" . uc(sprintf "%lx" , unpack("C", $1))/eg; | |
184 $value =~ tr/ /+/; | |
185 return $value; | |
186 } | |
187 | |
188 my %entities = ( | |
189 "<" => "lt", | |
190 ">" => "gt", | |
191 "&" => "amp", | |
192 ); | |
193 | |
194 sub htmlentities($) | |
195 { | |
196 my $value = $_[0]; | |
197 # $value =~ s/([keys %entities])/"&".$entities{$1}.";"/eg; | |
198 foreach my $val (keys %entities) { | |
199 $value =~ s/$val/\&$entities{$val}\;/g; | |
200 } | |
201 return $value; | |
202 } | |
203 | |
204 sub get_time_str($) | 183 sub get_time_str($) |
205 { | 184 { |
206 if ($_[0] >= 0) { | 185 return ($_[0] >= 0) ? (scalar localtime($_[0])) : "?"; |
207 return scalar localtime($_[0]); | 186 } |
208 } else { | 187 |
209 return "?"; | 188 ## Return string expressing how long ago given UNIX timestamp is from current time |
210 } | |
211 } | |
212 | |
213 my @paskat = (30*24*60*60, 7*24*60*60, 24*60*60, 60*60, 60); | 189 my @paskat = (30*24*60*60, 7*24*60*60, 24*60*60, 60*60, 60); |
214 my @opaskat = ("months", "weeks", "days", "hours", "minutes"); | 190 my @opaskat = ("months", "weeks", "days", "hours", "minutes"); |
215 my @upaskat = ("month", "week", "day", "hour", "minute"); | 191 my @upaskat = ("month", "week", "day", "hour", "minute"); |
216 | 192 |
217 sub get_ago_str($) | 193 sub get_ago_str($) |
236 return $str." ago"; | 212 return $str." ago"; |
237 } else { | 213 } else { |
238 return "?"; | 214 return "?"; |
239 } | 215 } |
240 } | 216 } |
217 | |
218 ## Convert non-alphanumeric characters in strong to hex-coded URI style | |
219 sub urlencode($) | |
220 { | |
221 my $value = $_[0]; | |
222 $value =~ s/([^a-zA-Z_0-9 ])/"%" . uc(sprintf "%lx" , unpack("C", $1))/eg; | |
223 $value =~ tr/ /+/; | |
224 return $value; | |
225 } | |
226 | |
227 my %entities = ( | |
228 "<" => "lt", | |
229 ">" => "gt", | |
230 "&" => "amp", | |
231 ); | |
232 | |
233 ## Convert special characters to HTML/XML entities | |
234 sub htmlentities($) | |
235 { | |
236 my $value = $_[0]; | |
237 $value =~ s/$_/\&$entities{$_}\;/g foreach (keys %entities); | |
238 return $value; | |
239 } | |
240 | |
241 | 241 |
242 sub printH($$$$) | 242 sub printH($$$$) |
243 { | 243 { |
244 my $fh = $_[1]; | 244 my $fh = $_[1]; |
245 if ($_[0]) { | 245 if ($_[0]) { |
523 | 523 |
524 | 524 |
525 ############################################################################# | 525 ############################################################################# |
526 ### DroneBL submission support | 526 ### DroneBL submission support |
527 ############################################################################# | 527 ############################################################################# |
528 my $dronebl_errors = 0; | |
529 my $dronebl_suspend = 0; | |
530 | |
528 sub dronebl_process | 531 sub dronebl_process |
529 { | 532 { |
533 return if ($dronebl_suspend-- > 0); | |
530 return unless ($settings{"DRONEBL"} > 0); | 534 return unless ($settings{"DRONEBL"} > 0); |
531 | 535 |
532 # Create submission data | 536 # Create submission data |
533 my $xml = "<?xml version=\"1.0\"?>\n<request key=\"".$settings{"DRONEBL_RPC_KEY"}."\">\n"; | 537 my $xml = "<?xml version=\"1.0\"?>\n<request key=\"".$settings{"DRONEBL_RPC_KEY"}."\">\n"; |
534 my $entries = 0; | 538 my $entries = 0; |
535 while (my ($ip, $entry) = each(%dronebl)) { | 539 while (my ($ip, $entry) = each(%dronebl)) { |
536 if ($entry->{"sent"} == 0 && $entry->{"tries"} < 3) { | 540 if ($entry->{"sent"} == 0 && $entry->{"tries"} < 3) { |
537 # $xml .= "<add ip=\"".$ip."\" type=\"".$entry->{"type"}."\" />\n"; | 541 $xml .= "<add ip=\"".$ip."\" type=\"".$entry->{"type"}."\" />\n"; |
538 $xml .= "<add ip=\"".$ip."\" type=\"1\" />\n"; | 542 # $xml .= "<add ip=\"".$ip."\" type=\"1\" />\n"; |
539 $entries++; | 543 $entries++; |
540 } | 544 } |
541 } | 545 } |
542 $xml .= "</request>\n"; | 546 $xml .= "</request>\n"; |
543 | 547 |
572 $type = $1; $msg = ""; | 576 $type = $1; $msg = ""; |
573 } | 577 } |
574 | 578 |
575 if ($type eq "success") { | 579 if ($type eq "success") { |
576 mlog(1, "[DroneBL] Succesfully submitted $entries entries.\n$msg\n"); | 580 mlog(1, "[DroneBL] Succesfully submitted $entries entries.\n$msg\n"); |
581 $dronebl_errors = 0; | |
577 while (my ($ip, $entry) = each(%dronebl)) { | 582 while (my ($ip, $entry) = each(%dronebl)) { |
578 $entry->{"sent"} = 1; | 583 $entry->{"sent"} = 1; |
579 $statlist{$ip}{"dronebl"} = 2 if defined($statlist{$ip}); | 584 $statlist{$ip}{"dronebl"} = 2 if defined($statlist{$ip}); |
580 } | 585 } |
581 } elsif ($type eq "error") { | 586 } elsif ($type eq "error") { |
582 # If we don't have a valid key, disable further submissions. | 587 # If we don't have a valid key, disable further submissions. |
583 if ($msg =~ /<code>403<\/code>/) { | 588 if ($msg =~ /<code>403<\/code>/) { |
584 mlog(-1, "Disabling DroneBL submission due to invalid key.\n"); | 589 mlog(-1, "Disabling DroneBL submission due to invalid key.\n"); |
585 $settings{"DRONEBL"} = 0; | 590 $settings{"DRONEBL"} = 0; |
591 } else { | |
592 $dronebl_errors++; | |
586 } | 593 } |
587 # Log error message mangled | 594 # Log error message mangled |
588 $msg =~ s{\s*</?[^>]+>}{ }g; | 595 $msg =~ s{\s*</?[^>]+>}{ }g; |
589 mlog(-1, "[DroneBL] Error in submission: $msg\n"); | 596 mlog(-1, "[DroneBL] Error in submission: $msg\n"); |
590 } else { | 597 } else { |
591 mlog(-1, "[DroneBL] Unsupported response message ".$str."\n"); | 598 mlog(-1, "[DroneBL] Unsupported response message ".$str."\n"); |
599 $dronebl_errors++; | |
592 } | 600 } |
593 } else { | 601 } else { |
594 mlog(-1, "[DroneBL] HTTP request failed: [".$res->code."] ".$res->message."\n"); | 602 mlog(-1, "[DroneBL] HTTP request failed: [".$res->code."] ".$res->message."\n"); |
603 $dronebl_errors++; | |
604 } | |
605 | |
606 if ($dronebl_errors >= $settings{"DRONEBL_MAX_ERRORS"}) { | |
607 mlog(-1, "Temporarily disabling DroneBL submissions due to too many errors for next ".$settings{"DRONEBL_SUSPEND"}. " rounds.\n"); | |
608 $dronebl_suspend = $settings{"DRONEBL_SUSPEND"}; | |
595 } | 609 } |
596 | 610 |
597 # Clean up expired entries, warn/note about unsubmitted ones. | 611 # Clean up expired entries, warn/note about unsubmitted ones. |
598 while (my ($ip, $entry) = each(%dronebl)) { | 612 while (my ($ip, $entry) = each(%dronebl)) { |
599 if (!check_time3($entry->{"date"})) { | 613 if (!check_time3($entry->{"date"})) { |
1102 } | 1116 } |
1103 sleep(1); | 1117 sleep(1); |
1104 foreach my $filename (keys %filehandles) { | 1118 foreach my $filename (keys %filehandles) { |
1105 seek($filehandles{$filename}, $filepos{$filename}, 0); | 1119 seek($filehandles{$filename}, $filepos{$filename}, 0); |
1106 } | 1120 } |
1107 if ($counter < 0 || $counter >= (60*5)) { | 1121 if ($counter < 0 || $counter >= 60) { |
1108 # Every once in a while, execute maintenance functions | 1122 # Every once in a while, execute maintenance functions |
1109 $counter = 0; | 1123 $counter = 0; |
1110 malt_maintenance(); | 1124 malt_maintenance(); |
1111 } | 1125 } |
1112 $counter++; | 1126 $counter++; |