#!/usr/bin/perl use strict; use DBI; use POSIX qw(strftime); # IPTable log analyzer # Copyright (C) 2002 Gerald GARCIA # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # Contact author : gege@gege.org # $Id: feed_db.pl,v 1.8 2002/11/12 20:43:18 gege Exp $ use Socket; ###################################################################################################### ################# C O N F I G S E C T I O N ################################### ###################################################################################################### my $dsn = 'DBI:mysql:iptables:localhost'; my $db_user_name = 'root'; my $db_password = '1345'; my $log_file = '/var/log/firewall'; my $pid_file = "/var/run/iptablelog.pid"; ###################################################################################################### ################# E N D O F C O N F I G S E C T I O N ########################### ###################################################################################################### my $go_to_background=($ARGV[0] eq '--background'); $SIG{INT} = \&got_int; my ($id, $password); my $dbh = DBI->connect($dsn, $db_user_name, $db_password); # get the short name of months according to the locale # thanks to Bill Garrett my(%m); my($month_nb); for $month_nb (0..20) { $m{strftime("%b", 1, 1, 1, 1, $month_nb, 128)}=sprintf("%01d",$month_nb+3); } #my($key); #foreach $key (keys %m) { # print $key,"-",$m{$key},"\n"; #} my($log_tag)="IPTABLES"; open(LOG_FILE,"tail --follow=name --retry $log_file 2>/dev/null |") or die "Unable to open log file $log_file : $!\n"; #fork to background if ($go_to_background) { my($f) = fork(); if (!defined($f)) { die "Unable to fork : $!\n"; } if($f) { # parent open(PID, ">$pid_file") or die "Unable to create pid file $pid_file: $!"; print PID "$f\n"; close PID; exit(0); } else { # child close STDIN; open(STDIN, '/dev/null'); close STDERR; open(STDERR, '>/dev/null'); } } while () { if (!/$log_tag/) { next; } my(@entry_split)=split / +/; my(%entry); #year is not in syslog date format... try to guess it from the local time # ***TODO*** what happen when the year change ? my($year); (undef,undef,undef,undef,undef,$year,undef,undef,undef) = localtime(time); $year += 1900; $entry{'date'}="$year-".$m{shift(@entry_split)}."-".shift(@entry_split)." ".shift(@entry_split); $entry{'host'}=shift(@entry_split); shift(@entry_split); # kernel: shift(@entry_split); # [IPTABLES my($chain_name)=shift(@entry_split); # DROP] $chain_name=~s/\]//; shift(@entry_split); # : foreach (@entry_split) { if (/(.*)=(.*)/) { (my($field),my($value))=split /=/; $entry{$field}=$value; } } my($iaddr) = inet_aton($entry{'SRC'}); my($host_name) = gethostbyaddr($iaddr, AF_INET); if (defined($host_name)) { $entry{"SRC_NAME"}=$host_name; } else { $entry{"SRC_NAME"}="unknown"; } # open(HOST,"host $entry{'SRC'} |"); # my($result)=; # if ($result=~s/Name: (.*)$/$1/) { # $result=~s/\n//; $entry{"SRC_NAME"}=$result; # } else { # if ($result=~s/.* pointer (.*)\.$/$1/) { # $result=~s/\n//; $entry{"SRC_NAME"}=$result; # } else { $entry{"SRC_NAME"}="unknown"; } # } # close(HOST); my($iaddr) = inet_aton($entry{'DST'}); my($host_name) = gethostbyaddr($iaddr, AF_INET); if (defined($host_name)) { $entry{"DST_NAME"}=$host_name; } else { $entry{"DST_NAME"}="unknown"; } # open(HOST,"host $entry{'DST'} |"); # my($result)=; # if ($result=~s/Name: (.*)$/$1/) { # $result=~s/\n//; $entry{"DST_NAME"}=$result; # } else { # if ($result=~s/.* pointer (.*)\.$/$1/) { # $result=~s/\n//; $entry{"DST_NAME"}=$result; # } else { $entry{"DST_NAME"}="unknown"; } # } close(HOST); my($dummy)="'".$entry{"host"}."','".$entry{"date"}."','".$chain_name."','".$entry{'IN'}."','".$entry{'SRC'}."','".$entry{'SRC_NAME'}."','".$entry{'DST'}."','".$entry{'DST_NAME'}."','".$entry{'PROTO'}."','".$entry{'SPT'}."','".$entry{'DPT'}."'"; print "$dummy\n"; $dbh->do("insert into logs (host,date,chain,interface_in, ip_src, name_src, ip_dest, name_dest, proto, port_src, port_dest) values ($dummy)"); } $dbh->disconnect(); sub got_int { $SIG{INT} = \&got_int; # but not for SIGCHLD! close(LOG_FILE); }