forked from extern/shorewall_code
Section the accounting file
This commit is contained in:
parent
195903444d
commit
5c0b592934
@ -42,13 +42,63 @@ our $VERSION = '4.4.17';
|
||||
#
|
||||
our %tables;
|
||||
|
||||
our $jumpchainref;
|
||||
our %accountingjumps;
|
||||
our $asection;
|
||||
our $defaultchain;
|
||||
our $defaultrestriction;
|
||||
our $restriction;
|
||||
our $accounting_commands = { COMMENT => 0, SECTION => 2 };
|
||||
our $sectionname;
|
||||
|
||||
use constant {
|
||||
LEGACY => -1,
|
||||
INPUT => 1,
|
||||
OUTPUT => 2,
|
||||
FORWARD => 3 };
|
||||
|
||||
our %asections = ( INPUT => INPUT,
|
||||
FORWARD => FORWARD,
|
||||
OUTPUT => OUTPUT );
|
||||
|
||||
#
|
||||
# Called by the compiler to [re-]initialize this module's state
|
||||
#
|
||||
sub initialize() {
|
||||
our $jumpchainref = undef;
|
||||
%tables = ();
|
||||
our %accountingjumps = ();
|
||||
$jumpchainref = undef;
|
||||
%tables = ();
|
||||
%accountingjumps = ();
|
||||
$asection = LEGACY;
|
||||
$defaultchain = 'accounting';
|
||||
$defaultrestriction = NO_RESTRICT;
|
||||
$sectionname = '';
|
||||
}
|
||||
|
||||
#
|
||||
# Process a SECTION header
|
||||
#
|
||||
sub process_section ($) {
|
||||
$sectionname = shift;
|
||||
my $newsect = $asections{$sectionname};
|
||||
#
|
||||
# read_a_line has already verified that there are exactly two tokens on the line
|
||||
#
|
||||
fatal_error "Invalid SECTION ($sectionname)" unless defined $newsect;
|
||||
fatal_error "SECTION not allowed after un-sectioned rules" unless $asection;
|
||||
fatal_error "Duplicate or out-of-order SECTION ($sectionname)" if $newsect <= $asection;
|
||||
|
||||
if ( $sectionname eq 'INPUT' ) {
|
||||
$defaultchain = 'accountin';
|
||||
$defaultrestriction = INPUT_RESTRICT;
|
||||
} elsif ( $sectionname eq 'OUTPUT' ) {
|
||||
$defaultchain = 'accountout';
|
||||
$defaultrestriction = OUTPUT_RESTRICT;
|
||||
} else {
|
||||
$defaultchain = 'accounting';
|
||||
$defaultrestriction = NO_RESTRICT;
|
||||
}
|
||||
|
||||
$asection = $newsect;
|
||||
}
|
||||
|
||||
#
|
||||
@ -59,17 +109,24 @@ sub process_accounting_rule( ) {
|
||||
our $jumpchainref = 0;
|
||||
our %accountingjumps;
|
||||
|
||||
my ($action, $chain, $source, $dest, $proto, $ports, $sports, $user, $mark, $ipsec, $headers ) = split_line1 1, 11, 'Accounting File';
|
||||
my ($action, $chain, $source, $dest, $proto, $ports, $sports, $user, $mark, $ipsec, $headers ) = split_line1 1, 11, 'Accounting File', $accounting_commands;
|
||||
|
||||
if ( $action eq 'COMMENT' ) {
|
||||
process_comment;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( $action eq 'SECTION' ) {
|
||||
process_section( $chain );
|
||||
return 0;
|
||||
}
|
||||
|
||||
$asection = 0 if $asection == LEGACY;
|
||||
|
||||
our $disposition = '';
|
||||
|
||||
sub reserved_chain_name($) {
|
||||
$_[0] =~ /^acc(?:ount(?:ing|out)|ipsecin|ipsecout)$/;
|
||||
$_[0] =~ /^acc(?:ount(?:in|ing|out)|ipsecin|ipsecout)$/;
|
||||
}
|
||||
|
||||
sub ipsec_chain_name($) {
|
||||
@ -90,7 +147,7 @@ sub process_accounting_rule( ) {
|
||||
sub jump_to_chain( $ ) {
|
||||
my $jumpchain = $_[0];
|
||||
fatal_error "Jumps to the $jumpchain chain are not allowed" if reserved_chain_name( $jumpchain );
|
||||
$jumpchainref = ensure_accounting_chain( $jumpchain, 0 );
|
||||
$jumpchainref = ensure_accounting_chain( $jumpchain, 0, $restriction );
|
||||
check_chain( $jumpchainref );
|
||||
$disposition = $jumpchain;
|
||||
$jumpchain;
|
||||
@ -148,20 +205,21 @@ sub process_accounting_rule( ) {
|
||||
}
|
||||
}
|
||||
|
||||
my $restriction = NO_RESTRICT;
|
||||
$restriction = $defaultrestriction;
|
||||
|
||||
if ( $source eq 'any' || $source eq 'all' ) {
|
||||
$source = ALLIP;
|
||||
$source = ALLIP;
|
||||
} else {
|
||||
fatal_error "MAC addresses are not allowed in the accounting file" if $source =~ /~/;
|
||||
$restriction |= INPUT_RESTRICT if $source =~ /~/;
|
||||
}
|
||||
|
||||
if ( have_bridges ) {
|
||||
if ( have_bridges && ! $asection ) {
|
||||
my $fw = firewall_zone;
|
||||
|
||||
if ( $source =~ /^$fw:?(.*)$/ ) {
|
||||
$source = $1 ? $1 : ALLIP;
|
||||
$restriction = OUTPUT_RESTRICT;
|
||||
fatal_error "MAC addresses are not allowed in an unsectioned accounting file" if $restriction & OUTPUT || $source =~ /~/;
|
||||
$chain = 'accountout' unless $chain and $chain ne '-';
|
||||
$dest = ALLIP if $dest eq 'any' || $dest eq 'all';
|
||||
} else {
|
||||
@ -181,7 +239,7 @@ sub process_accounting_rule( ) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$chain = 'accounting' unless $chain and $chain ne '-';
|
||||
$chain = $defaultchain unless $chain and $chain ne '-';
|
||||
$dest = ALLIP if $dest eq 'any' || $dest eq 'all';
|
||||
}
|
||||
|
||||
@ -189,7 +247,15 @@ sub process_accounting_rule( ) {
|
||||
my $dir;
|
||||
|
||||
if ( ! $chainref ) {
|
||||
$chainref = ensure_accounting_chain $chain, 0;
|
||||
if ( reserved_chain_name( $chain ) ) {
|
||||
fatal_error "May not use chain $chain in the $sectionname section" if $asection && $chain ne $defaultchain;
|
||||
$chainref = ensure_accounting_chain $chain, 0 , $restriction;
|
||||
} elsif ( $asection ) {
|
||||
fatal_error "Unknown accounting chain ($chain)";
|
||||
} else {
|
||||
$chainref = ensure_accounting_chain $chain, 0 , $restriction;
|
||||
}
|
||||
|
||||
$dir = ipsec_chain_name( $chain );
|
||||
|
||||
if ( $ipsec ne '-' ) {
|
||||
@ -209,11 +275,18 @@ sub process_accounting_rule( ) {
|
||||
$rule .= do_ipsec( $dir , $ipsec );
|
||||
}
|
||||
|
||||
$accountingjumps{$jumpchainref->{name}}{$chain} = 1 if $jumpchainref;
|
||||
if ( $jumpchainref ) {
|
||||
if ( $asection ) {
|
||||
my $jumprestrict = $jumpchainref->{restriction} || $restriction;
|
||||
fatal_error "Chain $jumpchainref->{name} contains rules that are incompatible with the $sectionname section" if $restriction && $jumprestrict ne $restriction;
|
||||
}
|
||||
|
||||
$accountingjumps{$jumpchainref->{name}}{$chain} = 1;
|
||||
}
|
||||
|
||||
fatal_error "$chain is not an accounting chain" unless $chainref->{accounting};
|
||||
|
||||
$restriction = $dir eq 'in' ? INPUT_RESTRICT : OUTPUT_RESTRICT if $dir;
|
||||
$restriction = $dir eq 'in' ? INPUT_RESTRICT : OUTPUT_RESTRICT if $dir && ! $asection;
|
||||
|
||||
expand_rule
|
||||
$chainref ,
|
||||
@ -274,59 +347,66 @@ sub setup_accounting() {
|
||||
|
||||
clear_comment;
|
||||
|
||||
if ( have_bridges ) {
|
||||
if ( $filter_table->{accounting} ) {
|
||||
for my $chain ( qw/INPUT FORWARD/ ) {
|
||||
if ( $nonEmpty ) {
|
||||
if ( have_bridges || $asection ) {
|
||||
if ( $filter_table->{accountin} ) {
|
||||
add_jump( $filter_table->{INPUT}, 'accountin', 0, '', 0, 0 );
|
||||
}
|
||||
|
||||
if ( $filter_table->{accounting} ) {
|
||||
optimize_okay( 'accounting' ) if $section;
|
||||
for my $chain ( qw/INPUT FORWARD/ ) {
|
||||
add_jump( $filter_table->{$chain}, 'accounting', 0, '', 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $filter_table->{accountout} ) {
|
||||
add_jump( $filter_table->{OUTPUT}, 'accountout', 0, '', 0, 0 );
|
||||
}
|
||||
} elsif ( $filter_table->{accounting} ) {
|
||||
for my $chain ( qw/INPUT FORWARD OUTPUT/ ) {
|
||||
add_jump( $filter_table->{$chain}, 'accounting', 0, '', 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $filter_table->{accountout} ) {
|
||||
add_jump( $filter_table->{OUTPUT}, 'accountout', 0, '', 0, 0 );
|
||||
}
|
||||
} elsif ( $filter_table->{accounting} ) {
|
||||
for my $chain ( qw/INPUT FORWARD OUTPUT/ ) {
|
||||
add_jump( $filter_table->{$chain}, 'accounting', 0, '', 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $filter_table->{accipsecin} ) {
|
||||
for my $chain ( qw/INPUT FORWARD/ ) {
|
||||
add_jump( $filter_table->{$chain}, 'accipsecin', 0, '', 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $filter_table->{accipsecout} ) {
|
||||
for my $chain ( qw/FORWARD OUTPUT/ ) {
|
||||
add_jump( $filter_table->{$chain}, 'accipsecout', 0, '', 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
for ( accounting_chainrefs ) {
|
||||
warning_message "Accounting chain $_->{name} has no references" unless keys %{$_->{references}};
|
||||
}
|
||||
|
||||
if ( my $chainswithjumps = keys %accountingjumps ) {
|
||||
my $progress = 1;
|
||||
|
||||
while ( $chainswithjumps && $progress ) {
|
||||
$progress = 0;
|
||||
for my $chain1 ( keys %accountingjumps ) {
|
||||
if ( keys %{$accountingjumps{$chain1}} ) {
|
||||
for my $chain2 ( keys %{$accountingjumps{$chain1}} ) {
|
||||
delete $accountingjumps{$chain1}{$chain2}, $progress = 1 unless $accountingjumps{$chain2};
|
||||
}
|
||||
} else {
|
||||
delete $accountingjumps{$chain1};
|
||||
$chainswithjumps--;
|
||||
$progress = 1;
|
||||
}
|
||||
if ( $filter_table->{accipsecin} ) {
|
||||
for my $chain ( qw/INPUT FORWARD/ ) {
|
||||
add_jump( $filter_table->{$chain}, 'accipsecin', 0, '', 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $chainswithjumps ) {
|
||||
my @chainswithjumps = keys %accountingjumps;
|
||||
fatal_error "Jump loop involving the following chains: @chainswithjumps";
|
||||
if ( $filter_table->{accipsecout} ) {
|
||||
for my $chain ( qw/FORWARD OUTPUT/ ) {
|
||||
add_jump( $filter_table->{$chain}, 'accipsecout', 0, '', 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
for ( accounting_chainrefs ) {
|
||||
warning_message "Accounting chain $_->{name} has no references" unless keys %{$_->{references}};
|
||||
}
|
||||
|
||||
if ( my $chainswithjumps = keys %accountingjumps ) {
|
||||
my $progress = 1;
|
||||
|
||||
while ( $chainswithjumps && $progress ) {
|
||||
$progress = 0;
|
||||
for my $chain1 ( keys %accountingjumps ) {
|
||||
if ( keys %{$accountingjumps{$chain1}} ) {
|
||||
for my $chain2 ( keys %{$accountingjumps{$chain1}} ) {
|
||||
delete $accountingjumps{$chain1}{$chain2}, $progress = 1 unless $accountingjumps{$chain2};
|
||||
}
|
||||
} else {
|
||||
delete $accountingjumps{$chain1};
|
||||
$chainswithjumps--;
|
||||
$progress = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $chainswithjumps ) {
|
||||
my @chainswithjumps = keys %accountingjumps;
|
||||
fatal_error "Jump loop involving the following chains: @chainswithjumps";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ our @EXPORT = qw(
|
||||
ensure_manual_chain
|
||||
log_rule_limit
|
||||
dont_optimize
|
||||
optimize_okay
|
||||
dont_delete
|
||||
dont_move
|
||||
|
||||
@ -221,6 +222,7 @@ our $VERSION = '4.4_18';
|
||||
# references => { <ref1> => <refs>, <ref2> => <refs>, ... }
|
||||
# blacklist => <number of blacklist rules at the head of the rules array> ( 0 or 1 )
|
||||
# action => <action tuple that generated this chain>
|
||||
# restrictions => Logical OR of restrictions in this chain.
|
||||
# } ,
|
||||
# <chain2> => ...
|
||||
# }
|
||||
@ -1107,14 +1109,15 @@ sub new_chain($$)
|
||||
|
||||
assert( $chain_table{$table} && ! ( $chain_table{$table}{$chain} || $builtin_target{ $chain } ) );
|
||||
|
||||
my $chainref = { name => $chain,
|
||||
rules => [],
|
||||
table => $table,
|
||||
loglevel => '',
|
||||
log => 1,
|
||||
cmdlevel => 0,
|
||||
references => {},
|
||||
blacklist => 0 };
|
||||
my $chainref = { name => $chain,
|
||||
rules => [],
|
||||
table => $table,
|
||||
loglevel => '',
|
||||
log => 1,
|
||||
cmdlevel => 0,
|
||||
references => {},
|
||||
blacklist => 0 ,
|
||||
restriction => 0 };
|
||||
|
||||
trace( $chainref, 'N', undef, '' ) if $debug;
|
||||
|
||||
@ -1240,6 +1243,21 @@ sub dont_optimize( $ ) {
|
||||
$chainref;
|
||||
}
|
||||
|
||||
#
|
||||
# Reverse the effect of dont_optimize
|
||||
#
|
||||
sub optimize_okay( $ ) {
|
||||
my $chain = shift;
|
||||
|
||||
my $chainref = reftype $chain ? $chain : $filter_table->{$chain};
|
||||
|
||||
$chainref->{dont_optimize} = 0;
|
||||
|
||||
trace( $chainref, 'O', undef, '' ) if $debug;
|
||||
|
||||
$chainref;
|
||||
}
|
||||
|
||||
#
|
||||
# Set the dont_optimize and dont_delete flags for a chain
|
||||
#
|
||||
@ -1301,9 +1319,9 @@ sub ensure_filter_chain( $$ )
|
||||
#
|
||||
# Create an accounting chain if necessary and return a reference to its table entry.
|
||||
#
|
||||
sub ensure_accounting_chain( $$ )
|
||||
sub ensure_accounting_chain( $$$ )
|
||||
{
|
||||
my ($chain, $ipsec) = @_;
|
||||
my ($chain, $ipsec, $restriction ) = @_;
|
||||
|
||||
my $chainref = $filter_table->{$chain};
|
||||
|
||||
@ -1313,10 +1331,11 @@ sub ensure_accounting_chain( $$ )
|
||||
fatal_error "Chain name ($chain) too long" if length $chain > 29;
|
||||
fatal_error "Invalid Chain name ($chain)" unless $chain =~ /^[-\w]+$/;
|
||||
$chainref = new_chain 'filter' , $chain;
|
||||
$chainref->{accounting} = 1;
|
||||
$chainref->{referenced} = 1;
|
||||
$chainref->{ipsec} = $ipsec;
|
||||
$chainref->{dont_optimize} = 1 unless $config{OPTIMIZE_ACCOUNTING} && $chain ne 'accounting';
|
||||
$chainref->{accounting} = 1;
|
||||
$chainref->{referenced} = 1;
|
||||
$chainref->{restriction} = $restriction;
|
||||
$chainref->{ipsec} = $ipsec;
|
||||
$chainref->{dont_optimize} = 1 unless $config{OPTIMIZE_ACCOUNTING};
|
||||
|
||||
if ( $chain ne 'accounting' ) {
|
||||
my $file = find_file $chain;
|
||||
@ -3667,7 +3686,8 @@ sub expand_rule( $$$$$$$$$$;$ )
|
||||
|
||||
$rule .= '-s $source ';
|
||||
} else {
|
||||
fatal_error "Source Interface ($iiface) not allowed when the source zone is the firewall zone" if $restriction & OUTPUT_RESTRICT;
|
||||
fatal_error "Source Interface ($iiface) not allowed when the SOURCE is the firewall" if $restriction & OUTPUT_RESTRICT;
|
||||
$chainref->{restriction} |= $restriction;
|
||||
$rule .= match_source_dev( $iiface );
|
||||
}
|
||||
}
|
||||
@ -3752,14 +3772,15 @@ sub expand_rule( $$$$$$$$$$;$ )
|
||||
$rule .= '-d $dest ';
|
||||
} else {
|
||||
fatal_error "Bridge Port ($diface) not allowed in OUTPUT or POSTROUTING rules" if ( $restriction & ( POSTROUTE_RESTRICT + OUTPUT_RESTRICT ) ) && port_to_bridge( $diface );
|
||||
fatal_error "Destination Interface ($diface) not allowed when the destination zone is the firewall zone" if $restriction & INPUT_RESTRICT;
|
||||
fatal_error "Destination Interface ($diface) not allowed when the destination zone is the firewall" if $restriction & INPUT_RESTRICT;
|
||||
fatal_error "Destination Interface ($diface) not allowed in the mangle OUTPUT chain" if $restriction & DESTIFACE_DISALLOW;
|
||||
|
||||
|
||||
if ( $iiface ) {
|
||||
my $bridge = port_to_bridge( $diface );
|
||||
fatal_error "Source interface ($iiface) is not a port on the same bridge as the destination interface ( $diface )" if $bridge && $bridge ne source_port_to_bridge( $iiface );
|
||||
}
|
||||
|
||||
|
||||
$chainref->{restriction} |= $restriction;
|
||||
$rule .= match_dest_dev( $diface );
|
||||
}
|
||||
} else {
|
||||
|
@ -2042,28 +2042,6 @@ sub check_trivalue( $$ ) {
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Check ACCOUNTING
|
||||
#
|
||||
sub check_accounting() {
|
||||
my $val = $config{ACCOUNTING};
|
||||
|
||||
if ( defined $val ) {
|
||||
$val = lc $val;
|
||||
if ( $val eq 'yes' || $val eq 'on' ) {
|
||||
$config{ACCOUNTING} = 'Yes';
|
||||
} elsif ( $val eq 'no' || $val eq 'off' ) {
|
||||
$config{ACCOUNTING} = '';
|
||||
} elsif ( $val eq '' ) {
|
||||
$config{ACCOUNTING} = 'NG';
|
||||
} elsif ( $val ne '' ) {
|
||||
fatal_error "Invalid value ($val) for ACCOUNTING";
|
||||
}
|
||||
} else {
|
||||
$config{ACCOUNTING} = 'Yes';
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Produce a report of the detected capabilities
|
||||
#
|
||||
@ -3238,9 +3216,7 @@ sub get_configuration( $ ) {
|
||||
default_yes_no 'AUTOMAKE' , '';
|
||||
default_yes_no 'WIDE_TC_MARKS' , '';
|
||||
default_yes_no 'TRACK_PROVIDERS' , '';
|
||||
|
||||
check_accounting;
|
||||
|
||||
default_yes_no 'ACCOUNTING' , 'Yes';
|
||||
default_yes_no 'OPTIMIZE_ACCOUNTING' , '';
|
||||
default_yes_no 'DYNAMIC_BLACKLIST' , 'Yes';
|
||||
default_yes_no 'REQUIRE_INTERFACE' , '';
|
||||
|
@ -2,6 +2,8 @@ Changes in Shorewall 4.4.18
|
||||
|
||||
1) Split up modules file.
|
||||
|
||||
2) Add sections to the accounting file.
|
||||
|
||||
Changes in Shorewall 4.4.17
|
||||
|
||||
1) Secure helper and modules files for non-root access.
|
||||
|
@ -43,6 +43,61 @@ None.
|
||||
For example, if you don't use traffic shaping or ipsets, you can
|
||||
remove those from your modules file.
|
||||
|
||||
2) Traditionally, the root of the Shorewall accounting rules has been
|
||||
the 'accounting' chain. Having a single root chain has drawbacks:
|
||||
|
||||
- Many rules are traversed needlessly (they could not possibly
|
||||
match traffic).
|
||||
- At any time, the Netfilter team could begin generating errors
|
||||
when loading those same rules.
|
||||
- MAC addresses may not be used in the accounting rules.
|
||||
- The 'accounting' chain cannot be optimized when
|
||||
OPTIMIZE_ACCOUNTING=Yes.
|
||||
- The rules may be defined in any order so the rules compiler must
|
||||
post-process the ruleset to ensure that there are no loops and to
|
||||
alert the user to unreferenced chains.
|
||||
|
||||
Beginning with Shorewall 4.4.18, the accounting structure can be
|
||||
created with three root chains:
|
||||
|
||||
- accountin: Rules that are valid in the INPUT chain (may not
|
||||
specify an output interface).
|
||||
- accountout: Rules that are valid in the OUTPUT chain (may not
|
||||
specify an input interface or a MAC address).
|
||||
- accounting: Other rules.
|
||||
|
||||
The new structure is enabled by sectioning the accounting file in a
|
||||
manner similar to the rules file.
|
||||
|
||||
The sections are INPUT, OUTPUT and FORWARD and must appear in that
|
||||
order (although any of them may be omitted). The first
|
||||
non-commentary record in the accounting file must be a section
|
||||
header when sectioning is used.
|
||||
|
||||
When sections are enabled:
|
||||
|
||||
- You must jump to a user-defined accounting chain before you can
|
||||
add rules to that chain. This eliminates loops and unreferenced
|
||||
chains.
|
||||
- You may not specify an output interface in the INPUT section.
|
||||
- In the OUTPUT section:
|
||||
- You may not specify an input interface
|
||||
- You may not jump to a chain defined in the INPUT section that
|
||||
specifies an input interface
|
||||
- You may not specify a MAC address
|
||||
- You may not jump to a chain defined in the INPUT section that
|
||||
specifies specifies a MAC address.
|
||||
- The default value of the CHAIN column is:
|
||||
- 'accountin' in the INPUT section
|
||||
- 'accountout' in the OUTPUT section
|
||||
- 'accounting' in the FORWARD section
|
||||
- Traffic addressed to the firewall goes through the rules defined
|
||||
in the INPUT section.
|
||||
- Traffic originating on the firewall goes through the rules
|
||||
defined in the OUTPUT section.
|
||||
- Traffic being forwarded through the firewall goes through the
|
||||
rules from all three sections.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
I V. R E L E A S E 4 . 4 H I G H L I G H T S
|
||||
----------------------------------------------------------------------------
|
||||
|
@ -235,6 +235,177 @@
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Sectioned Accounting Rules</title>
|
||||
|
||||
<para>Traditionally, the root of the Shorewall accounting rules has been
|
||||
the <emphasis role="bold">accounting</emphasis> chain. Having a single
|
||||
root chain has drawbacks:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>Many rules are traversed needlessly (they could not possibly
|
||||
match traffic).</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>At any time, the Netfilter team could begin generating errors
|
||||
when loading those same rules.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>MAC addresses may not be used in the accounting rules.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The <emphasis role="bold">accounting</emphasis> chain cannot be
|
||||
optimized when OPTIMIZE_ACCOUNTING=Yes.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The rules may be defined in any order so the rules compiler must
|
||||
post-process the ruleset to ensure that there are no loops and to
|
||||
alert the user to unreferenced chains.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para> Beginning with Shorewall 4.4.18, the accounting structure can be
|
||||
created with three root chains:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><emphasis role="bold">accountin</emphasis>: Rules that are valid
|
||||
in the <emphasis role="bold">INPUT</emphasis> chain (may not specify
|
||||
an output interface).</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><emphasis role="bold">accountout</emphasis>: Rules that are
|
||||
valid in the OUTPUT chain (may not specify an input interface or a MAC
|
||||
address).</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><emphasis role="bold">accounting</emphasis>: Other rules.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>The new structure is enabled by sectioning the accounting file in a
|
||||
manner similar to the <ulink url="manpages/shorewall-rules.html">rules
|
||||
file</ulink>. The sections are <emphasis role="bold">INPUT</emphasis>,
|
||||
<emphasis role="bold">OUTPUT</emphasis> and <emphasis
|
||||
role="bold">FORWARD</emphasis> and must appear in that order (although any
|
||||
of them may be omitted). The first non-commentary record in the accounting
|
||||
file must be a section header when sectioning is used. Section headers
|
||||
have the form:</para>
|
||||
|
||||
<para><option>SECTION</option>
|
||||
<replaceable>section-name</replaceable></para>
|
||||
|
||||
<para>When sections are enabled:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>You must jump to a user-defined accounting chain before you can
|
||||
add rules to that chain.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>This eliminates loops and unreferenced chains.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>You may not specify an output interface in the <emphasis
|
||||
role="bold">INPUT</emphasis> section.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>In the OUTPUT section:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>You may not specify an input interface</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>You may not jump to a chain defined in the <emphasis
|
||||
role="bold">INPUT</emphasis> section that specifies an input
|
||||
interface</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>You may not specify a MAC address</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>You may not jump to a chain defined in the <emphasis
|
||||
role="bold">INPUT</emphasis> section that specifies specifies a
|
||||
MAC address.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The default value of the CHAIN column is:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><emphasis role="bold">accountin</emphasis> in the <emphasis
|
||||
role="bold">INPUT</emphasis> section</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><emphasis role="bold">accounout</emphasis> in the <emphasis
|
||||
role="bold">OUTPUT</emphasis> section</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><emphasis role="bold">accounting</emphasis> in the <emphasis
|
||||
role="bold">FORWARD</emphasis> section</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Traffic addressed to the firewall goes through the rules defined
|
||||
in the INPUT section.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Traffic originating on the firewall goes through the rules
|
||||
defined in the OUTPUT section.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Traffic being forwarded through the firewall goes through the
|
||||
rules from all three sections.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>Here is a sample sectioned file that used <link
|
||||
linkend="perIP">Per-IP Accounting</link>.</para>
|
||||
|
||||
<caution>
|
||||
<para>In this example, the dmz net corresponds to a vserver zone so
|
||||
lives on the firewall itself.</para>
|
||||
</caution>
|
||||
|
||||
<programlisting>#ACTION CHAIN SOURCE DESTINATION PROTO DEST SOURCE USER/ MARK IPSEC
|
||||
# PORT(S) PORT(S) GROUP
|
||||
SECTION INPUT
|
||||
ACCOUNT(fw-net,$FW_NET) - COM_IF
|
||||
ACCOUNT(dmz-net,$DMZ_NET) - COM_IF
|
||||
|
||||
SECTION OUTPUT
|
||||
ACCOUNT(fw-net,$FW_NET) - - COM_IF
|
||||
ACCOUNT(dmz-net,$DMZ_NET) - - COM_IF
|
||||
|
||||
SECTION FORWARD
|
||||
ACCOUNT(loc-net,$INT_NET) - COM_IF INT_IF
|
||||
ACCOUNT(loc-net,$INT_NET) - INT_IF COM_IF
|
||||
</programlisting>
|
||||
</section>
|
||||
|
||||
<section id="Collectd">
|
||||
<title>Integrating Shorewall Accounting with Collectd</title>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user