2007-03-15 22:55:22 +01:00
|
|
|
#
|
2007-12-01 18:45:43 +01:00
|
|
|
# Shorewall-perl 4.1 -- /usr/share/shorewall-perl/Shorewall/Accounting.pm
|
2007-03-15 22:55:22 +01:00
|
|
|
#
|
2007-09-08 18:09:51 +02:00
|
|
|
# This program is under GPL [http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt]
|
2007-03-15 22:55:22 +01:00
|
|
|
#
|
|
|
|
# (c) 2007 - Tom Eastep (teastep@shorewall.net)
|
|
|
|
#
|
|
|
|
# Complete documentation is available at http://shorewall.net
|
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of Version 2 of the GNU General Public License
|
|
|
|
# as published by the Free Software Foundation.
|
|
|
|
#
|
|
|
|
# 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
|
2007-09-08 18:09:51 +02:00
|
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2007-03-15 22:55:22 +01:00
|
|
|
#
|
2007-04-19 01:55:25 +02:00
|
|
|
# This module contains the code that handles the /etc/shorewall/accounting
|
|
|
|
# file.
|
2007-03-15 22:55:22 +01:00
|
|
|
#
|
2007-03-15 16:04:29 +01:00
|
|
|
package Shorewall::Accounting;
|
|
|
|
require Exporter;
|
2007-11-16 00:24:54 +01:00
|
|
|
use Shorewall::Config qw(:DEFAULT :internal);
|
2007-06-06 00:13:58 +02:00
|
|
|
use Shorewall::IPAddrs;
|
2007-03-15 16:04:29 +01:00
|
|
|
use Shorewall::Zones;
|
2007-11-16 00:24:54 +01:00
|
|
|
use Shorewall::Chains qw(:DEFAULT :internal);
|
2007-03-15 16:04:29 +01:00
|
|
|
|
|
|
|
use strict;
|
|
|
|
|
|
|
|
our @ISA = qw(Exporter);
|
|
|
|
our @EXPORT = qw( setup_accounting );
|
|
|
|
our @EXPORT_OK = qw( );
|
2008-02-06 00:50:00 +01:00
|
|
|
our $VERSION = 4.0.6;
|
2007-03-15 16:04:29 +01:00
|
|
|
|
2007-06-15 00:07:45 +02:00
|
|
|
#
|
|
|
|
# Initialize globals -- we take this novel approach to globals initialization to allow
|
|
|
|
# the compiler to run multiple times in the same process. The
|
|
|
|
# initialize() function does globals initialization for this
|
|
|
|
# module and is called from an INIT block below. The function is
|
|
|
|
# also called by Shorewall::Compiler::compiler at the beginning of
|
2007-07-26 20:36:18 +02:00
|
|
|
# the second and subsequent calls to that function.
|
2007-06-15 00:07:45 +02:00
|
|
|
#
|
|
|
|
|
2007-06-14 01:02:39 +02:00
|
|
|
sub initialize() {
|
|
|
|
our $jumpchainref;
|
|
|
|
$jumpchainref = undef;
|
|
|
|
}
|
|
|
|
|
|
|
|
INIT {
|
|
|
|
initialize;
|
|
|
|
}
|
|
|
|
|
2007-03-15 16:04:29 +01:00
|
|
|
#
|
|
|
|
# Accounting
|
|
|
|
#
|
2007-05-01 19:50:50 +02:00
|
|
|
sub process_accounting_rule( $$$$$$$$$ ) {
|
2007-07-26 20:36:18 +02:00
|
|
|
|
2007-06-05 18:49:13 +02:00
|
|
|
our $jumpchainref;
|
|
|
|
|
2007-05-01 19:50:50 +02:00
|
|
|
my ($action, $chain, $source, $dest, $proto, $ports, $sports, $user, $mark ) = @_;
|
2007-03-15 16:04:29 +01:00
|
|
|
|
2007-12-17 21:53:27 +01:00
|
|
|
our $disposition = '';
|
|
|
|
|
2008-04-11 03:48:05 +02:00
|
|
|
sub check_chain( $ ) {
|
2007-08-10 19:37:02 +02:00
|
|
|
my $chainref = shift;
|
2008-04-11 04:13:25 +02:00
|
|
|
fatal_error "A non-accounting chain ($chainref->{name}) may not appear in the accounting file" if $chainref->{policy};
|
2007-08-10 19:37:02 +02:00
|
|
|
}
|
|
|
|
|
2007-03-15 16:04:29 +01:00
|
|
|
sub accounting_error() {
|
2007-09-10 17:52:57 +02:00
|
|
|
fatal_error "Invalid Accounting rule";
|
2007-03-15 16:04:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub jump_to_chain( $ ) {
|
|
|
|
my $jumpchain = $_[0];
|
2008-04-11 03:01:12 +02:00
|
|
|
$jumpchainref = ensure_accounting_chain( $jumpchain );
|
2008-04-11 03:48:05 +02:00
|
|
|
check_chain( $jumpchainref );
|
2007-12-17 21:53:27 +01:00
|
|
|
$disposition = $jumpchain;
|
2007-03-15 16:04:29 +01:00
|
|
|
"-j $jumpchain";
|
|
|
|
}
|
|
|
|
|
|
|
|
my $target = '';
|
|
|
|
|
2007-06-06 00:13:58 +02:00
|
|
|
$proto = '' if $proto eq 'any';
|
|
|
|
$ports = '' if $ports eq 'any' || $ports eq 'all';
|
|
|
|
$sports = '' if $sports eq 'any' || $sports eq 'all';
|
|
|
|
|
2007-05-01 20:30:10 +02:00
|
|
|
my $rule = do_proto( $proto, $ports, $sports ) . do_user ( $user ) . do_test ( $mark, 0xFF );
|
2007-03-15 16:04:29 +01:00
|
|
|
my $rule2 = 0;
|
|
|
|
|
|
|
|
unless ( $action eq 'COUNT' ) {
|
|
|
|
if ( $action eq 'DONE' ) {
|
|
|
|
$target = '-j RETURN';
|
|
|
|
} else {
|
|
|
|
( $action, my $cmd ) = split /:/, $action;
|
|
|
|
if ( $cmd ) {
|
|
|
|
if ( $cmd eq 'COUNT' ) {
|
|
|
|
$rule2=1;
|
2008-01-10 22:07:07 +01:00
|
|
|
} elsif ( $cmd ne 'JUMP' ) {
|
2007-03-15 16:04:29 +01:00
|
|
|
accounting_error;
|
|
|
|
}
|
2008-01-10 22:07:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$target = jump_to_chain $action;
|
2007-03-15 16:04:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-06-11 01:41:30 +02:00
|
|
|
my $restriction = NO_RESTRICT;
|
|
|
|
|
2007-06-06 00:13:58 +02:00
|
|
|
$source = ALLIPv4 if $source eq 'any' || $source eq 'all';
|
2007-06-11 01:41:30 +02:00
|
|
|
|
2007-09-10 17:52:57 +02:00
|
|
|
if ( have_bridges ) {
|
|
|
|
my $fw = firewall_zone;
|
|
|
|
|
|
|
|
if ( $source =~ /^$fw:?(.*)$/ ) {
|
2007-06-11 20:07:34 +02:00
|
|
|
$source = $1 ? $1 : ALLIPv4;
|
2007-06-11 01:41:30 +02:00
|
|
|
$restriction = OUTPUT_RESTRICT;
|
|
|
|
$chain = 'accountout' unless $chain and $chain ne '-';
|
2007-06-11 17:59:25 +02:00
|
|
|
$dest = ALLIPv4 if $dest eq 'any' || $dest eq 'all';
|
2007-06-11 01:41:30 +02:00
|
|
|
} else {
|
|
|
|
$chain = 'accounting' unless $chain and $chain ne '-';
|
|
|
|
if ( $dest eq 'any' || $dest eq 'all' || $dest eq ALLIPv4 ) {
|
|
|
|
expand_rule(
|
2007-09-12 17:03:47 +02:00
|
|
|
ensure_filter_chain( 'accountout' , 0 ) ,
|
2007-06-11 01:41:30 +02:00
|
|
|
OUTPUT_RESTRICT ,
|
|
|
|
$rule ,
|
|
|
|
$source ,
|
|
|
|
$dest = ALLIPv4 ,
|
|
|
|
'' ,
|
|
|
|
$target ,
|
|
|
|
'' ,
|
2008-01-10 21:55:27 +01:00
|
|
|
$disposition ,
|
2007-06-11 01:41:30 +02:00
|
|
|
'' );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2007-08-10 19:37:02 +02:00
|
|
|
$chain = 'accounting' unless $chain and $chain ne '-';
|
2007-06-11 01:41:30 +02:00
|
|
|
$dest = ALLIPv4 if $dest eq 'any' || $dest eq 'all';
|
|
|
|
}
|
|
|
|
|
2008-04-11 03:48:05 +02:00
|
|
|
my $chainref = ensure_accounting_chain $chain;
|
2007-06-06 00:13:58 +02:00
|
|
|
|
2007-03-15 16:04:29 +01:00
|
|
|
expand_rule
|
|
|
|
$chainref ,
|
2007-06-10 19:57:08 +02:00
|
|
|
$restriction ,
|
2007-03-15 16:04:29 +01:00
|
|
|
$rule ,
|
|
|
|
$source ,
|
|
|
|
$dest ,
|
|
|
|
'' ,
|
|
|
|
$target ,
|
|
|
|
'' ,
|
2007-12-17 21:53:27 +01:00
|
|
|
$disposition ,
|
2007-03-15 16:04:29 +01:00
|
|
|
'' ;
|
|
|
|
|
|
|
|
if ( $rule2 ) {
|
2007-04-08 16:42:26 +02:00
|
|
|
expand_rule
|
2007-03-15 16:04:29 +01:00
|
|
|
$jumpchainref ,
|
2007-06-10 19:57:08 +02:00
|
|
|
$restriction ,
|
2007-03-15 16:04:29 +01:00
|
|
|
$rule ,
|
|
|
|
$source ,
|
|
|
|
$dest ,
|
|
|
|
'' ,
|
|
|
|
'' ,
|
|
|
|
'' ,
|
|
|
|
'' ,
|
|
|
|
'' ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub setup_accounting() {
|
2007-07-26 20:36:18 +02:00
|
|
|
|
2007-03-30 17:57:08 +02:00
|
|
|
my $fn = open_file 'accounting';
|
2007-03-15 16:04:29 +01:00
|
|
|
|
2007-11-27 16:50:20 +01:00
|
|
|
first_entry "$doing $fn...";
|
2007-11-16 00:24:54 +01:00
|
|
|
|
2008-04-11 04:46:17 +02:00
|
|
|
my $nonEmpty = 0;
|
|
|
|
|
2007-03-29 17:47:47 +02:00
|
|
|
while ( read_a_line ) {
|
2007-03-15 16:04:29 +01:00
|
|
|
|
2007-06-27 16:47:33 +02:00
|
|
|
my ( $action, $chain, $source, $dest, $proto, $ports, $sports, $user, $mark ) = split_line1 1, 9, 'Accounting File';
|
2007-03-15 16:04:29 +01:00
|
|
|
|
2007-06-27 16:47:33 +02:00
|
|
|
if ( $action eq 'COMMENT' ) {
|
|
|
|
process_comment;
|
|
|
|
} else {
|
2008-04-11 04:46:17 +02:00
|
|
|
$nonEmpty = 1;
|
2007-06-27 16:47:33 +02:00
|
|
|
process_accounting_rule $action, $chain, $source, $dest, $proto, $ports, $sports, $user, $mark;
|
|
|
|
}
|
2007-03-15 16:04:29 +01:00
|
|
|
}
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2008-04-11 04:46:17 +02:00
|
|
|
fatal_error "Accounring rules are isolated" if $nonEmpty && ! $filter_table->{accounting};
|
|
|
|
|
2007-09-10 17:52:57 +02:00
|
|
|
clear_comment;
|
2007-06-27 16:47:33 +02:00
|
|
|
|
2007-09-10 17:52:57 +02:00
|
|
|
if ( have_bridges ) {
|
2007-09-12 17:03:47 +02:00
|
|
|
if ( $filter_table->{accounting} ) {
|
2007-06-10 19:09:09 +02:00
|
|
|
for my $chain ( qw/INPUT FORWARD/ ) {
|
2007-09-12 17:03:47 +02:00
|
|
|
insert_rule $filter_table->{$chain}, 1, '-j accounting';
|
2007-06-10 19:09:09 +02:00
|
|
|
}
|
2007-03-15 16:04:29 +01:00
|
|
|
}
|
2007-06-10 18:42:34 +02:00
|
|
|
|
2007-09-12 17:03:47 +02:00
|
|
|
if ( $filter_table->{accountout} ) {
|
|
|
|
insert_rule $filter_table->{OUTPUT}, 1, '-j accountout';
|
2007-06-10 19:09:09 +02:00
|
|
|
}
|
|
|
|
} else {
|
2007-09-12 17:03:47 +02:00
|
|
|
if ( $filter_table->{accounting} ) {
|
2007-06-10 19:09:09 +02:00
|
|
|
for my $chain ( qw/INPUT FORWARD OUTPUT/ ) {
|
2007-09-12 17:03:47 +02:00
|
|
|
insert_rule $filter_table->{$chain}, 1, '-j accounting';
|
2007-06-10 19:09:09 +02:00
|
|
|
}
|
|
|
|
}
|
2007-06-10 18:42:34 +02:00
|
|
|
}
|
2007-03-15 16:04:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
1;
|