mirror of
https://gitlab.com/shorewall/code.git
synced 2024-12-25 23:59:01 +01:00
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 <teastep@shorewall.net>
This commit is contained in:
parent
9946fbd3b5
commit
fd6ff1849a
@ -155,6 +155,7 @@ our %EXPORT_TAGS = (
|
|||||||
do_ipsec
|
do_ipsec
|
||||||
log_rule
|
log_rule
|
||||||
expand_rule
|
expand_rule
|
||||||
|
promote_blacklist_rules
|
||||||
addnatjump
|
addnatjump
|
||||||
set_chain_variables
|
set_chain_variables
|
||||||
mark_firewall_not_started
|
mark_firewall_not_started
|
||||||
@ -213,7 +214,7 @@ our $VERSION = '4.4_13';
|
|||||||
# ]
|
# ]
|
||||||
# logchains => { <key1> = <chainref1>, ... }
|
# logchains => { <key1> = <chainref1>, ... }
|
||||||
# references => { <ref1> => <refs>, <ref2> => <refs>, ... }
|
# references => { <ref1> => <refs>, <ref2> => <refs>, ... }
|
||||||
# frozen => <number of frozen rules at the head of the rules array>
|
# blacklist => <number of blacklist rules at the head of the rules array>
|
||||||
# } ,
|
# } ,
|
||||||
# <chain2> => ...
|
# <chain2> => ...
|
||||||
# }
|
# }
|
||||||
@ -621,7 +622,7 @@ sub insert_rule1($$$)
|
|||||||
$rule = join( ' ', '-A', $rule );
|
$rule = join( ' ', '-A', $rule );
|
||||||
|
|
||||||
if ( $number < 0 ) {
|
if ( $number < 0 ) {
|
||||||
$chainref->{frozen}++;
|
$chainref->{blacklist}++;
|
||||||
$number = 0;
|
$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
|
# 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( $ ) {
|
sub delete_chain( $ ) {
|
||||||
my $chainref = shift;
|
my $chainref = shift;
|
||||||
|
|
||||||
$chainref->{referenced} = 0;
|
$chainref->{referenced} = 0;
|
||||||
$chainref->{frozen} = 0;
|
$chainref->{blacklist} = 0;
|
||||||
$chainref->{rules} = [];
|
$chainref->{rules} = [];
|
||||||
$chainref->{references} = {};
|
$chainref->{references} = {};
|
||||||
trace( $chainref, 'X', undef, '' ) if $debug;
|
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
|
# 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
|
# 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( $$ ) {
|
sub move_rules( $$ ) {
|
||||||
my ($chain1, $chain2 ) = @_;
|
my ($chain1, $chain2 ) = @_;
|
||||||
|
|
||||||
if ( $chain1->{referenced} ) {
|
if ( $chain1->{referenced} ) {
|
||||||
my $name1 = $chain1->{name};
|
my $name1 = $chain1->{name};
|
||||||
my $name2 = $chain2->{name};
|
my $name2 = $chain2->{name};
|
||||||
my $rules = $chain2->{rules};
|
my $rules = $chain2->{rules};
|
||||||
my $count = @{$chain1->{rules}};
|
my $count = @{$chain1->{rules}};
|
||||||
my $tableref = $chain_table{$chain1->{table}};
|
my $tableref = $chain_table{$chain1->{table}};
|
||||||
my $frozen = $chain2->{frozen};
|
my $blacklist = $chain2->{blacklist};
|
||||||
#
|
#
|
||||||
# We allow '+' in chain names and '+' is an RE meta-character. Escape it.
|
# We allow '+' in chain names and '+' is an RE meta-character. Escape it.
|
||||||
#
|
#
|
||||||
@ -713,15 +714,15 @@ sub move_rules( $$ ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( $debug ) {
|
if ( $debug ) {
|
||||||
my $rule = $frozen;
|
my $rule = $blacklist;
|
||||||
trace( $chain2, 'A', ++$rule, $_ ) for @{$chain1->{rules}};
|
trace( $chain2, 'A', ++$rule, $_ ) for @{$chain1->{rules}};
|
||||||
}
|
}
|
||||||
|
|
||||||
splice @$rules, $frozen, 0, @{$chain1->{rules}};
|
splice @$rules, $blacklist, 0, @{$chain1->{rules}};
|
||||||
|
|
||||||
$chain2->{referenced} = 1;
|
$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.
|
# In a firewall->x policy chain, multiple DHCP ACCEPT rules can be moved to the head of the chain.
|
||||||
# This hack avoids that.
|
# This hack avoids that.
|
||||||
@ -742,15 +743,15 @@ sub move_rules( $$ ) {
|
|||||||
sub copy_rules( $$ ) {
|
sub copy_rules( $$ ) {
|
||||||
my ($chain1, $chain2 ) = @_;
|
my ($chain1, $chain2 ) = @_;
|
||||||
|
|
||||||
my $name1 = $chain1->{name};
|
my $name1 = $chain1->{name};
|
||||||
my $name = $name1;
|
my $name = $name1;
|
||||||
my $name2 = $chain2->{name};
|
my $name2 = $chain2->{name};
|
||||||
my $frozen1 = $chain1->{frozen};
|
my $blacklist1 = $chain1->{blacklist};
|
||||||
my $frozen2 = $chain2->{frozen};
|
my $blacklist2 = $chain2->{blacklist};
|
||||||
my @rules1 = @{$chain1->{rules}};
|
my @rules1 = @{$chain1->{rules}};
|
||||||
my $rules2 = $chain2->{rules};
|
my $rules2 = $chain2->{rules};
|
||||||
my $count = @{$chain1->{rules}};
|
my $count = @{$chain1->{rules}};
|
||||||
my $tableref = $chain_table{$chain1->{table}};
|
my $tableref = $chain_table{$chain1->{table}};
|
||||||
#
|
#
|
||||||
# We allow '+' in chain names and '+' is an RE meta-character. Escape it.
|
# 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]+)/;
|
increment_reference_count( $tableref->{$1}, $name2 ) if / -[jg] ([^\s]+)/;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $frozen1 ) {
|
if ( $blacklist1 ) {
|
||||||
if ( $debug ) {
|
if ( $debug ) {
|
||||||
my $rule = @$rules2;
|
my $rule = @$rules2;
|
||||||
trace( $chain2, 'A', ++$rule, $_ ) for @rules1;
|
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 ) {
|
if ( $debug ) {
|
||||||
@ -1021,7 +1022,7 @@ sub new_chain($$)
|
|||||||
log => 1,
|
log => 1,
|
||||||
cmdlevel => 0,
|
cmdlevel => 0,
|
||||||
references => {},
|
references => {},
|
||||||
frozen => 0 };
|
blacklist => 0 };
|
||||||
|
|
||||||
trace( $chainref, 'N', undef, '' ) if $debug;
|
trace( $chainref, 'N', undef, '' ) if $debug;
|
||||||
|
|
||||||
@ -3678,6 +3679,54 @@ sub expand_rule( $$$$$$$$$$;$ )
|
|||||||
$diface;
|
$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
|
# The following code generates the input to iptables-restore from the contents of the
|
||||||
# @rules arrays in the chain table entries.
|
# @rules arrays in the chain table entries.
|
||||||
|
Loading…
Reference in New Issue
Block a user