Default-action lists

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2017-02-06 10:11:48 -08:00
parent 686ca9d3a3
commit 92133e5a6b
No known key found for this signature in database
GPG Key ID: 96E6B3F2423A4D10

View File

@ -311,12 +311,12 @@ sub initialize( $ ) {
# This is updated from the *_DEFAULT settings in shorewall.conf. Those settings were stored # This is updated from the *_DEFAULT settings in shorewall.conf. Those settings were stored
# in the %config hash when shorewall[6].conf was processed. # in the %config hash when shorewall[6].conf was processed.
# #
%default_actions = ( DROP => 'none' , %default_actions = ( DROP => [] ,
REJECT => 'none' , REJECT => [] ,
BLACKLIST => 'none' , BLACKLIST => [] ,
ACCEPT => 'none' , ACCEPT => [] ,
QUEUE => 'none' , QUEUE => [] ,
NFQUEUE => 'none' , NFQUEUE => [] ,
); );
# #
# These are set to 1 as sections are encountered. # These are set to 1 as sections are encountered.
@ -430,6 +430,7 @@ sub convert_to_policy_chain($$$$$$)
$chainref->{audit} = $audit; $chainref->{audit} = $audit;
$chainref->{policychain} = $chainref->{name}; $chainref->{policychain} = $chainref->{name};
$chainref->{policypair} = [ $source, $dest ]; $chainref->{policypair} = [ $source, $dest ];
$chainref->{defaults} = [];
} }
# #
@ -479,7 +480,7 @@ sub set_policy_chain($$$$$$)
$chainref->{synchain} = $polchainref->{synchain}; $chainref->{synchain} = $polchainref->{synchain};
} }
$chainref->{default} = $polchainref->{default} if defined $polchainref->{default}; $chainref->{defaults} = $polchainref->{defaults};
$chainref->{is_policy} = 1; $chainref->{is_policy} = 1;
push @policy_chains, $chainref; push @policy_chains, $chainref;
} else { } else {
@ -541,17 +542,7 @@ sub process_default_action( $$$$ ) {
$level = 'none'; $level = 'none';
} }
if ( "\L$default" eq 'none' ) { if ( ( $targets{$def} || 0 ) & ACTION ) {
if ( supplied $param || ( supplied $level && $level ne 'none' ) ) {
if ( $default_option ) {
fatal_error "Invalid setting ($originalpolicy) for $policy";
} else {
fatal_error "Invalid policy ($originalpolicy)";
}
}
$default = 'none';
} elsif ( ( $targets{$def} || 0 ) & ACTION ) {
$default = supplied $param ? normalize_action( $def, $level, $param ) : $default = supplied $param ? normalize_action( $def, $level, $param ) :
$level eq 'none' ? normalize_action_name $def : $level eq 'none' ? normalize_action_name $def :
normalize_action( $def, $level, '' ); normalize_action( $def, $level, '' );
@ -566,12 +557,34 @@ sub process_default_action( $$$$ ) {
} }
} else { } else {
$default = $default_actions{$policy} || 'none'; $default = $default_actions{$policy};
} }
$default; $default;
} }
sub process_default_actions( $$$ ) {
my ( $originalpolicy, $policy, $defaults ) = @_;
my @defaults;
if ( supplied $defaults ) {
if ( $defaults ne 'none' ) {
for my $default ( split_list3( $defaults, 'Default Action' ) ) {
my ( $action, $level, undef, $remainder ) = split( /:/, $default, ACTION_TUPLE_ELEMENTS - 1);
fatal_error "Invalid default action ($default:$level:$remainder)" if defined $remainder;
push @defaults, process_default_action( $originalpolicy, $policy, $action, $level );
}
}
\@defaults;
} else {
$default_actions{$policy};
}
}
# #
# Verify an NFQUEUE specification and return the appropriate ip[6]tables target # Verify an NFQUEUE specification and return the appropriate ip[6]tables target
# #
@ -657,12 +670,10 @@ sub process_a_policy1($$$$$$$) {
require_capability 'AUDIT_TARGET', ":audit", "s" if $audit; require_capability 'AUDIT_TARGET', ":audit", "s" if $audit;
my ( $policy, $default, $level, undef, $remainder ) = split( /:/, $originalpolicy, ACTION_TUPLE_ELEMENTS ); my ( $policy, $defaults ) = split( /:/, $originalpolicy, 2 );
fatal_error "Invalid or missing POLICY ($originalpolicy)" unless $policy; fatal_error "Invalid or missing POLICY ($originalpolicy)" unless $policy;
fatal_error "Invalid default action ($default:$level:$remainder)" if defined $remainder;
( $policy , my $queue ) = get_target_param $policy; ( $policy , my $queue ) = get_target_param $policy;
fatal_error "Invalid policy ($policy)" unless exists $validpolicies{$policy}; fatal_error "Invalid policy ($policy)" unless exists $validpolicies{$policy};
@ -671,7 +682,7 @@ sub process_a_policy1($$$$$$$) {
fatal_error "A $policy policy may not be audited" unless $auditpolicies{$policy}; fatal_error "A $policy policy may not be audited" unless $auditpolicies{$policy};
} }
$default = process_default_action( $originalpolicy, $policy, $default, $level ); my $default = process_default_actions( $originalpolicy, $policy, $defaults );
if ( defined $queue ) { if ( defined $queue ) {
$policy = handle_nfqueue( $queue, $policy = handle_nfqueue( $queue,
@ -728,11 +739,8 @@ sub process_a_policy1($$$$$$$) {
$chainref->{synchain} = $chain $chainref->{synchain} = $chain
} }
assert( $default ); $chainref->{defaults} = $default;
my $chainref1 = $usedactions{$default}; $chainref->{origin} = shortlineinfo('');
$chainref->{default} = $chainref1 ? $chainref1->{name} : $default;
$chainref->{origin} = shortlineinfo('');
if ( $clientwild ) { if ( $clientwild ) {
if ( $serverwild ) { if ( $serverwild ) {
@ -842,15 +850,15 @@ sub process_policies()
our @zonelist = $config{EXPAND_POLICIES} ? all_zones : ( all_zones, 'all' ); our @zonelist = $config{EXPAND_POLICIES} ? all_zones : ( all_zones, 'all' );
for my $option ( qw( DROP_DEFAULT REJECT_DEFAULT BLACKLIST_DEFAULT ACCEPT_DEFAULT QUEUE_DEFAULT NFQUEUE_DEFAULT) ) { for my $option ( qw( DROP_DEFAULT REJECT_DEFAULT BLACKLIST_DEFAULT ACCEPT_DEFAULT QUEUE_DEFAULT NFQUEUE_DEFAULT) ) {
my $action = $config{$option}; my $actions = $config{$option};
unless ( $action eq 'none' ) { if ( $actions eq 'none' ) {
my ( $default, $level, $remainder ) = split( /:/, $action, 3 ); $actions = [];
fatal_error "Invalid setting ( $action ) for $option" if supplied $remainder; } else {
$action = process_default_action( $action, $option, $default, $level ); $actions = process_default_actions( $actions, $option, $actions );
} }
$default_actions{$map{$option}} = $action; $default_actions{$map{$option}} = $actions;
} }
for $zone ( all_zones ) { for $zone ( all_zones ) {
@ -910,12 +918,16 @@ sub process_policies()
sub process_inline ($$$$$$$$$$$$$$$$$$$$$$); sub process_inline ($$$$$$$$$$$$$$$$$$$$$$);
sub add_policy_rules( $$$$$ ) { sub add_policy_rules( $$$$$ ) {
my ( $chainref , $target, $loglevel, $default, $dropmulticast ) = @_; my ( $chainref , $target, $loglevel, $defaults, $dropmulticast ) = @_;
unless ( $target eq 'NONE' ) { unless ( $target eq 'NONE' ) {
my @defaults;
@defaults = @$defaults if defined $defaults;
add_ijump $chainref, j => 'RETURN', d => '224.0.0.0/4' if $dropmulticast && $target ne 'CONTINUE' && $target ne 'ACCEPT'; add_ijump $chainref, j => 'RETURN', d => '224.0.0.0/4' if $dropmulticast && $target ne 'CONTINUE' && $target ne 'ACCEPT';
if ( $default && $default ne 'none' ) { for my $default ( @defaults ) {
my ( $action ) = split ':', $default; my ( $action ) = split ':', $default;
if ( ( $targets{$action} || 0 ) == ACTION ) { if ( ( $targets{$action} || 0 ) == ACTION ) {
@ -987,27 +999,26 @@ sub complete_policy_chain( $$$ ) { #Chainref, Source Zone, Destination Zone
my $chainref = $_[0]; my $chainref = $_[0];
my $policyref = $filter_table->{$chainref->{policychain}}; my $policyref = $filter_table->{$chainref->{policychain}};
my $synparams = $policyref->{synparams}; my $synparams = $policyref->{synparams};
my $default = $policyref->{default}; my $defaults = $policyref->{defaults};
my $policy = $policyref->{policy}; my $policy = $policyref->{policy};
my $loglevel = $policyref->{loglevel}; my $loglevel = $policyref->{loglevel};
assert( $policyref ); assert( $policyref );
if ( $chainref eq $policyref ) { if ( $chainref eq $policyref ) {
add_policy_rules $chainref , $policy, $loglevel , $default, $config{MULTICAST}; add_policy_rules $chainref , $policy, $loglevel , $defaults, $config{MULTICAST};
} else { } else {
if ( $policy eq 'ACCEPT' || $policy eq 'QUEUE' || $policy =~ /^NFQUEUE/ ) { if ( $policy eq 'ACCEPT' || $policy eq 'QUEUE' || $policy =~ /^NFQUEUE/ ) {
if ( $synparams ) { if ( $synparams ) {
report_syn_flood_protection; report_syn_flood_protection;
add_policy_rules $chainref , $policy , $loglevel , $default, $config{MULTICAST}; add_policy_rules $chainref , $policy , $loglevel , $defaults, $config{MULTICAST};
} else { } else {
add_ijump $chainref, g => $policyref; add_ijump $chainref, g => $policyref;
$chainref = $policyref; $chainref = $policyref;
add_policy_rules( $chainref, $policy, $loglevel, $default, $config{MULTICAST} ) if $default =~/^macro\./;
} }
} elsif ( $policy eq 'CONTINUE' ) { } elsif ( $policy eq 'CONTINUE' ) {
report_syn_flood_protection if $synparams; report_syn_flood_protection if $synparams;
add_policy_rules $chainref , $policy , $loglevel , $default, $config{MULTICAST}; add_policy_rules $chainref , $policy , $loglevel , $defaults, $config{MULTICAST};
} else { } else {
report_syn_flood_protection if $synparams; report_syn_flood_protection if $synparams;
add_ijump $chainref , g => $policyref; add_ijump $chainref , g => $policyref;
@ -1030,7 +1041,7 @@ sub complete_policy_chains() {
unless ( ( my $policy = $chainref->{policy} ) eq 'NONE' ) { unless ( ( my $policy = $chainref->{policy} ) eq 'NONE' ) {
my $loglevel = $chainref->{loglevel}; my $loglevel = $chainref->{loglevel};
my $provisional = $chainref->{provisional}; my $provisional = $chainref->{provisional};
my $default = $chainref->{default}; my $defaults = $chainref->{defaults};
my $name = $chainref->{name}; my $name = $chainref->{name};
my $synparms = $chainref->{synparms}; my $synparms = $chainref->{synparms};
@ -1042,7 +1053,7 @@ sub complete_policy_chains() {
# is a single jump. Generate_matrix() will just use the policy target when # is a single jump. Generate_matrix() will just use the policy target when
# needed. # needed.
# #
ensure_rules_chain $name if ( $default ne 'none' || ensure_rules_chain $name if ( @$defaults ||
$loglevel || $loglevel ||
$synparms || $synparms ||
$config{MULTICAST} || $config{MULTICAST} ||
@ -1053,7 +1064,7 @@ sub complete_policy_chains() {
} }
if ( $name =~ /^all[-2]|[-2]all$/ ) { if ( $name =~ /^all[-2]|[-2]all$/ ) {
add_policy_rules $chainref , $policy, $loglevel , $default, $config{MULTICAST}; add_policy_rules $chainref , $policy, $loglevel , $defaults, $config{MULTICAST};
} }
} }
} }
@ -1082,20 +1093,18 @@ sub complete_standard_chain ( $$$$ ) {
my ( $stdchainref, $zone, $zone2, $default ) = @_; my ( $stdchainref, $zone, $zone2, $default ) = @_;
my $ruleschainref = $filter_table->{rules_chain( ${zone}, ${zone2} ) } || $filter_table->{rules_chain( 'all', 'all' ) }; my $ruleschainref = $filter_table->{rules_chain( ${zone}, ${zone2} ) } || $filter_table->{rules_chain( 'all', 'all' ) };
my ( $policy, $loglevel, $defaultaction ) = ( $default , 6, $config{$default . '_DEFAULT'} ); my ( $policy, $loglevel ) = ( $default , 6 );
my $defaultactions = $default_actions{$policy};
my $policychainref; my $policychainref;
$policychainref = $filter_table->{$ruleschainref->{policychain}} if $ruleschainref; $policychainref = $filter_table->{$ruleschainref->{policychain}} if $ruleschainref;
if ( $policychainref ) { if ( $policychainref ) {
( $policy, $loglevel, $defaultaction ) = @{$policychainref}{'policy', 'loglevel', 'default' }; ( $policy, $loglevel, $defaultactions ) = @{$policychainref}{'policy', 'loglevel', 'defaults' };
$stdchainref->{origin} = $policychainref->{origin}; $stdchainref->{origin} = $policychainref->{origin};
} elsif ( $defaultaction !~ /:/ ) {
$defaultaction = normalize_single_action( $defaultaction );
} }
add_policy_rules $stdchainref , $policy , $loglevel, $defaultactions, 0;
add_policy_rules $stdchainref , $policy , $loglevel, $defaultaction, 0;
} }
# #