package Lire::Firewall::IptablesDlfConverter;
use strict;
use Lire::DlfConverter;
use Lire::Firewall qw/firewall_number2names/;
use Lire::Syslog;
use Carp;
use base qw/Lire::DlfConverter/;
sub new {
my $proto = shift;
bless {}, (ref $proto || $proto);
}
sub name { 'iptables' }
sub title { 'Iptables firewall log' }
sub description { 'Iptables firewall log' }
sub schemas { qw/firewall/ }
sub handle_log_lines { 1 }
sub init_dlf_converter {
my ($self, $process) = @_;
$self->{'parser'} = new Lire::Syslog;
# wether or not to try to resolve IP addresses to hostnames
## $self->{'resolve'} = Lire::Config->get( 'resolve_ips' );
$self->{'resolve'} = 0;
}
my %ipt2dlf = (
IN => "rcv_intf",
OUT => "snt_intf",
SRC => "from_ip",
DST => "to_ip",
SPT => "from_port",
DPT => "to_port",
TYPE => "from_port",
CODE => "to_port",
LEN => "length",
PROTO => "protocol",
);
my $denied_re = qr/deny|denied|drop|reject|unallowed/i;
my $permit_re = qr/accept|permit/i;
my %field_re = ();
foreach my $k ( keys %ipt2dlf ) {
$field_re{$k} = qr/\b$k=(\S*)/;
}
sub process_log_line {
my ($self, $process, $line) = @_;
eval {
my $log = $self->{'parser'}->parse($line);
local $_ = $log->{'content'};
# Skip non-iptables records
#
# The starts of the line is set by the user.
#
# We cannot rely on the process name (usually kernel) since
# this is added by klogd and not by the iptables logging code.
return $process->ignore_log_line($line)
unless $log->{content} =~ /IN=\w* OUT=\w*/;
my %dlf = (
time => $log->{timestamp},
count => 1,
);
# There is a problem with the IPTable log, there is no real
# informations on how to determine the reason the packet was
# logged, i.e. denied or permitted. The user must specify
# a custom label, we set the action to denied if we find common
# string in the label.
($dlf{rule}) = $log->{content} =~ /^(.*?)IN=/;
$dlf{action} = "denied" if $dlf{rule} =~ /$denied_re/;
$dlf{action} = "permitted" if $dlf{rule} =~ /$permit_re/;
while ( my ( $field, $re ) = each %field_re ) {
my ( $value ) = $log->{content} =~ /$re/;
( $dlf{$ipt2dlf{$field}} ) = $value if defined $value;
}
# IPTables will log the following on all packet
die "iptables lexer failed\n"
unless exists $dlf{from_ip} &&
exists $dlf{to_ip} &&
exists $dlf{length} &&
exists $dlf{protocol};
firewall_number2names( \%dlf );
# fill in $dlf{from_host} and $dlf{to_host}
## $self->{'resolve'} && firewall_resolve ( \%dlf );
$process->write_dlf('firewall', \%dlf);
};
if($@) {
$process->error($line, $@);
}
}
sub finish_conversion {
delete $_[0]->{'parser'};
}
1; # nag nag.
__END__
=pod
=head1 NAME
IptablesDlfConverter - convert netfilter/iptables syslog logs to firewall DLF
=head1 DESCRIPTION
B converts Linux 2.4 iptables packet log into firewall DLF format.
=head1 LIMITATIONS
The netfilter logging modules don't log the status of the packet
(drop, accept, reject) like the ipchains logging code. You can specify
a prefix that will be used in the log. This converter will mark the
packet as 'denied' whenever that prefix matches (case insensitive) the
following regex: 'denied|deny|drop|reject|unallowed', it will mark the
packet as 'permitted' whenever that prefix matches (case insensitive)
the following regex: 'accept|permit', and all other packets will have
'-' as the value of the 'action' field.
So in order for this converter to detect 'denied' packets, you should use a
prefix containing one of those substrings.
For example:
iptables -N lodrop
iptables -A logdrop -j LOG --log-prefix "Packet-DENY: "
iptables -A logdrop -j DROP
or other similar prefixes: 'denied: ', 'Packet-REJECT: ', ...
The prefix used will end up in the 'rule' field of the DLF record.
=head1 EXAMPLES
IptablesDlfConvertor will be rarely used on its own, but is more likely
called by lr_log2report:
$ lr_log2report iptables < /var/log/iptables.log > report
=head1 SEE ALSO
The Netfilter webpage at http://netfilter.samba.org/ .
=head1 AUTHORS
Francis J. Lacoste
=head1 VERSION
$Id: IptablesDlfConverter.pm,v 1.12 2006/07/23 13:16:35 vanbaal Exp $
=head1 COPYRIGHT
Copyright (C) 2001, 2002, 2003, 2004 Stichting LogReport Foundation
LogReport@LogReport.org
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 (see COPYING); if not, check with
http://www.gnu.org/copyleft/gpl.html.
=cut
# Local Variables:
# mode: cperl
# End: