#!/usr/bin/perl
use Time::Local;
use File::stat;
# Linux IPTables DShield Client. V 0.0.1
#
# This script will extract relevant lines from the log file and
# send them to 'reports@dshield.org'.
#
# IMPORTANT: CHANGE THE '$filter' below with a marker that can
# be found in all log lines you would like to submit.
# e.g.: IN=eth0 or something like that.
# you don't need this if you write your firewall logs
# to a separate file.
#
# It should run from cron regularly to look for new entries. See
# 'parameters' for more details.
#
# Important: Linux syslog files do not keep track of the year.
# remember to rotate your logs at the end of the year.
#
$EXT_IP=`/sbin/ifconfig | head -2 | grep 'inet addr' | awk '{print \$2}' | sed -e 's/.*://'`;
#print "external IP =($EXT_IP)\n";
chomp $EXT_IP;
#print "external IP =($EXT_IP)\n";
#exit;
#print "before setting filter\n";
$filter="IN=eth0"; # replace with pattern that occurs in all iptables lines
$logfile="/var/log/messages"; # location of log file.
#print "filter = $filter\n";
#print "logfile = $logfile\n";
#
# Parameters:
#
$userid="86579302"; # replace with your userid if you have one.
#$email='root@localhost'; # replace with your e-mail address.
$email='lchialing@yahoo.com'; # replace with your e-mail address.
$to='reports@dshield.org'; # send log to this address. Change for testing.
#$cc_flag=TRUE;
$cc_flag=0;
$tz="-05:00"; # setup your time zone here. Use offset from
# GMT. E.g: +01:00 for Central Europe,
# -05:00 for Easter US.
# Subject line. No need to change
$subject="FORMAT IPTABLES USERID $userid TZ $tz";
$local_log='/tmp/dshield.log'; # keep a local copy here for revie
#
# End of parameter. Skip through the section below for local abnomalities.
#
%months = (Jan=>0, Feb=>1, Mar=>2, Apr=>3, May=>4, Jun=>5, Jul=>6, Aug=>7, Sep=>8, Oct=>9, Nov=>10, Dec=>11);
$state="/var/tmp/dshield"; # file that is used to store timestamp of log file.
$rolllogfile="/var/log/messages.1"; # location of last log file.
#
# Nothing should need changing beyond this point.
#
# setup a halfway safe /tmp file
srand(time);
$tmp="/tmp/dshield".$$.rand(1000);
$tmp2="/tmp/dshield_cllee".$$.rand(1000);
#
# the 'state' file contains the timestamp
# of the log file the last time the script ran.
#
$last_date=0;
if ( -e $state ) {
$last_date = `cat $state`;
}
#
# get the current mod date of the logfile
#
if ( -f $logfile ) {
$stat=stat($logfile);
$curr_date=$stat->ctime;
} else {
die ("Can't find LogFile $logfile\n");
}
#
# if current date stamp older than last,
# either nothing written or something screwy - abort.
#
if ($curr_date <= $last_date) {
die ("Nothing written to log file since last export. Check if the correct logfile is used ($logfile)\n");
}
#
# remove stale tmp files. This should never happen, as
# the temp file name is generated randomly
if (-s $tmp2) {
system ("rm $tmp2");
}
#
# remove stale tmp files. This should never happen, as
# the temp file name is generated randomly
if (-s $tmp) {
system ("rm $tmp");
}
#
# create empty 600 file..
# make sure it is still empty and 600 after we
# created it.
system ("touch $tmp; chmod 600 $tmp");
if (-s $tmp) {
die "TMP file grew after creation.\n";
}
#
# create empty 600 file..
# make sure it is still empty and 600 after we
# created it.
system ("touch $tmp2; chmod 600 $tmp2");
if (-s $tmp2) {
die "TMP2 file grew after creation.\n";
}
#
# check to see if logfile rolled since last run
# and parse if so.
#
$roll_date = 0;
$stat=stat($rolllogfile);
$roll_date=$stat->ctime;
if ($roll_date >= $last_date) {
parselog ($rolllogfile, $last_date, $tmp);
}
#
# Parse current log file
#
parselog ($logfile, $last_date, $tmp);
# send the file. Only bother if there is something to
# report.
if ( -s $tmp) {
open (MAIL,"| /usr/sbin/sendmail -t -oi");
print MAIL "To: $to\n";
print MAIL "From: $email\n";
if ($cc_flag) {print MAIL "Cc: $email\n";}
print MAIL "Subject: $subject\n\n";
print MAIL `cat $tmp`;
close MAIL;
if ($local) {
open (MAIL,"> $local");
print MAIL "To: $to\n";
print MAIL "From: $email\n";
if ($cc_flag) {print MAIL "Cc: $email\n";}
print MAIL "Subject: $subject\n\n";
print MAIL `cat $tmp`;
close MAIL;
}
}
#
# Parse current log file - filter out NetBios and send to me
#
parselog_cllee ($logfile, $last_date, $tmp2);
# send the file. Only bother if there is something to
# report.
if ( -s $tmp2) {
open (MAIL,"| /usr/sbin/sendmail -t -oi");
print MAIL "To: $email\n";
print MAIL "From: $email\n";
#if ($cc_flag) {print MAIL "Cc: $email\n";}
print MAIL "Subject: cllee $subject\n\n";
print MAIL `cat $tmp2`;
close MAIL;
if ($local) {
open (MAIL,"> $local");
print MAIL "To: $email\n";
print MAIL "From: $email\n";
#if ($cc_flag) {print MAIL "Cc: $email\n";}
print MAIL "Subject: cllee $subject\n\n";
print MAIL `cat $tmp2`;
close MAIL;
}
}
#
# cleanup the temp file and write a new state file
#
system ("rm $tmp");
system ("rm $tmp2");
system ("echo $curr_date > $state");
sub parselog {
local($logfile,$last_date,$tmpfile) = @_;
(undef,undef,undef,undef,$cur_month,$year,undef) = localtime(time);
$cur_month++;
@lines = `grep "$filter" $logfile | grep IN=eth0 | grep -v SRC=$EXT_IP | grep -v SRC=151.191.1.10 | grep -v SRC=151.191.1.12 | grep -v SRC=151.191.175.7 | grep -v SPT=80`;
open (LOGFILE, "<$logfile");
open (TMPFILE, ">>$tmpfile");
foreach $line (@lines) {
$line =~ /(\w{3}) ([ \d]{2}) (\d{2}):(\d{2}):(\d{2}) /;
$dateline = timelocal ($5, $4, $3, $2, $months{$1}, ($months{$1}>$cur_month) ? $year-1 : $year );
if ($dateline >= $last_date) {
print TMPFILE $line;
}
}
close (TMPFILE);
close (LOGFILE);
}
sub parselog_cllee {
local($logfile,$last_date,$tmpfile) = @_;
(undef,undef,undef,undef,$cur_month,$year,undef) = localtime(time);
$cur_month++;
@lines = `grep "$filter" $logfile | grep IN=eth0 | grep 'BAD SRC'`;
open (LOGFILE, "<$logfile");
open (TMPFILE, ">>$tmpfile");
foreach $line (@lines) {
$line =~ /(\w{3}) ([ \d]{2}) (\d{2}):(\d{2}):(\d{2}) /;
$dateline = timelocal ($5, $4, $3, $2, $months{$1}, ($months{$1}>$cur_month) ? $year-1 : $year );
if ($dateline >= $last_date) {
print TMPFILE $line;
}
}
close (TMPFILE);
close (LOGFILE);
}
|