From d898c87617613071ca8c68b4959e25eb010de65f Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Fri, 17 Sep 2010 11:05:35 -0700 Subject: [PATCH 01/18] Eliminate a parameter to add_jump() --- Shorewall/Perl/Shorewall/Chains.pm | 11 +++++++---- Shorewall/Perl/Shorewall/Rules.pm | 8 ++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index d0e8a9a66..592a96e5c 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -620,6 +620,11 @@ sub insert_rule1($$$) $rule .= "-m comment --comment \"$comment\"" if $comment; $rule = join( ' ', '-A', $rule ); + if ( $number < 0 ) { + $chainref->{frozen}++; + $number = 0; + } + splice( @{$chainref->{rules}}, $number, 0, $rule ); trace( $chainref, 'I', ++$number, $rule ) if $debug; @@ -1040,8 +1045,8 @@ sub ensure_chain($$) # optional 5th argument causes long port lists to be split. The optional 6th # argument, if passed, gives the 0-relative index where the jump is to be inserted. # -sub add_jump( $$$;$$$$ ) { - my ( $fromref, $to, $goto_ok, $predicate, $expandports, $index, $freeze ) = @_; +sub add_jump( $$$;$$$ ) { + my ( $fromref, $to, $goto_ok, $predicate, $expandports, $index ) = @_; $predicate |= ''; @@ -1074,8 +1079,6 @@ sub add_jump( $$$;$$$$ ) { } else { add_rule ($fromref, join( '', $predicate, "-$param $to" ), $expandports || 0 ); } - - $fromref->{frozen}++ if $freeze; } # diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index 314b178fc..b4b681dd9 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -1874,20 +1874,20 @@ sub generate_matrix() { if ( $zoneref->{options}{in}{blacklist} ) { my $blackref = $filter_table->{blacklst}; - add_jump $frwd_ref , $blackref, 0, $state, 0, undef, 1; - add_jump ensure_filter_chain( rules_chain( $zone, firewall_zone ), 1 ) , $blackref , 0, $state, 0, 0, 1; + add_jump $frwd_ref , $blackref, 0, $state, 0, -1; + add_jump ensure_filter_chain( rules_chain( $zone, firewall_zone ), 1 ) , $blackref , 0, $state, 0, -1; } if ( $zoneref->{options}{out}{blacklist} ) { my $blackref = $filter_table->{blackout}; - add_jump ensure_filter_chain( rules_chain( firewall_zone, $zone ), 1 ) , $blackref , 0, $state, 0, 0, 1; + add_jump ensure_filter_chain( rules_chain( firewall_zone, $zone ), 1 ) , $blackref , 0, $state, 0, -1; for my $zone1 ( @zones ) { my $ruleschain = rules_chain( $zone1, $zone ); my $ruleschainref = $filter_table->{$ruleschain}; if ( $zone ne $zone1 || ( $ruleschainref && $ruleschainref->{referenced} ) ) { - add_jump( ensure_filter_chain( $ruleschain, 1 ), $blackref, 0, $state, 0, 0 , 1 ); + add_jump( ensure_filter_chain( $ruleschain, 1 ), $blackref, 0, $state, 0, -1 ); } } } From 7175f8a63e159b3e13815221d8a66c4def74d544 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Fri, 17 Sep 2010 11:06:32 -0700 Subject: [PATCH 02/18] Revert versions on Rules and Zones modules --- Shorewall/Perl/Shorewall/Rules.pm | 2 +- Shorewall/Perl/Shorewall/Zones.pm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index b4b681dd9..3f2d445e7 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -46,7 +46,7 @@ our @EXPORT = qw( process_tos compile_stop_firewall ); our @EXPORT_OK = qw( process_rule process_rule1 initialize ); -our $VERSION = '4.4_14'; +our $VERSION = '4.4_13'; our $macro_nest_level; our $current_param; diff --git a/Shorewall/Perl/Shorewall/Zones.pm b/Shorewall/Perl/Shorewall/Zones.pm index f870d9752..91e4a1209 100644 --- a/Shorewall/Perl/Shorewall/Zones.pm +++ b/Shorewall/Perl/Shorewall/Zones.pm @@ -84,7 +84,7 @@ our @EXPORT = qw( NOTHING ); our @EXPORT_OK = qw( initialize ); -our $VERSION = '4.4_14'; +our $VERSION = '4.4_13'; # # IPSEC Option types From 28aa7b82673b7fdc1f6d4875f59a4be55955c346 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Fri, 17 Sep 2010 11:56:47 -0700 Subject: [PATCH 03/18] Re-add OPTIONS column to blacklist templates --- Shorewall/configfiles/blacklist | 2 +- Shorewall6/blacklist | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Shorewall/configfiles/blacklist b/Shorewall/configfiles/blacklist index 9e7722cb9..172a93e5f 100644 --- a/Shorewall/configfiles/blacklist +++ b/Shorewall/configfiles/blacklist @@ -7,5 +7,5 @@ # information. # ############################################################################### -#ADDRESS/SUBNET PROTOCOL PORT +#ADDRESS/SUBNET PROTOCOL PORT OPTIONS diff --git a/Shorewall6/blacklist b/Shorewall6/blacklist index 6b519040e..df071bedb 100755 --- a/Shorewall6/blacklist +++ b/Shorewall6/blacklist @@ -7,4 +7,4 @@ # information. # ############################################################################### -#ADDRESS/SUBNET PROTOCOL PORT +#ADDRESS/SUBNET PROTOCOL PORT OPTIONS From 2e3635ff50a33b99ea250abc3bf1742206e7f634 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Fri, 17 Sep 2010 12:08:48 -0700 Subject: [PATCH 04/18] Be sure that {frozen} is defined --- Shorewall/Perl/Shorewall/Chains.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 592a96e5c..935259c0d 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -690,8 +690,7 @@ sub increment_reference_count( $$ ) { # # The rules generated by interface options are added to the interfaces's input chain and # forward chain. Shorewall::Rules::generate_matrix() may decide to move those rules to -# a zone-oriented chain, hence this function. -# + sub move_rules( $$ ) { my ($chain1, $chain2 ) = @_; @@ -1011,7 +1010,8 @@ sub new_chain($$) loglevel => '', log => 1, cmdlevel => 0, - references => {} }; + references => {}, + frozen => 0 }; trace( $chainref, 'N', undef, '' ) if $debug; From b76ee408a52925f4f37e3ccdf5c5f154a351d8df Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Fri, 17 Sep 2010 12:35:34 -0700 Subject: [PATCH 05/18] Emit clearer error messages --- Shorewall/Perl/Shorewall/Rules.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index 3f2d445e7..52f15278a 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -282,7 +282,7 @@ sub setup_blacklist() { $target , '' ); } else { - warning_message 'Blacklist entry ignored because there are no "blacklist in" zones'; + warning_message '"src" entry ignored because there are no "blacklist in" zones'; } } } elsif ( $_ =~ /^(?:dst|to)$/ ) { @@ -302,7 +302,7 @@ sub setup_blacklist() { $target , '' ); } else { - warning_message 'Blacklist entry ignored because there are no "blacklist out" zones'; + warning_message '"dst" entry ignored because there are no "blacklist out" zones'; } } } else { From 7a6943fa548f60af73c2321c6375e785f7a07435 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Fri, 17 Sep 2010 12:46:38 -0700 Subject: [PATCH 06/18] Disallow mss and blacklist on firewall and vserver zones --- Shorewall/Perl/Shorewall/Zones.pm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Shorewall/Perl/Shorewall/Zones.pm b/Shorewall/Perl/Shorewall/Zones.pm index 91e4a1209..03f1a705d 100644 --- a/Shorewall/Perl/Shorewall/Zones.pm +++ b/Shorewall/Perl/Shorewall/Zones.pm @@ -309,10 +309,12 @@ sub parse_zone_option_list($$) "tunnel-src" => NETWORK, "tunnel-dst" => NETWORK, ); + + use constant { UNRESTRICTED => 1, NOFW => 2 }; # # Hash of options that have their own key in the returned hash. # - my %key = ( mss => 1 , blacklist => 'blacklist' ); + my %key = ( mss => NOFW , blacklist => NOFW ); my ( $list, $zonetype ) = @_; my %h; @@ -345,6 +347,7 @@ sub parse_zone_option_list($$) } if ( $key{$e} ) { + fatal_error "Option '$e' not permitted with this zone type " if $key{$e} == NOFW && ($zonetype == FIREWALL || $zonetype == VSERVER); $h{$e} = $val || 1; } else { fatal_error "The \"$e\" option may only be specified for ipsec zones" unless $zonetype == IPSEC; From ad660d7fe5bf85292f3e1d2c3a1d1836c3ea581e Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Fri, 17 Sep 2010 13:49:32 -0700 Subject: [PATCH 07/18] Simplify move_rules() --- Shorewall/Perl/Shorewall/Chains.pm | 35 ++++++++++-------------------- Shorewall/Perl/Shorewall/Zones.pm | 2 +- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 935259c0d..160568e53 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -700,8 +700,7 @@ sub move_rules( $$ ) { my $rules = $chain2->{rules}; my $count = @{$chain1->{rules}}; my $tableref = $chain_table{$chain1->{table}}; - my @frozen = (); - my $frozen = $chain2->{frozen} || 0; + my $frozen = $chain2->{frozen}; # # We allow '+' in chain names and '+' is an RE meta-character. Escape it. # @@ -710,29 +709,19 @@ sub move_rules( $$ ) { for ( @{$chain1->{rules}} ) { adjust_reference_counts( $tableref->{$1}, $name1, $name2 ) if / -[jg] ([^\s]+)/; } - # - # Get the frozen rules out of the way for the moment - # - $chain2->{frozen} += $chain1->{frozen}; - unshift @frozen, shift @$rules while $frozen--; - - if ( $debug ) { - my $rule = @{$chain1->{rules}}; - trace( $chain2, 'A', ++$rule, $_ ) for @{$chain1->{rules}}; - } - - unshift @$rules, @{$chain1->{rules}}; - # - # Now re-add the frozen rules at the front - # - unshift @$rules, @frozen; - # - # In a firewall->x policy chain, multiple DHCP ACCEPT rules can be moved to the head of the chain. - # This hack avoids that. - # - shift @{$rules} while @{$rules} > 1 && $rules->[0] eq $rules->[1]; + + splice @$rules, $chain2->{frozen}, 0, @{$chain1->{rules}}; $chain2->{referenced} = 1; + + unless ( $chain2->{frozen} += $chain1->{frozen} ) { + # + # In a firewall->x policy chain, multiple DHCP ACCEPT rules can be moved to the head of the chain. + # This hack avoids that. + # + shift @{$rules} while @{$rules} > 1 && $rules->[0] eq $rules->[1]; + } + delete_chain $chain1; $count; diff --git a/Shorewall/Perl/Shorewall/Zones.pm b/Shorewall/Perl/Shorewall/Zones.pm index 03f1a705d..70af32008 100644 --- a/Shorewall/Perl/Shorewall/Zones.pm +++ b/Shorewall/Perl/Shorewall/Zones.pm @@ -314,7 +314,7 @@ sub parse_zone_option_list($$) # # Hash of options that have their own key in the returned hash. # - my %key = ( mss => NOFW , blacklist => NOFW ); + my %key = ( mss => UNRESTRICTED , blacklist => NOFW ); my ( $list, $zonetype ) = @_; my %h; From 85430e459cf80eb806345821a92d036c51abfe52 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Fri, 17 Sep 2010 14:35:25 -0700 Subject: [PATCH 08/18] Restore trace output in move_rules() Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 160568e53..33cfba648 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -690,6 +690,7 @@ sub increment_reference_count( $$ ) { # # The rules generated by interface options are added to the interfaces's input chain and # forward chain. Shorewall::Rules::generate_matrix() may decide to move those rules to +# the head of a rules chain (behind any frozen rules already there). sub move_rules( $$ ) { my ($chain1, $chain2 ) = @_; @@ -710,7 +711,12 @@ sub move_rules( $$ ) { adjust_reference_counts( $tableref->{$1}, $name1, $name2 ) if / -[jg] ([^\s]+)/; } - splice @$rules, $chain2->{frozen}, 0, @{$chain1->{rules}}; + if ( $debug ) { + my $rule = $frozen; + trace( $chain2, 'A', ++$rule, $_ ) for @{$chain1->{rules}}; + } + + splice @$rules, $frozen, 0, @{$chain1->{rules}}; $chain2->{referenced} = 1; From c9e876fcf52f63881e1bf1297ab2d02f912b1718 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Fri, 17 Sep 2010 15:10:02 -0700 Subject: [PATCH 09/18] Fix an optimization bug with the new blacklisting code --- Shorewall/Perl/Shorewall/Chains.pm | 32 +++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 33cfba648..37a02a0eb 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -744,8 +744,10 @@ sub copy_rules( $$ ) { my $name1 = $chain1->{name}; my $name = $name1; my $name2 = $chain2->{name}; - my @rules = @{$chain1->{rules}}; - my $rules = $chain2->{rules}; + my $frozen1 = $chain1->{frozen}; + my $frozen2 = $chain2->{frozen}; + my @rules1 = @{$chain1->{rules}}; + my $rules2 = $chain2->{rules}; my $count = @{$chain1->{rules}}; my $tableref = $chain_table{$chain1->{table}}; # @@ -753,20 +755,32 @@ sub copy_rules( $$ ) { # $name1 =~ s/\+/\\+/; - my $last = pop @$rules; # Delete the jump to chain1 + my $last = pop @$rules2; # Delete the jump to chain1 - if ( $debug ) { - my $rule = @$rules; - trace( $chain2, 'A', ++$rule, $_ ) for @rules; - } # # Chain2 is now a referent of all of Chain1's targets # - for ( @rules ) { + for ( @rules1 ) { increment_reference_count( $tableref->{$1}, $name2 ) if / -[jg] ([^\s]+)/; } - push @$rules, @rules; + if ( $frozen1 || $frozen2 ) { + if ( $debug ) { + my $rule = @$rules2; + trace( $chain2, 'A', ++$rule, $_ ) for @rules1; + } + + splice @$rules2, $frozen2, 0, splice( @rules1, 0, $frozen1 ); + + $chain2->{frozen} += $frozen1; + } + + if ( $debug ) { + my $rule = @$rules2; + trace( $chain2, 'A', ++$rule, $_ ) for @rules1; + } + + push @$rules2, @rules1; progress_message " $count rules from $chain1->{name} appended to $chain2->{name}"; From c5bb3ecfac76dd5ac6bbee74ef7c90ba3cc05e01 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Fri, 17 Sep 2010 15:42:05 -0700 Subject: [PATCH 10/18] Simplify a test Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 37a02a0eb..1aa2a9649 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -764,7 +764,7 @@ sub copy_rules( $$ ) { increment_reference_count( $tableref->{$1}, $name2 ) if / -[jg] ([^\s]+)/; } - if ( $frozen1 || $frozen2 ) { + if ( $frozen1 ) { if ( $debug ) { my $rule = @$rules2; trace( $chain2, 'A', ++$rule, $_ ) for @rules1; From 6106dd3adaceebfd685fc0e354941dff6b3d5be9 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Fri, 17 Sep 2010 16:00:36 -0700 Subject: [PATCH 11/18] Zero out {frozen} in a deleted chain entry --- Shorewall/Perl/Shorewall/Chains.pm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 1aa2a9649..ac9936077 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -624,7 +624,7 @@ sub insert_rule1($$$) $chainref->{frozen}++; $number = 0; } - + splice( @{$chainref->{rules}}, $number, 0, $rule ); trace( $chainref, 'I', ++$number, $rule ) if $debug; @@ -642,12 +642,13 @@ sub insert_rule($$$) { # # Do final work to 'delete' a chain. We leave it in the chain table but clear -# the 'referenced', 'rules' and 'references' members. +# the 'referenced', 'rules', 'references' and 'frozen' members. # sub delete_chain( $ ) { my $chainref = shift; $chainref->{referenced} = 0; + $chainref->{frozen} = 0; $chainref->{rules} = []; $chainref->{references} = {}; trace( $chainref, 'X', undef, '' ) if $debug; From 1588c700c5d28d51745a268f898d9b4d1dbc31c6 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Fri, 17 Sep 2010 16:38:34 -0700 Subject: [PATCH 12/18] Fix blacklisting vs vservers --- Shorewall/Perl/Shorewall/Rules.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index 52f15278a..86406a9d9 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -1875,14 +1875,14 @@ sub generate_matrix() { if ( $zoneref->{options}{in}{blacklist} ) { my $blackref = $filter_table->{blacklst}; add_jump $frwd_ref , $blackref, 0, $state, 0, -1; - add_jump ensure_filter_chain( rules_chain( $zone, firewall_zone ), 1 ) , $blackref , 0, $state, 0, -1; + add_jump ensure_filter_chain( rules_chain( $zone, $_ ), 1 ) , $blackref , 0, $state, 0, -1 for firewall_zone, @vservers; } if ( $zoneref->{options}{out}{blacklist} ) { my $blackref = $filter_table->{blackout}; add_jump ensure_filter_chain( rules_chain( firewall_zone, $zone ), 1 ) , $blackref , 0, $state, 0, -1; - for my $zone1 ( @zones ) { + for my $zone1 ( @zones, @vservers ) { my $ruleschain = rules_chain( $zone1, $zone ); my $ruleschainref = $filter_table->{$ruleschain}; From fd568ece471396265695621d98d6c62724e6fe68 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Fri, 17 Sep 2010 17:12:34 -0700 Subject: [PATCH 13/18] Clear raw table on 'clear' --- Shorewall/Perl/prog.header | 1 + Shorewall/Perl/prog.header6 | 1 + 2 files changed, 2 insertions(+) diff --git a/Shorewall/Perl/prog.header b/Shorewall/Perl/prog.header index b00bbbfca..3d85d6b32 100644 --- a/Shorewall/Perl/prog.header +++ b/Shorewall/Perl/prog.header @@ -614,6 +614,7 @@ clear_firewall() { setpolicy OUTPUT ACCEPT run_iptables -F + qt $IPTABLES -t raw -F echo 1 > /proc/sys/net/ipv4/ip_forward diff --git a/Shorewall/Perl/prog.header6 b/Shorewall/Perl/prog.header6 index 1931f2448..979a6ad65 100644 --- a/Shorewall/Perl/prog.header6 +++ b/Shorewall/Perl/prog.header6 @@ -584,6 +584,7 @@ clear_firewall() { setpolicy OUTPUT ACCEPT run_iptables -F + qt $IP6TABLES -t raw -F echo 1 > /proc/sys/net/ipv6/conf/all/forwarding From 801c1cb6b3fdb8ad2625228c39f432aa66f5aa52 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Fri, 17 Sep 2010 17:37:07 -0700 Subject: [PATCH 14/18] Update release docs --- Shorewall/changelog.txt | 2 ++ Shorewall/releasenotes.txt | 3 +++ 2 files changed, 5 insertions(+) diff --git a/Shorewall/changelog.txt b/Shorewall/changelog.txt index d7d73f163..b0a9288b4 100644 --- a/Shorewall/changelog.txt +++ b/Shorewall/changelog.txt @@ -31,6 +31,8 @@ Changes in Shorewall 4.4.13 14) Use '-m state' for UNTRACKED. +15) Clear raw table on 'clear' + Changes in Shorewall 4.4.12 1) Fix IPv6 shorecap program. diff --git a/Shorewall/releasenotes.txt b/Shorewall/releasenotes.txt index 6588d32a2..cb0ff7cb7 100644 --- a/Shorewall/releasenotes.txt +++ b/Shorewall/releasenotes.txt @@ -110,6 +110,9 @@ VI. PROBLEMS CORRECTED AND NEW FEATURES IN PRIOR RELEASES state match rather than conntrack match for UNTRACKED state matching. +12) If the routestopped files contains NOTRACK rules, 'shorewall* clear' + does not clear the raw table. + ---------------------------------------------------------------------------- I I. K N O W N P R O B L E M S R E M A I N I N G ---------------------------------------------------------------------------- From c040344bc168df3cc9a793c1646c3d16edb8cbd4 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sat, 18 Sep 2010 07:37:42 -0700 Subject: [PATCH 15/18] Promote 'in' blacklist rules to the head of the interface chain - Added Chains::promote_blacklist_rules() - Called the function from Rules::generate_matrix() Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 103 +++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 27 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index ac9936077..d7406d102 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -155,6 +155,7 @@ our %EXPORT_TAGS = ( do_ipsec log_rule expand_rule + promote_blacklist_rules addnatjump set_chain_variables mark_firewall_not_started @@ -213,7 +214,7 @@ our $VERSION = '4.4_13'; # ] # logchains => { = , ... } # references => { => , => , ... } -# frozen => +# blacklist => # } , # => ... # } @@ -621,7 +622,7 @@ sub insert_rule1($$$) $rule = join( ' ', '-A', $rule ); if ( $number < 0 ) { - $chainref->{frozen}++; + $chainref->{blacklist}++; $number = 0; } @@ -642,13 +643,13 @@ sub insert_rule($$$) { # # Do final work to 'delete' a chain. We leave it in the chain table but clear -# the 'referenced', 'rules', 'references' and 'frozen' members. +# the 'referenced', 'rules', 'references' and 'blacklist' members. # sub delete_chain( $ ) { my $chainref = shift; $chainref->{referenced} = 0; - $chainref->{frozen} = 0; + $chainref->{blacklist} = 0; $chainref->{rules} = []; $chainref->{references} = {}; trace( $chainref, 'X', undef, '' ) if $debug; @@ -691,18 +692,18 @@ sub increment_reference_count( $$ ) { # # The rules generated by interface options are added to the interfaces's input chain and # forward chain. Shorewall::Rules::generate_matrix() may decide to move those rules to -# the head of a rules chain (behind any frozen rules already there). +# the head of a rules chain (behind any blacklist rules already there). sub move_rules( $$ ) { my ($chain1, $chain2 ) = @_; if ( $chain1->{referenced} ) { - my $name1 = $chain1->{name}; - my $name2 = $chain2->{name}; - my $rules = $chain2->{rules}; - my $count = @{$chain1->{rules}}; - my $tableref = $chain_table{$chain1->{table}}; - my $frozen = $chain2->{frozen}; + my $name1 = $chain1->{name}; + my $name2 = $chain2->{name}; + my $rules = $chain2->{rules}; + my $count = @{$chain1->{rules}}; + my $tableref = $chain_table{$chain1->{table}}; + my $blacklist = $chain2->{blacklist}; # # We allow '+' in chain names and '+' is an RE meta-character. Escape it. # @@ -713,15 +714,15 @@ sub move_rules( $$ ) { } if ( $debug ) { - my $rule = $frozen; + my $rule = $blacklist; trace( $chain2, 'A', ++$rule, $_ ) for @{$chain1->{rules}}; } - splice @$rules, $frozen, 0, @{$chain1->{rules}}; + splice @$rules, $blacklist, 0, @{$chain1->{rules}}; $chain2->{referenced} = 1; - unless ( $chain2->{frozen} += $chain1->{frozen} ) { + unless ( $chain2->{blacklist} += $chain1->{blacklist} ) { # # In a firewall->x policy chain, multiple DHCP ACCEPT rules can be moved to the head of the chain. # This hack avoids that. @@ -742,15 +743,15 @@ sub move_rules( $$ ) { sub copy_rules( $$ ) { my ($chain1, $chain2 ) = @_; - my $name1 = $chain1->{name}; - my $name = $name1; - my $name2 = $chain2->{name}; - my $frozen1 = $chain1->{frozen}; - my $frozen2 = $chain2->{frozen}; - my @rules1 = @{$chain1->{rules}}; - my $rules2 = $chain2->{rules}; - my $count = @{$chain1->{rules}}; - my $tableref = $chain_table{$chain1->{table}}; + my $name1 = $chain1->{name}; + my $name = $name1; + my $name2 = $chain2->{name}; + my $blacklist1 = $chain1->{blacklist}; + my $blacklist2 = $chain2->{blacklist}; + my @rules1 = @{$chain1->{rules}}; + my $rules2 = $chain2->{rules}; + my $count = @{$chain1->{rules}}; + my $tableref = $chain_table{$chain1->{table}}; # # We allow '+' in chain names and '+' is an RE meta-character. Escape it. # @@ -765,15 +766,15 @@ sub copy_rules( $$ ) { increment_reference_count( $tableref->{$1}, $name2 ) if / -[jg] ([^\s]+)/; } - if ( $frozen1 ) { + if ( $blacklist1 ) { if ( $debug ) { my $rule = @$rules2; trace( $chain2, 'A', ++$rule, $_ ) for @rules1; } - splice @$rules2, $frozen2, 0, splice( @rules1, 0, $frozen1 ); + splice @$rules2, $blacklist2, 0, splice( @rules1, 0, $blacklist1 ); - $chain2->{frozen} += $frozen1; + $chain2->{blacklist} += $blacklist1; } if ( $debug ) { @@ -1021,7 +1022,7 @@ sub new_chain($$) log => 1, cmdlevel => 0, references => {}, - frozen => 0 }; + blacklist => 0 }; trace( $chainref, 'N', undef, '' ) if $debug; @@ -3678,6 +3679,54 @@ sub expand_rule( $$$$$$$$$$;$ ) $diface; } +# +# Where a zone sharing a multi-zone interface has an 'in' blacklist rule, move the rule to the beginning of +# the associated interface chain +# +sub promote_blacklist_rules() { + for my $chain1ref ( grep $_->{blacklist} , values %$filter_table ) { + my $copied = 0; + my $rule = $chain1ref->{rules}[0]; + # + # Isolate the name of the blacklist chain + # + $rule =~ / -j ([^\/s]+)/; + + my $chainb = $1; + + assert( $chainb && $chainb =~ /^black/ ); + + unless ( $chainb eq 'blackout' ) { + # + # An 'in' blacklist rule + # + for my $chain2ref ( map $filter_table->{$_}, keys %{$chain1ref->{references}} ) { + unless ( $chain2ref->{builtin} ) { + # + # This is not INPUT or FORWARD -- we wouldn't want to move the + # rule to the head of one of those chains + # + $copied++; + # + # Copy the blacklist rule to the head of the parent chain unless it + # already has a blacklist rule. + # + unless ( $chain2ref->{blacklist} ) { + unshift @{$chain2ref->{rules}}, $rule; + $chain2ref->{references}{$chainb}++; + $chain2ref->{blacklist}++; + } + } + } + + if ( $copied ) { + shift @{$chain1ref->{rules}}; + $chain1ref->{blacklist} = 0; + $chain1ref->{references}{chainb}--; + } + } + } +} # # The following code generates the input to iptables-restore from the contents of the # @rules arrays in the chain table entries. From 6f0893cd7a89f44ea12b9fa659aa7ad42bba180f Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sat, 18 Sep 2010 08:36:35 -0700 Subject: [PATCH 16/18] Correct Chains::promote_blacklist_rules() - Interate through chains that jump to 'blacklst' until no rule is promoted This is required to promote jumps past exclusion chains - Correct reference counting; the first cut was horribly wrong Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 42 ++++++++++++++++++------------ 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index d7406d102..cca4474d5 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -214,7 +214,7 @@ our $VERSION = '4.4_13'; # ] # logchains => { = , ... } # references => { => , => , ... } -# blacklist => +# blacklist => ( 0 or 1 ) # } , # => ... # } @@ -3684,19 +3684,26 @@ sub expand_rule( $$$$$$$$$$;$ ) # the associated interface chain # sub promote_blacklist_rules() { - for my $chain1ref ( grep $_->{blacklist} , values %$filter_table ) { - my $copied = 0; - my $rule = $chain1ref->{rules}[0]; - # - # Isolate the name of the blacklist chain - # - $rule =~ / -j ([^\/s]+)/; + my $promoted = 1; + my $chainbref = $filter_table->{blacklst}; - my $chainb = $1; + while ( $promoted ) { + $promoted = 0; - assert( $chainb && $chainb =~ /^black/ ); + for my $chain1ref ( grep $_->{blacklist} , values %$filter_table ) { + my $copied = 0; + my $rule = $chain1ref->{rules}[0]; + my $chain1 = $chain1ref->{name}; + # + # Isolate the name of the blacklist chain + # + $rule =~ / -j ([^\s]+)/; - unless ( $chainb eq 'blackout' ) { + my $chainb = $1; + + assert( $chainb && $chainb =~ /^black/ ); + + next unless $chainb eq 'blacklst'; # # An 'in' blacklist rule # @@ -3705,7 +3712,6 @@ sub promote_blacklist_rules() { # # This is not INPUT or FORWARD -- we wouldn't want to move the # rule to the head of one of those chains - # $copied++; # # Copy the blacklist rule to the head of the parent chain unless it @@ -3713,8 +3719,8 @@ sub promote_blacklist_rules() { # unless ( $chain2ref->{blacklist} ) { unshift @{$chain2ref->{rules}}, $rule; - $chain2ref->{references}{$chainb}++; - $chain2ref->{blacklist}++; + $chainbref->{references}{$chain2ref->{name}}++; + $chain2ref->{blacklist} = 1; } } } @@ -3722,11 +3728,13 @@ sub promote_blacklist_rules() { if ( $copied ) { shift @{$chain1ref->{rules}}; $chain1ref->{blacklist} = 0; - $chain1ref->{references}{chainb}--; + assert ( $chainbref->{references}{$chain1ref->{name}}-- > 0 ); + $promoted = 1; } - } - } + } + } } + # # The following code generates the input to iptables-restore from the contents of the # @rules arrays in the chain table entries. From c3299d5f89057fe588b9a087507e5ba6b4868da7 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sat, 18 Sep 2010 08:36:59 -0700 Subject: [PATCH 17/18] Enable blacklist rule promotion Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Rules.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index 86406a9d9..681b32273 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -2287,6 +2287,8 @@ sub generate_matrix() { add_interface_jumps @interfaces unless $interface_jumps_added; + promote_blacklist_rules; + my %builtins = ( mangle => [ qw/PREROUTING INPUT FORWARD POSTROUTING/ ] , nat=> [ qw/PREROUTING OUTPUT POSTROUTING/ ] , filter=> [ qw/INPUT FORWARD OUTPUT/ ] ); From 0e9c70406965121193d8fbad0e859d574a23f9b3 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sat, 18 Sep 2010 08:42:21 -0700 Subject: [PATCH 18/18] Don't scan the filter table for jumps to 'blacklst' if the 'blacklst' chain does not exist Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index cca4474d5..c9bd94b64 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -3684,9 +3684,12 @@ sub expand_rule( $$$$$$$$$$;$ ) # the associated interface chain # sub promote_blacklist_rules() { - my $promoted = 1; my $chainbref = $filter_table->{blacklst}; + return 1 unless $chainbref; + + my $promoted = 1; + while ( $promoted ) { $promoted = 0;