From 9f423412d813d08aa84044d5c5bf31d0f187c3e7 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Mon, 21 Jan 2019 11:07:52 -0800 Subject: [PATCH] Allow zone exclusion in the policy file Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Rules.pm | 44 ++++++++++++++++++++----- Shorewall/manpages/shorewall-policy.xml | 24 +++++++++----- 2 files changed, 52 insertions(+), 16 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index a28882ab5..0ada5dc61 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -672,14 +672,42 @@ sub process_a_policy1($$$$$$$) { my ( $client, $server, $originalpolicy, $loglevel, $synparams, $connlimit, $intrazone ) = @_; - my $clientwild = ( "\L$client" =~ /^all(\+)?$/ ); + my $clientwild = ( "\L$client" =~ /^all(\+)?(?:!(.+))?$/ ); + my $clientexclude; + my %clientexcluded; - $intrazone ||= $clientwild && $1; + if ( $clientwild ) { + $intrazone ||= $1; + + if ( $clientexclude = $2 ) { + for my $client ( split_list( $clientexclude, 'zone' ) ) { + fatal_error "Undefined zone ($client)" unless defined_zone( $client ); + $clientexcluded{$client} = 1; + } + + $client = 'all'; + } + } fatal_error "Undefined zone ($client)" unless $clientwild || defined_zone( $client ); - my $serverwild = ( "\L$server" =~ /^all(\+)?/ ); - $intrazone ||= ( $serverwild && $1 ); + my $serverwild = ( "\L$server" =~ /^all(\+)?(?:!(.+))?/ ); + my $serverexclude; + my %serverexcluded; + + + if ( $serverwild ) { + $intrazone ||= $1; + + if ( $serverexclude = $2 ) { + for my $server ( split_list( $serverexclude, 'zone' ) ) { + fatal_error "Undefined zone ($server)" unless defined_zone( $server ); + $serverexcluded{$server} = 1; + } + + $server = 'all'; + } + } fatal_error "Undefined zone ($server)" unless $serverwild || defined_zone( $server ); @@ -762,20 +790,20 @@ sub process_a_policy1($$$$$$$) { if ( $clientwild ) { if ( $serverwild ) { - for my $zone ( @zonelist ) { - for my $zone1 ( @zonelist ) { + for my $zone ( grep( ! $clientexcluded{$_}, @zonelist ) ) { + for my $zone1 ( grep( ! $serverexcluded{zone}, @zonelist ) ) { set_policy_chain $zone, $zone1, $chainref, $policy, $intrazone; print_policy $zone, $zone1, $originalpolicy, $chain; } } } else { - for my $zone ( all_zones ) { + for my $zone ( grep( ! $clientexcluded{$_}, all_zones ) ) { set_policy_chain $zone, $server, $chainref, $policy, $intrazone; print_policy $zone, $server, $originalpolicy, $chain; } } } elsif ( $serverwild ) { - for my $zone ( @zonelist ) { + for my $zone ( grep( ! $serverexcluded{$_}, @zonelist ) ) { set_policy_chain $client, $zone, $chainref, $policy, $intrazone; print_policy $client, $zone, $originalpolicy, $chain; } diff --git a/Shorewall/manpages/shorewall-policy.xml b/Shorewall/manpages/shorewall-policy.xml index cd6eedb77..1f7d7cfac 100644 --- a/Shorewall/manpages/shorewall-policy.xml +++ b/Shorewall/manpages/shorewall-policy.xml @@ -68,32 +68,35 @@ SOURCE - zone[,...[+]]|$FW|all|all+ + role="bold">all[+][!ezone[,...]] Source zone. Must be the name of a zone defined in shorewall-zones(5), $FW, "all" or "all+". - Support for "all+" was added in Shorewall 4.5.17. "all" does - not override the implicit intra-zone ACCEPT policy while "all+" - does. + Support for all+ was added in + Shorewall 4.5.17. all does not + override the implicit intra-zone ACCEPT policy while all+ does. Beginning with Shorewall 5.0.12, multiple zones may be listed separated by commas. As above, if '+' is specified after two or more zone names, then the policy overrides the implicit intra-zone ACCEPT policy if the same zone appears in both the SOURCE and DEST columns. + + Beginning with Shorewall 5.2.3, a comma-separated list of + excluded zones preceded by "!" may follow all or all+. DEST - zone[,...[+]]|$FW|all|all+ + role="bold">$FW|all[+][!ezone[,...]] Destination zone. Must be the name of a zone defined in zone appears in both the SOURCE and DEST columns. + + Beginning with Shorewall 5.2.3, a comma-separated list of + excluded zones preceded by "!" may follow all or all+.