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>, ... }
# references => { <ref1> => <refs>, <ref2> => <refs>, ... }
# frozen => <number of frozen rules at the head of the rules array>
# } ,
# <chain2> => ...
# }
@ -695,6 +696,8 @@ sub move_rules( $$ ) {
my $rules = $chain2->{rules};
my $count = @{$chain1->{rules}};
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.
#
@ -703,13 +706,22 @@ 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}};
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.
@ -1028,8 +1040,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 ) = @_;
sub add_jump( $$$;$$$$ ) {
my ( $fromref, $to, $goto_ok, $predicate, $expandports, $index, $freeze ) = @_;
$predicate |= '';
@ -1062,6 +1074,8 @@ sub add_jump( $$$;$$$ ) {
} else {
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} ) {
my $blackref = $filter_table->{blacklst};
add_jump $frwd_ref , $blackref, 0, $state;
add_jump ensure_filter_chain( rules_chain( $zone, firewall_zone ), 1 ) , $blackref , 0, $state, 0, 0;
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;
}
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;
add_jump ensure_filter_chain( rules_chain( firewall_zone, $zone ), 1 ) , $blackref , 0, $state, 0, 0, 1;
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};
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';
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
EOF
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';
${IPTABLES}-save -t filter | grep '^-A dynamic' > ${VARDIR}/.dynamic
fi
;;
*)
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
start)
logger -p kern.err "ERROR:$g_product start failed"

View File

@ -231,7 +231,7 @@ sub initialize( $ ) {
if ( $family == F_IPV4 ) {
%validinterfaceoptions = (arp_filter => BINARY_IF_OPTION,
arp_ignore => ENUM_IF_OPTION,
blacklist => SIMPLE_IF_OPTION,
blacklist => SIMPLE_IF_OPTION + IF_OPTION_HOST,
bridge => SIMPLE_IF_OPTION,
detectnets => OBSOLETE_IF_OPTION,
dhcp => SIMPLE_IF_OPTION,
@ -264,7 +264,7 @@ sub initialize( $ ) {
sourceonly => 1,
);
} else {
%validinterfaceoptions = ( blacklist => SIMPLE_IF_OPTION,
%validinterfaceoptions = ( blacklist => SIMPLE_IF_OPTION + IF_OPTION_HOST,
bridge => SIMPLE_IF_OPTION,
dhcp => SIMPLE_IF_OPTION,
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
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
/etc/shorewall/tcinterfaces.