Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
#!/usr/bin/perl -w ## fwreport ## pod at tail $|++; use strict; my $version = '0.09.27'; use File::Temp qw/tempfile/; use Socket; use Net::Whois::IANA; use Locale::Country; use File::Slurp; use Text::Autoformat; # use Module::Versions::Report; ## Config params: my $infile = shift || 'fwreport.in'; ## logfile from Netfilters + firewall my $foutfile = shift || 'fwreport.out'; ## formatted output report my $routfile = shift || 'fwreport.raw'; ## unformatted output repo +rt my $tempdir = '/tmp/'; my $template = 'file_XXXXXXXXXX'; my $fqdn_level = 2; ## Eliminate duplicates from input file: my $attacks = 1; my ( $fh, $filename1 ) = tempfile($template, DIR=>$tempdir, UNLINK=>1) +; { open( IN, $infile ) or die "Error opening $infile: $!"; while(<IN>){ my %seen; for (<IN>){ ++$attacks; ++$seen{$_}; } print $fh sort keys %seen; } close IN or die "Error closing $infile: $!"; } ## Ready intermediate file from write to read: seek $fh,0,0; ## Parse intermediate file: my (@countries, @domains, @s_svcs, @d_svcs, ); while(<$fh>){ ## Populate hash with select elements from entry: my @elements = split( /\s+/ ); my %entry; for my $element (@elements) { my ($key, $value) = split(/=/, $element, 2); next unless ($key =~ m/^(IN|OUT|SRC|DST|PROTO|SPT|DPT)$/); $entry{$key} = (defined($value) ? $value : ''); } ## Determine what country attack is from: my $iana = new Net::Whois::IANA; $iana->whois_query(-ip=>$entry{SRC}); ## leading 2 chars only, avoid CACA, USUS, EU # whole world msgs: my $cc = substr($iana->country(), 0, 2); ## decode to name: my $cn = code2country($cc); push(@countries, $cn) if $cn; ## Reverse DNS lookup of attacking host: my $domain = gethostbyaddr(inet_aton($entry{SRC}),AF_INET); ## truncate FQDN down to n-level: push @domains,($domain ? $domain =~ m/((?:[^.]+\.?){1,$fqdn_level})$ +/ : $entry{SRC}); ## Determine name of attacking service: my $s_svc = getservbyport( $entry{SPT}, lc($entry{PROTO}) ); push @s_svcs,($s_svc ? $s_svc : $entry{SPT}); ## Determine name of attacked service: my $d_svc = getservbyport( $entry{DPT}, lc($entry{PROTO}) ); push @d_svcs,( $d_svc ? $d_svc : $entry{DPT}); } ## Wrap it up: { undef my %saw; @saw{@countries} = (); my @countries_u = sort keys %s +aw; undef %saw; @saw{@domains} = (); my @domains_u = sort keys %s +aw; undef %saw; @saw{@s_svcs} = (); my @s_svcs_u = sort keys %s +aw; undef %saw; @saw{@d_svcs} = (); my @d_svcs_u = sort keys %s +aw; open( OUT, "+> $routfile" ) or die "Error opening $routfile: $!"; my ($sec,$min,$hour,$mday,$mon,$year,) = localtime(time); my $stamp = sprintf( "%02d-%02d-%02d %02d:%02d", $year+1900, $mon+1, $mday, $hour, $m +in ); print OUT $stamp . "\n"x2; print OUT "\n"x2; print OUT 'BLOCKED ATTACKS = ' . $attacks . "\n"x2; print OUT "\n"x1; print OUT 'ATTACKING COUNTRIES = '; print OUT my $countries_u = @countries_u . "\n"x2; print OUT $_ . ' ' for (@countries_u); print OUT "\n"x3; my @domains_us = SortAlphaThenNum( @domains_u ); print OUT 'ATTACKING DOMAINS = '; print OUT my $domains_us = @domains_us . "\n"x2; print OUT $_ . ', ' for (@domains_us); print OUT "\n"x3; my @s_svcs_us = SortAlphaThenNum( @s_svcs_u ); print OUT 'ATTACKING SERVICES = '; print OUT my $s_svcs_us = @s_svcs_us . "\n"x2; print OUT $_ . ', ' for (@s_svcs_us); print OUT "\n"x3; my @d_svcs_us = SortAlphaThenNum( @d_svcs_u ); print OUT 'ATTACKED SERVICES = '; print OUT my $d_svcs_us = @d_svcs_us . "\n"x2; print OUT $_ . ', ' for (@d_svcs_us); print OUT "\n"x3; close OUT or die "Error closing $routfile: $!"; } ## Spruce it up a bit: { my $rawtext = read_file($routfile); my $formatted = autoformat $rawtext,{left=>1,right=>72,all=>1,squeez +e=>0}; write_file($foutfile, $formatted); } ###################################################################### +#### ## Elements with any alpha before elements with all numeric sub SortAlphaThenNum { my @unsorted = @_; return my @sorted = map $_->[0], sort { $a->[1] <=> $b->[1] || $a->[2] cmp $b->[2] || $a->[3] <=> $b->[3] || $a->[0] cmp $b->[0] } map [ $_, scalar(/^\d/), split /(\d+)/, $_, 2], @unsorted ; } END { sleep 1 && print "\a" for( 1..3 ); } ###################################################################### +#### =head1 TITLE fwreport =head1 SYNOPSIS fwreport infile outfile =head1 DESCRIPTION A lightweight parser for Netfilter logs. Produces highly-simplified summary for PHB consumption. =head1 TODO ?combine redundant 'wrap it up' code into sub? Sanity-check IN Strip leading whitespace from IN: s/^\s+//g Datetimestamp for filename Datestamp of input file to output report Getopt::Long and Pod::Usage --infile, --outfile, --versions, --help, --man Module::Versions::Report conditionally with END{...} Test on Win32 File::Temp instead of $routfile File::Slurp may not allow this =head1 UPDATE 2003-11-10 14:45 CST Post to PerlMonks Reduce number and scope of global vars PC speaker beeps on completion Datestamp of program run to output report Sample input and report to pod 2003-11-08 22:00 CST File::Slurp, Text::Autoformat to prettify output report Output sort any-alpha first, all-numeric last Revise parsing: number of (attacks, attackers, ISPs) list of (countries, domains, attack(ing|ed) services) Parse country codes to names Add Module::Versions::Report Eliminate duplicates entries from intermediate file Print to OUT instead of STDOUT Strip all but rightmost 2 or 3 elements of FQDN Strip bogus country code info: CACA => CA, USUS => US, EU # Country is really world wide => EU Only print protocol num if no service name Eliminate duplicate entries from IN Use File::Temp for intermediate file Parse src/dst ports to service names: Debug TCP is uc while /etc/services is lc Read data from IN Rename from "whobe" Parse input from syslog contents Read from file (one IPaddr/line) instead of @ARGV Reverse name lookup of source address Variable-ize output delimiter 2003-10-31 17:10 CST Initial working code =head1 TESTED Debian 3.0r1 Perl 5.8.0 strict 1.02 warnings 1.00 File::Temp 0.14 Socket 1.75 Net::Whois::IANA 0.03 Locale::Country 2.06 File::Slurp 2004.0904 Text::Autoformat 1.12 Modules::Versions::Report 1.02 =head1 BUGS Unclear on root-cause, but IP addresses registered to LACNIC occasionally cause errors and lookup failure: Use of uninitialized value in scalar chomp at Net/Whois/IANA.pm lin +e 117. =head1 CREDITS Props ta menolly for gracious reminder of rudimentary perling, atcroft for hash-populating aid, tye and jmcnamara for es'plaining seek() re: File::Temp write then re +ad, wufnik and Enlil for FQDN truncating idears, bart, Enlil, and Limbic~Region for unnatural list sorting with ST, dru145 for www.ginini.com.au/tools/fwlogsum/, Lincoln Stein for NPwP, And to some guy named vroom. =head1 AUTHOR ybiC =head1 SAMPLE INPUT (extraneous fields stripped, to reduce lateral scrolling at PM) IN=eth0 OUT= SRC=172.141.50.1 DST=1.2.3.4 SPT=3155 DPT=17300 PROTO=UD +P IN=eth0 OUT= SRC=200.226.91.1 DST=1.2.3.4 SPT=1369 DPT=17300 PROTO=UD +P ACTION=drop-input IN=eth0 OUT= SRC=202.123.79.1 DST=1.2.3.4 SPT=49634 + DPT=21 PROTO=TCP IN=eth0 OUT= SRC=211.162.110.1 DST=1.2.3.4 SPT=30112 DPT=1026 PROTO=T +CP IN=eth0 OUT= SRC=213.25.170.1 DST=1.2.3.4 SPT=4674 DPT=2282 PROTO=TCP IN=eth0 OUT= SRC=221.141.148.1 DST=1.2.3.4 SPT=4124 DPT=25 PROTO=TCP IN=eth0 OUT= SRC=24.128.81.1 DST=1.2.3.4 SPT=3789 DPT=17300 PROTO=UDP IN=eth0 OUT= SRC=24.150.221.1 DST=1.2.3.4 SPT=1900 DPT=17300 PROTO=TC +P IN=eth0 OUT= SRC=24.187.84.1 DST=1.2.3.4 SPT=4789 DPT=593 PROTO=UDP IN=eth0 OUT= SRC=24.194.92.1 DST=1.2.3.4 SPT=3540 DPT=17300 PROTO=TCP IN=eth0 OUT= SRC=24.214.27.1 DST=1.2.3.4 SPT=4076 DPT=17300 PROTO=TCP IN=eth0 OUT= SRC=24.60.217.1 DST=1.2.3.4 SPT=2268 DPT=17300 PROTO=TCP IN=eth0 OUT= SRC=61.143.182.1 DST=1.2.3.4 SPT=30110 DPT=1026 PROTO=TC +P IN=eth0 OUT= SRC=61.172.3.1 DST=1.2.3.4 SPT=32997 DPT=1026 PROTO=TCP IN=eth0 OUT= SRC=61.250.91.1 DST=1.2.3.4 SPT=58926 DPT=443 PROTO=TCP IN=eth0 OUT= SRC=62.59.148.1 DST=1.2.3.4 SPT=666 DPT=1026 PROTO=TCP IN=eth0 OUT= SRC=63.83.69.1 DST=1.2.3.4 SPT=4823 DPT=57 PROTO=TCP IN=eth0 OUT= SRC=65.130.116.1 DST=1.2.3.4 SPT=2782 DPT=524 PROTO=TCP IN=eth0 OUT= SRC=65.50.156.1 DST=1.2.3.4 SPT=2394 DPT=17300 PROTO=TCP IN=eth0 OUT= SRC=68.1.179.1 DST=1.2.3.4 SPT=2878 DPT=515 PROTO=TCP IN=eth0 OUT= SRC=68.13.16.1 DST=1.2.3.4 SPT=53 DPT=1026 52 PROTO=TCP IN=eth0 OUT= SRC=68.16.97.1 DST=1.2.3.4 SPT=65322 DPT=554 PROTO=TCP IN=eth0 OUT= SRC=68.16.97.1 DST=1.2.3.4 SPT=65323 DPT=7070 PROTO=TCP IN=eth0 OUT= SRC=68.21.37.1 DST=1.2.3.4 SPT=2991 DPT=20168 PROTO=TCP IN=eth0 OUT= SRC=68.22.76.1 DST=1.2.3.4 SPT=1379 DPT=20168 PROTO=UDP IN=eth0 OUT= SRC=68.3.106.1 DST=1.2.3.4 SPT=3577 DPT=20168 PROTO=UDP IN=eth0 OUT= SRC=68.50.191.1 DST=1.2.3.4 SPT=4565 DPT=20168 PROTO=TCP IN=eth0 OUT= SRC=68.51.50.1 DST=1.2.3.4 SPT=3425 DPT=20168 PROTO=TCP IN=eth0 OUT= SRC=68.83.144.1 DST=1.2.3.4 SPT=1298 DPT=20168 PROTO=TCP IN=eth0 OUT= SRC=68.99.193.1 DST=1.2.3.4 SPT=4070 DPT=1026 PROTO=TCP IN=eth0 OUT= SRC=68.99.193.1 DST=1.2.3.4 SPT=4070 DPT=1027 PROTO=UDP IN=eth0 OUT= SRC=81.166.217.1 DST=1.2.3.4 SPT=3963 DPT=21 PROTO=TCP IN=eth0 OUT= SRC=193.108.95.1 DST=1.2.3.4 SPT=80 DPT=1042 PROTO=TCP IN=eth0 OUT= SRC=193.108.95.1 DST=1.2.3.4 SPT=80 DPT=1043 PROTO=TCP IN=eth0 OUT= SRC=202.12.29.1 DST=1.2.3.4 SPT=43 DPT=38423 PROTO=TCP IN=eth0 OUT= SRC=216.239.59.1 DST=1.2.3.4 SPT=80 DPT=1031 PROTO=TCP =head1 SAMPLE OUTPUT 2003-11-09 14:55 BLOCKED ATTACKS = 36 ATTACKING COUNTRIES = 10 Australia Brazil Canada China France Hong Kong Kore +a, Republic of Netherlands Poland United States ATTACKING DOMAINS = 25 ameritech.net, apnic.net, attbi.com, bellsouth.net, cgocable.net, com.br, comcast.net, cox.net, knology.net, optonline.net, qwest.net, rogers.com, rr.com, tiscali.fr, zonnet.nl, 61.143.182.1, 61.172.3.1, 61.250.91.1, 63.83.69.1, 193.108.95.1, 202.123.79.1, 211.162.110.1, 213.25.170.1, 216.239.59.1, 221.141.148.1, ATTACKING SERVICES = 32 domain, whois, www, 666, 1298, 1369, 1379, 1900, 2268, 2394, 2782, 28 +78, 2991, 3425, 3540, 3577, 3789, 3963, 4070, 4076, 4124, 4565, 4674, 478 +9, 4823, 30110, 30112, 32997, 49634, 58926, 65322, 65323, ATTACKED SERVICES = 18 ftp, https, mtp, printer, smtp, 524, 554, 593, 1026, 1027, 1031, 1042 +, 1043, 2282, 7070, 17300, 20168, 38423, =cut

In reply to (code) Netfilter/iptables log parser/reporter for PHB consumption by ybiC

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others meditating upon the Monastery: (13)
    As of 2014-10-22 07:02 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      For retirement, I am banking on:










      Results (114 votes), past polls