Implement LOG_ZONE

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2018-02-20 14:02:06 -08:00
parent 4dfc6d90b9
commit 7ad7598d5b
No known key found for this signature in database
GPG Key ID: 96E6B3F2423A4D10
16 changed files with 176 additions and 58 deletions

View File

@ -282,7 +282,7 @@ sub process_accounting_rule1( $$$$$$$$$$$ ) {
if ( $dest eq 'any' || $dest eq 'all' || $dest eq ALLIP ) {
expand_rule(
ensure_rules_chain ( 'accountout' ) ,
ensure_chain ( $config{ACCOUNTING_TABLE}, 'accountout' ) ,
OUTPUT_RESTRICT ,
$prerule ,
$rule ,

View File

@ -172,6 +172,12 @@ our %EXPORT_TAGS = (
related_chain
invalid_chain
untracked_chain
rules_log
blacklist_log
established_log
related_log
invalid_log
untracked_log
zone_forward_chain
use_forward_chain
input_chain
@ -2266,6 +2272,56 @@ sub untracked_chain($$) {
'&' . &rules_chain(@_);
}
#
# Logname for chains between an ordered pair of zones
#
sub rules_log( $$ ) {
my $logchain = $config{LOG_ZONE};
if ( $logchain eq 'both' ) {
join "$config{ZONE2ZONE}", @_;
} elsif ( $logchain eq 'src' ) {
$_[0];
} else {
$_[1];
}
}
#
# Log name of the blacklist chain between an ordered pair of zones
#
sub blacklist_log($$) {
&rules_log(@_) . '~';
}
#
# Log name of the established chain between an ordered pair of zones
#
sub established_log($$) {
'^' . &rules_log(@_)
}
#
# Log name of the related chain between an ordered pair of zones
#
sub related_log($$) {
'+' . &rules_log(@_);
}
#
# Log name of the invalid chain between an ordered pair of zones
#
sub invalid_log($$) {
'_' . &rules_log(@_);
}
#
# Name of the untracked chain between an ordered pair of zones
#
sub untracked_log($$) {
'&' . &rules_log(@_);
}
#
# Create the base for a chain involving the passed interface -- we make this a function so it will be
# easy to change the mapping should the need ever arrive.
@ -4629,7 +4685,7 @@ sub logchain( $$$$$$ ) {
log_irule_limit(
$loglevel ,
$logchainref ,
$chainref->{name} ,
$chainref->{logname} ,
$disposition ,
[] ,
$logtag,
@ -6808,13 +6864,13 @@ sub log_irule_limit( $$$$$$$$@ ) {
sub log_rule( $$$$ ) {
my ( $level, $chainref, $disposition, $matches ) = @_;
log_rule_limit $level, $chainref, $chainref->{name} , $disposition, $globals{LOGLIMIT}, '', 'add', $matches;
log_rule_limit $level, $chainref, $chainref->{logname} , $disposition, $globals{LOGLIMIT}, '', 'add', $matches;
}
sub log_irule( $$$;@ ) {
my ( $level, $chainref, $disposition, @matches ) = @_;
log_irule_limit $level, $chainref, $chainref->{name} , $disposition, $globals{LOGILIMIT} , '', 'add', '', @matches;
log_irule_limit $level, $chainref, $chainref->{logname} , $disposition, $globals{LOGILIMIT} , '', 'add', '', @matches;
}
#

View File

@ -881,6 +881,7 @@ sub initialize( $;$$$) {
UNTRACKED_LOG_LEVEL => undef,
LOG_BACKEND => undef,
LOG_LEVEL => undef,
LOG_ZONE => undef,
#
# Location of Files
#
@ -3022,9 +3023,9 @@ sub process_compiler_directive( $$$$ ) {
$var = $2 || 'chain';
directive_error( "Shorewall variables may only be SET in the body of an action", $filename, $linenumber ) unless $actparams{0};
my $val = $actparams{$var} = evaluate_expression ( $expression,
$filename,
$linenumber,
0 );
$filename,
$linenumber,
0 );
$parmsmodified = PARMSMODIFIED;
} else {
$variables{$2} = evaluate_expression( $expression,
@ -6791,6 +6792,13 @@ sub get_configuration( $$$ ) {
$config{LOG_BACKEND} = $val;
}
if ( supplied( $val = $config{LOG_ZONE} ) ) {
fatal_error "Invalid LOG_ZONE setting ($val)" unless $val =~ /^(src|dst|both)$/i;
$config{LOG_ZONE} = lc( $val );
} else {
$config{LOG_ZONE} = 'both';
}
warning_message "RFC1918_LOG_LEVEL=$config{RFC1918_LOG_LEVEL} ignored. The 'norfc1918' interface/host option is no longer supported" if $config{RFC1918_LOG_LEVEL};
default_log_level 'SMURF_LOG_LEVEL', '';

View File

@ -112,6 +112,13 @@ our %section_functions = ( ALL_SECTION , \&rules_chain,
UNTRACKED_SECTION, \&untracked_chain,
NEW_SECTION, \&rules_chain );
our %log_functions = ( ALL_SECTION , \&rules_log ,
BLACKLIST_SECTION , \&blacklist_log ,
ESTABLISHED_SECTION , \&established_log ,
RELATED_SECTION , \&related_log ,
INVALID_SECTION , \&invalid_log ,
UNTRACKED_SECTION , \&untracked_log ,
NEW_SECTION , \&rules_log );
#
# Section => STATE map - initialized in process_rules().
#
@ -403,8 +410,8 @@ sub initialize( $ ) {
#
# Create a rules chain
#
sub new_rules_chain( $ ) {
my $chainref = new_chain( 'filter', $_[0] );
sub new_rules_chain( $$ ) {
my $chainref = new_chain( 'filter', &rules_chain( @_ ), &rules_log( @_ ) );
if ( $config{FASTACCEPT} ) {
if ( $globals{RELATED_TARGET} eq 'ACCEPT' && ! $config{RELATED_LOG_LEVEL} ) {
@ -445,7 +452,7 @@ sub new_policy_chain($$$$$)
{
my ($source, $dest, $policy, $provisional, $audit) = @_;
my $chainref = new_rules_chain( rules_chain( ${source}, ${dest} ) );
my $chainref = new_rules_chain( ${source}, ${dest} );
convert_to_policy_chain( $chainref, $source, $dest, $policy, $provisional, $audit );
@ -455,9 +462,11 @@ sub new_policy_chain($$$$$)
#
# Set the passed chain's policychain and policy to the passed values.
#
sub set_policy_chain($$$$$$)
sub set_policy_chain($$$$$)
{
my ( $chain, $source, $dest, $polchainref, $policy, $intrazone ) = @_;
my ( $source, $dest, $polchainref, $policy, $intrazone ) = @_;
my $chain = rules_chain( $source, $dest );
my $chainref = $filter_table->{$chain};
@ -467,7 +476,7 @@ sub set_policy_chain($$$$$$)
$chainref->{provisional} = '';
}
} else {
$chainref = new_rules_chain $chain;
$chainref = new_rules_chain( $source, $dest );
}
unless ( $chainref->{policychain} ) {
@ -483,6 +492,7 @@ sub set_policy_chain($$$$$$)
if ( defined $polchainref->{synparams} ) {
$chainref->{synparams} = $polchainref->{synparams};
$chainref->{synchain} = $polchainref->{synchain};
$chainref->{synlog} = $polchainref->{synlog};
}
$chainref->{pactions} = $polchainref->{pactions} || [];
@ -743,7 +753,8 @@ sub process_a_policy1($$$$$$$) {
$value = do_ratelimit $synparams, 'ACCEPT' if $synparams ne '';
$value .= do_connlimit $connlimit if $connlimit ne '';
$chainref->{synparams} = $value;
$chainref->{synchain} = $chain
$chainref->{synchain} = $chain;
$chainref->{synlog} = '@' . $chainref->{logname};
}
$chainref->{pactions} = $pactionref;
@ -753,19 +764,19 @@ sub process_a_policy1($$$$$$$) {
if ( $serverwild ) {
for my $zone ( @zonelist ) {
for my $zone1 ( @zonelist ) {
set_policy_chain rules_chain( ${zone}, ${zone1} ), $zone, $zone1, $chainref, $policy, $intrazone;
set_policy_chain $zone, $zone1, $chainref, $policy, $intrazone;
print_policy $zone, $zone1, $originalpolicy, $chain;
}
}
} else {
for my $zone ( all_zones ) {
set_policy_chain rules_chain( ${zone}, ${server} ), $zone, $server, $chainref, $policy, $intrazone;
set_policy_chain $zone, $server, $chainref, $policy, $intrazone;
print_policy $zone, $server, $originalpolicy, $chain;
}
}
} elsif ( $serverwild ) {
for my $zone ( @zonelist ) {
set_policy_chain rules_chain( ${client}, ${zone} ), $client, $zone, $chainref, $policy, $intrazone;
set_policy_chain $client, $zone, $chainref, $policy, $intrazone;
print_policy $client, $zone, $originalpolicy, $chain;
}
} else {
@ -832,6 +843,8 @@ sub save_policies() {
}
}
sub ensure_rules_chain( $$ );
#
# Process the policy file
#
@ -881,19 +894,15 @@ sub process_policies()
if ( $type == LOCAL ) {
for my $zone1 ( off_firewall_zones ) {
unless ( $zone eq $zone1 ) {
my $name = rules_chain( $zone, $zone1 );
my $name1 = rules_chain( $zone1, $zone );
set_policy_chain( $name, $zone, $zone1, ensure_rules_chain( $name ), 'NONE', 0 );
set_policy_chain( $name1, $zone1, $zone, ensure_rules_chain( $name1 ), 'NONE', 0 );
set_policy_chain( $zone, $zone1, ensure_rules_chain( $zone, $zone1 ), 'NONE', 0 );
set_policy_chain( $zone1, $zone, ensure_rules_chain( $zone1, $zone ), 'NONE', 0 );
}
}
} elsif ( $type == LOOPBACK ) {
for my $zone1 ( off_firewall_zones ) {
unless ( $zone eq $zone1 || zone_type( $zone1 ) == LOOPBACK ) {
my $name = rules_chain( $zone, $zone1 );
my $name1 = rules_chain( $zone1, $zone );
set_policy_chain( $name, $zone, $zone1, ensure_rules_chain( $name ), 'NONE', 0 );
set_policy_chain( $name1, $zone1, $zone, ensure_rules_chain( $name1 ), 'NONE', 0 );
set_policy_chain( $zone, $zone1, ensure_rules_chain( $zone, $zone1 ), 'NONE', 0 );
set_policy_chain( $zone1, $zone, ensure_rules_chain( $zone1, $zone ), 'NONE', 0 );
}
}
}
@ -1062,7 +1071,7 @@ sub complete_policy_chain( $$$ ) { #Chainref, Source Zone, Destination Zone
progress_message_nocompress " Policy $policy from $_[1] to $_[2] using chain $chainref->{name}";
}
sub ensure_rules_chain( $ );
sub finish_chain_sections( $ );
#
# Finish all policy Chains
@ -1076,7 +1085,7 @@ sub complete_policy_chains() {
my $provisional = $chainref->{provisional};
my $defaults = $chainref->{pactions};
my $name = $chainref->{name};
my $synparms = $chainref->{synparms};
my $synparams = $chainref->{synparams};
unless ( $chainref->{referenced} || $provisional || $policy eq 'CONTINUE' ) {
if ( $config{OPTIMIZE} & 2 ) {
@ -1086,13 +1095,13 @@ sub complete_policy_chains() {
# is a single jump. Generate_matrix() will just use the policy target when
# needed.
#
ensure_rules_chain $name if ( @$defaults ||
$loglevel ||
$synparms ||
$config{MULTICAST} ||
! ( $policy eq 'ACCEPT' || $config{FASTACCEPT} ) );
finish_chain_sections( $chainref ) if ( @$defaults ||
$loglevel ||
$synparams ||
$config{MULTICAST} ||
! ( $policy eq 'ACCEPT' || $config{FASTACCEPT} ) );
} else {
ensure_rules_chain $name;
finish_chain_sections( $chainref );
}
}
@ -1149,13 +1158,14 @@ sub setup_syn_flood_chains() {
my $limit = $chainref->{synparams};
if ( $limit && ! $filter_table->{syn_flood_chain $chainref} ) {
my $level = $chainref->{loglevel};
my $synchainref = @zones > 1 ?
new_chain 'filter' , syn_flood_chain $chainref :
new_chain( 'filter' , '@' . $chainref->{name} );
my $synchainref =
@zones > 1 ?
new_chain( 'filter' , syn_flood_chain $chainref , $chainref->{synlog} ) :
new_chain( 'filter' , '@' . $chainref->{name} , '@' . $chainref->{logname} );
add_rule $synchainref , "${limit}-j RETURN";
log_irule_limit( $level ,
$synchainref ,
$synchainref->{name} ,
$synchainref->{logname} ,
'DROP',
@{$globals{LOGILIMIT}} ? $globals{LOGILIMIT} : [ limit => "--limit 5/min --limit-burst 5" ] ,
'' ,
@ -1227,7 +1237,7 @@ sub finish_chain_section ($$$) {
log_rule_limit( $level,
$chain2ref,
$chain2ref->{name},
$chain2ref->{logname},
uc $target,
$globals{LOGLIMIT},
$tag ,
@ -1306,20 +1316,9 @@ sub finish_chain_section ($$$) {
pop_comment( $save_comment );
}
#
# Create a rules chain if necessary and populate it with the appropriate ESTABLISHED,RELATED rule(s) and perform SYN rate limiting.
#
# Return a reference to the chain's table entry.
#
sub ensure_rules_chain( $ )
{
my ($chain) = @_;
sub finish_chain_sections( $ ) {
my ( $chainref ) = @_;
my $chainref = $filter_table->{$chain};
$chainref = new_rules_chain( $chain ) unless $chainref;
unless ( $chainref->{referenced} ) {
if ( $section & ( NEW_SECTION | POLICYACTION_SECTION ) ) {
finish_chain_section $chainref , $chainref, 'ESTABLISHED,RELATED,INVALID,UNTRACKED';
} elsif ( $section == UNTRACKED_SECTION ) {
@ -1331,7 +1330,24 @@ sub ensure_rules_chain( $ )
}
$chainref->{referenced} = 1;
}
}
#
# Create a rules chain if necessary and populate it with the appropriate ESTABLISHED,RELATED rule(s) and perform SYN rate limiting.
#
# Return a reference to the chain's table entry.
#
sub ensure_rules_chain( $$ )
{
my ($source, $dest) = @_;
my $chain = rules_chain( $source, $dest );
my $chainref = $filter_table->{$chain};
$chainref = new_rules_chain( $source, $dest ) unless $chainref;
finish_chain_sections( $chainref ) unless $chainref->{referenced};
$chainref;
}
@ -2967,7 +2983,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
#
# Mark the chain as referenced and add appropriate rules from earlier sections.
#
$chainref = ensure_rules_chain $chain;
$chainref = ensure_rules_chain ${sourcezone}, ${destzone};
#
# Handle rules in the BLACKLIST, ESTABLISHED, RELATED, INVALID and UNTRACKED sections
#
@ -2977,7 +2993,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
unless ( $auxref ) {
my $save_comment = push_comment;
$auxref = new_chain 'filter', $auxchain;
$auxref = new_chain 'filter', $auxchain, $log_functions{$section}->( $sourcezone, $destzone );
$auxref->{blacklistsection} = 1 if $blacklist;
add_ijump( $chainref, j => $auxref, state_imatch( $section_states{$section} ) );

View File

@ -85,8 +85,8 @@ sub setup_tunnels() {
for my $zone ( split_list $gatewayzones, 'zone' ) {
my $type = zone_type( $zone );
fatal_error "Invalid zone ($zone) for GATEWAY ZONE" if $type == FIREWALL || $type == BPORT;
$inchainref = ensure_rules_chain( rules_chain( ${zone}, ${fw} ) );
$outchainref = ensure_rules_chain( rules_chain( ${fw}, ${zone} ) );
$inchainref = ensure_rules_chain( ${zone}, ${fw} );
$outchainref = ensure_rules_chain( ${fw}, ${zone} );
unless ( have_ipsec ) {
add_tunnel_rule $inchainref, p => 50, @$source;
@ -250,8 +250,8 @@ sub setup_tunnels() {
fatal_error "Invalid tunnel ZONE ($zone)" if $zonetype & ( FIREWALL | BPORT );
my $inchainref = ensure_rules_chain( rules_chain( ${zone}, ${fw} ) );
my $outchainref = ensure_rules_chain( rules_chain( ${fw}, ${zone} ) );
my $inchainref = ensure_rules_chain( ${zone}, ${fw} );
my $outchainref = ensure_rules_chain( ${fw}, ${zone} );
$gateways = ALLIP if $gateways eq '-';

View File

@ -45,6 +45,8 @@ LOG_MARTIANS=Yes
LOG_VERBOSITY=2
LOG_ZONE=Both
LOGALLNEW=
LOGFILE=/var/log/messages

View File

@ -56,6 +56,8 @@ LOG_MARTIANS=Yes
LOG_VERBOSITY=2
LOG_ZONE=Both
LOGALLNEW=
LOGFILE=/var/log/messages

View File

@ -53,6 +53,8 @@ LOG_MARTIANS=Yes
LOG_VERBOSITY=2
LOG_ZONE=Both
LOGALLNEW=
LOGFILE=/var/log/messages

View File

@ -56,6 +56,8 @@ LOG_MARTIANS=Yes
LOG_VERBOSITY=2
LOG_ZONE=Both
LOGALLNEW=
LOGFILE=/var/log/messages

View File

@ -45,6 +45,8 @@ LOG_MARTIANS=Yes
LOG_VERBOSITY=2
LOG_ZONE=Both
LOGALLNEW=
LOGFILE=/var/log/messages

View File

@ -1418,6 +1418,24 @@ net all DROP info</programlisting>then the chain name is 'net-all'
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis role="bold">LOG_ZONE=</emphasis>[<emphasis
role="bold"><option>src</option>|<option>dst</option>|<option>both</option></emphasis>]</term>
<listitem>
<para>Added in Shorewall 5.2.0. When a log message is issued from a
chain that relates to a pair of zones (e.g, 'fw-net'), the chain
name normally appears in the log message (unless LOGTAGONLY=Yes and
a log tag is specified). This can prevent OPTIMIZE category 8 from
combining chains which are identical except for the names of the
zones involved. LOG_ZONE allows for only the source or destination
zone to appear in the messages by setting LOG_ZONE to
<option>src</option> or <option>dest</option> respectively. If
LOG_ZONE=<option>both</option> (the default), then the full chain
name is included in log messages.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role="bold">LOG_LEVEL=</emphasis><emphasis>log-level</emphasis>[:<replaceable>log-tag</replaceable>]</term>

View File

@ -44,6 +44,8 @@ LOG_BACKEND=
LOG_VERBOSITY=2
LOG_ZONE=Both
LOGALLNEW=
LOGFILE=

View File

@ -45,6 +45,8 @@ LOG_BACKEND=
LOG_VERBOSITY=2
LOG_ZONE=Both
LOGALLNEW=
LOGFILE=

View File

@ -44,6 +44,8 @@ LOG_BACKEND=
LOG_VERBOSITY=2
LOG_ZONE=Both
LOGALLNEW=
LOGFILE=/var/log/messages

View File

@ -44,6 +44,8 @@ LOG_BACKEND=
LOG_VERBOSITY=2
LOG_ZONE=Both
LOGALLNEW=
LOGFILE=/var/log/messages

View File

@ -44,6 +44,8 @@ LOG_BACKEND=
LOG_VERBOSITY=2
LOG_ZONE=Both
LOGALLNEW=
LOGFILE=/var/log/messages