Ensure that blacklist rules are before the other interface-oriented rules

This commit is contained in:
Tom Eastep 2010-09-16 18:19:16 -07:00
parent 27c445381e
commit 2ce3c8aa88
4 changed files with 51 additions and 33 deletions

View File

@ -213,6 +213,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>
# } , # } ,
# <chain2> => ... # <chain2> => ...
# } # }
@ -695,6 +696,8 @@ sub move_rules( $$ ) {
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 = ();
my $frozen = $chain2->{frozen} || 0;
# #
# 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.
# #
@ -703,13 +706,22 @@ sub move_rules( $$ ) {
for ( @{$chain1->{rules}} ) { for ( @{$chain1->{rules}} ) {
adjust_reference_counts( $tableref->{$1}, $name1, $name2 ) if / -[jg] ([^\s]+)/; 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 ) { if ( $debug ) {
my $rule = @{$chain1->{rules}}; my $rule = @{$chain1->{rules}};
trace( $chain2, 'A', ++$rule, $_ ) for @{$chain1->{rules}}; trace( $chain2, 'A', ++$rule, $_ ) for @{$chain1->{rules}};
} }
unshift @{$rules}, @{$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. # 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.
@ -1028,8 +1040,8 @@ sub ensure_chain($$)
# optional 5th argument causes long port lists to be split. The optional 6th # 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. # argument, if passed, gives the 0-relative index where the jump is to be inserted.
# #
sub add_jump( $$$;$$$ ) { sub add_jump( $$$;$$$$ ) {
my ( $fromref, $to, $goto_ok, $predicate, $expandports, $index ) = @_; my ( $fromref, $to, $goto_ok, $predicate, $expandports, $index, $freeze ) = @_;
$predicate |= ''; $predicate |= '';
@ -1062,6 +1074,8 @@ sub add_jump( $$$;$$$ ) {
} else { } else {
add_rule ($fromref, join( '', $predicate, "-$param $to" ), $expandports || 0 ); add_rule ($fromref, join( '', $predicate, "-$param $to" ), $expandports || 0 );
} }
$fromref->{frozen}++ if $freeze;
} }
# #

View File

@ -1874,16 +1874,21 @@ sub generate_matrix() {
if ( $zoneref->{options}{in}{blacklist} ) { if ( $zoneref->{options}{in}{blacklist} ) {
my $blackref = $filter_table->{blacklst}; my $blackref = $filter_table->{blacklst};
add_jump $frwd_ref , $blackref, 0, $state; 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; add_jump ensure_filter_chain( rules_chain( $zone, firewall_zone ), 1 ) , $blackref , 0, $state, 0, 0, 1;
} }
if ( $zoneref->{options}{out}{blacklist} ) { if ( $zoneref->{options}{out}{blacklist} ) {
my $blackref = $filter_table->{blackout}; my $blackref = $filter_table->{blackout};
add_jump ensure_filter_chain( rules_chain( firewall_zone, $zone ), 1 ) , $blackref , 0, $state, 0, 0; add_jump ensure_filter_chain( rules_chain( firewall_zone, $zone ), 1 ) , $blackref , 0, $state, 0, 0, 1;
for my $zone1 ( @zones ) { for my $zone1 ( @zones ) {
add_jump( ensure_filter_chain( rules_chain( $zone1, $zone ), 1 ), $blackref, 0, $state, 0, 0 ) unless $zone eq $zone1; 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 );
}
} }
} }
@ -2382,33 +2387,38 @@ EOF
$output->{policy} = 'ACCEPT' if $config{ADMINISABSENTMINDED}; $output->{policy} = 'ACCEPT' if $config{ADMINISABSENTMINDED};
if ( $family == F_IPV4 ) { if ( $family == F_IPV4 ) {
emit( ' deletechain() {',
' qt $IPTABLES -L $1 -n && qt $IPTABLES -F $1 && qt $IPTABLES -X $1' );
} else {
emit( ' deletechain() {',
' qt $IP6TABLES -L $1 -n && qt $IP6TABLES -F $1 && qt $IP6TABLES -X $1' );
}
emit <<'EOF'; emit <<'EOF';
deletechain() {
qt $IPTABLES -L $1 -n && qt $IPTABLES -F $1 && qt $IPTABLES -X $1
} }
case $COMMAND in case $COMMAND in
stop|clear|restore) stop|clear|restore)
if chain_exists dynamic; then if chain_exists dynamic; then
EOF ${IPTABLES}-save -t filter | grep '^-A dynamic' > ${VARDIR}/.dynamic
if ( $family == F_IPV4 ) {
emit( ' ${IPTABLES}-save -t filter | grep \'^-A dynamic\' > ${VARDIR}/.dynamic' );
} else {
emit( ' ${IP6TABLES}-save -t filter | grep \'^-A dynamic\' > ${VARDIR}/.dynamic' );
}
emit <<'EOF';
fi fi
;; ;;
*) *)
set +x set +x
EOF
} else {
emit <<'EOF';
deletechain() {
qt $IPTABLES -L $1 -n && qt $IPTABLES -F $1 && qt $IPTABLES -X $1
}
case $COMMAND in
stop|clear|restore)
if chain_exists dynamic; then
${IP6TABLES}-save -t filter | grep '^-A dynamic' > ${VARDIR}/.dynamic
fi
;;
*)
set +x
EOF
}
emit <<'EOF';
case $COMMAND in case $COMMAND in
start) start)
logger -p kern.err "ERROR:$g_product start failed" logger -p kern.err "ERROR:$g_product start failed"

View File

@ -231,7 +231,7 @@ sub initialize( $ ) {
if ( $family == F_IPV4 ) { if ( $family == F_IPV4 ) {
%validinterfaceoptions = (arp_filter => BINARY_IF_OPTION, %validinterfaceoptions = (arp_filter => BINARY_IF_OPTION,
arp_ignore => ENUM_IF_OPTION, arp_ignore => ENUM_IF_OPTION,
blacklist => SIMPLE_IF_OPTION, blacklist => SIMPLE_IF_OPTION + IF_OPTION_HOST,
bridge => SIMPLE_IF_OPTION, bridge => SIMPLE_IF_OPTION,
detectnets => OBSOLETE_IF_OPTION, detectnets => OBSOLETE_IF_OPTION,
dhcp => SIMPLE_IF_OPTION, dhcp => SIMPLE_IF_OPTION,
@ -264,7 +264,7 @@ sub initialize( $ ) {
sourceonly => 1, sourceonly => 1,
); );
} else { } else {
%validinterfaceoptions = ( blacklist => SIMPLE_IF_OPTION, %validinterfaceoptions = ( blacklist => SIMPLE_IF_OPTION + IF_OPTION_HOST,
bridge => SIMPLE_IF_OPTION, bridge => SIMPLE_IF_OPTION,
dhcp => SIMPLE_IF_OPTION, dhcp => SIMPLE_IF_OPTION,
maclist => SIMPLE_IF_OPTION + IF_OPTION_HOST, maclist => SIMPLE_IF_OPTION + IF_OPTION_HOST,

View File

@ -224,12 +224,6 @@ VI. PROBLEMS CORRECTED AND NEW FEATURES IN PRIOR RELEASES
to be supported for several releases. A warning will be added at to be supported for several releases. A warning will be added at
least one release before support is removed. least one release before support is removed.
g) Given that blacklisting is now zone-based, there is a slight
change in behavior. Previously, blacklisting was done before
the other interface-oriented checks (tcpflags, nosmurfs, dhcp,
etc.). Beginning with this release, blacklisting is performed
after these checks.
5) There is now an OUT-BANDWIDTH column in 5) There is now an OUT-BANDWIDTH column in
/etc/shorewall/tcinterfaces. /etc/shorewall/tcinterfaces.