forked from extern/shorewall_code
Add conditional logic for optional run-time address variables
Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
parent
47cdbd04db
commit
7555a0953d
@ -146,6 +146,8 @@ our %EXPORT_TAGS = (
|
||||
do_headers
|
||||
have_ipset_rules
|
||||
record_runtime_address
|
||||
conditional_rule
|
||||
conditional_rule_end
|
||||
match_source_dev
|
||||
match_dest_dev
|
||||
iprange_match
|
||||
@ -2689,6 +2691,38 @@ sub record_runtime_address( $ ) {
|
||||
get_interface_address( $interface ) . ' ';
|
||||
}
|
||||
|
||||
#
|
||||
# If the passed address is a run-time address variable for an optional interface, then
|
||||
# begin a conditional rule block that tests the address for nil.
|
||||
#
|
||||
sub conditional_rule( $$ ) {
|
||||
my ( $chainref, $address ) = @_;
|
||||
|
||||
if ( $address =~ /^!?&(.+)$/ ) {
|
||||
my $interface = $1;
|
||||
if ( my $ref = known_interface $interface ) {
|
||||
if ( $ref->{options}{optional} ) {
|
||||
my $variable = get_interface_address( $interface );
|
||||
add_commands( $chainref , "if [ $variable != " . NILIP . ' ]; then' );
|
||||
incr_cmd_level $chainref;
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
0;
|
||||
}
|
||||
|
||||
#
|
||||
# If end a conditional in a chain
|
||||
#
|
||||
|
||||
sub conditional_rule_end( $ ) {
|
||||
my $chainref = shift;
|
||||
decr_cmd_level $chainref;
|
||||
add_commands( $chainref , "fi\n" );
|
||||
}
|
||||
|
||||
sub mysplit( $ );
|
||||
|
||||
#
|
||||
@ -3453,6 +3487,8 @@ sub handle_network_list( $$ ) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
################################################################################################################
|
||||
#
|
||||
# This function provides a uniform way to generate Netfilter[6] rules (something the original Shorewall
|
||||
@ -3800,9 +3836,23 @@ sub expand_rule( $$$$$$$$$$;$ )
|
||||
#
|
||||
my $exclude = '-j MARK --or-mark ' . in_hex( $globals{EXCLUSION_MASK} );
|
||||
|
||||
add_rule $chainref, ( match_source_net $_ , $restriction ) . $exclude for ( mysplit $iexcl );
|
||||
add_rule $chainref, ( match_dest_net $_ ) . $exclude for ( mysplit $dexcl );
|
||||
add_rule $chainref, ( match_orig_dest $_ ) . $exclude for ( mysplit $oexcl );
|
||||
for ( mysplit $iexcl ) {
|
||||
my $cond = conditional_rule( $chainref, $_ );
|
||||
add_rule $chainref, ( match_source_net $_ , $restriction ) . $exclude;
|
||||
conditional_rule_end( $chainref ) if $cond;
|
||||
}
|
||||
|
||||
for ( mysplit $dexcl ) {
|
||||
my $cond = conditional_rule( $chainref, $_ );
|
||||
add_rule $chainref, ( match_dest_net $_ ) . $exclude;
|
||||
conditional_rule_end( $chainref ) if $cond;
|
||||
}
|
||||
|
||||
for ( mysplit $oexcl ) {
|
||||
my $cond = conditional_rule( $chainref, $_ );
|
||||
add_rule $chainref, ( match_orig_dest $_ ) . $exclude;
|
||||
conditional_rule_end( $chainref ) if $cond;
|
||||
}
|
||||
#
|
||||
# Augment the rule to include 'not excluded'
|
||||
#
|
||||
@ -3818,25 +3868,47 @@ sub expand_rule( $$$$$$$$$$;$ )
|
||||
# Use the current rule and send all possible matches to the exclusion chain
|
||||
#
|
||||
for my $onet ( mysplit $onets ) {
|
||||
|
||||
my $cond = conditional_rule( $chainref, $onet );
|
||||
|
||||
$onet = match_orig_dest $onet;
|
||||
|
||||
for my $inet ( mysplit $inets ) {
|
||||
|
||||
my $cond = conditional_rule( $chainref, $inet );
|
||||
|
||||
my $source_match = match_source_net( $inet, $restriction ) if have_capability( 'KLUDGEFREE' );
|
||||
|
||||
for my $dnet ( mysplit $dnets ) {
|
||||
$source_match = match_source_net( $inet, $restriction ) unless have_capability( 'KLUDGEFREE' );
|
||||
add_jump( $chainref, $echainref, 0, join( '', $rule, $source_match, match_dest_net( $dnet ), $onet ), 1 );
|
||||
}
|
||||
|
||||
conditional_rule_end( $chainref ) if $cond;
|
||||
}
|
||||
|
||||
conditional_rule_end( $chainref ) if $cond;
|
||||
}
|
||||
#
|
||||
# Generate RETURNs for each exclusion
|
||||
#
|
||||
add_rule $echainref, ( match_source_net $_ , $restriction ) . '-j RETURN' for ( mysplit $iexcl );
|
||||
add_rule $echainref, ( match_dest_net $_ ) . '-j RETURN' for ( mysplit $dexcl );
|
||||
add_rule $echainref, ( match_orig_dest $_ ) . '-j RETURN' for ( mysplit $oexcl );
|
||||
for ( mysplit $iexcl ) {
|
||||
my $cond = conditional_rule( $echainref, $_ );
|
||||
add_rule $echainref, ( match_source_net $_ , $restriction ) . '-j RETURN';
|
||||
conditional_rule_end( $echainref ) if $cond;
|
||||
}
|
||||
|
||||
for ( mysplit $dexcl ) {
|
||||
my $cond = conditional_rule( $echainref, $_ );
|
||||
add_rule $echainref, ( match_dest_net $_ ) . '-j RETURN';
|
||||
conditional_rule_end( $echainref ) if $cond;
|
||||
}
|
||||
|
||||
for ( mysplit $oexcl ) {
|
||||
my $cond = conditional_rule( $echainref, $_ );
|
||||
add_rule $echainref, ( match_orig_dest $_ ) . '-j RETURN';
|
||||
conditional_rule_end( $echainref ) if $cond;
|
||||
}
|
||||
#
|
||||
# Log rule
|
||||
#
|
||||
@ -3863,10 +3935,15 @@ sub expand_rule( $$$$$$$$$$;$ )
|
||||
# No non-trivial exclusions or we're using marks to handle them
|
||||
#
|
||||
for my $onet ( mysplit $onets ) {
|
||||
my $cond = conditional_rule( $chainref, $onet );
|
||||
|
||||
$onet = match_orig_dest $onet;
|
||||
|
||||
for my $inet ( mysplit $inets ) {
|
||||
my $source_match;
|
||||
|
||||
my $cond = conditional_rule( $chainref, $inet );
|
||||
|
||||
$source_match = match_source_net( $inet, $restriction ) if have_capability( 'KLUDGEFREE' );
|
||||
|
||||
for my $dnet ( mysplit $dnets ) {
|
||||
@ -3874,6 +3951,8 @@ sub expand_rule( $$$$$$$$$$;$ )
|
||||
my $dest_match = match_dest_net( $dnet );
|
||||
my $matches = join( '', $rule, $source_match, $dest_match, $onet );
|
||||
|
||||
my $cond = conditional_rule( $chainref, $dnet );
|
||||
|
||||
if ( $loglevel eq '' ) {
|
||||
#
|
||||
# No logging -- add the target rule with matches to the rule chain
|
||||
@ -3916,8 +3995,14 @@ sub expand_rule( $$$$$$$$$$;$ )
|
||||
$matches,
|
||||
1 );
|
||||
}
|
||||
|
||||
conditional_rule_end( $chainref ) if $cond;
|
||||
}
|
||||
|
||||
conditional_rule_end( $chainref ) if $cond;
|
||||
}
|
||||
|
||||
conditional_rule_end( $chainref ) if $cond;
|
||||
}
|
||||
}
|
||||
#
|
||||
|
@ -34,6 +34,8 @@ use strict;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT = qw( ALLIPv4
|
||||
ALLIPv6
|
||||
NILIPv4
|
||||
NILIPv6
|
||||
IPv4_MULTICAST
|
||||
IPv6_MULTICAST
|
||||
IPv6_LINKLOCAL
|
||||
@ -44,6 +46,7 @@ our @EXPORT = qw( ALLIPv4
|
||||
IPv6_SITE_ALLNODES
|
||||
IPv6_SITE_ALLRTRS
|
||||
ALLIP
|
||||
NILIP
|
||||
ALL
|
||||
TCP
|
||||
UDP
|
||||
@ -63,6 +66,9 @@ our @EXPORT = qw( ALLIPv4
|
||||
allipv4
|
||||
allipv6
|
||||
allip
|
||||
nilipv4
|
||||
nilipv6
|
||||
nilip
|
||||
rfc1918_networks
|
||||
resolve_proto
|
||||
proto_name
|
||||
@ -73,7 +79,7 @@ our @EXPORT = qw( ALLIPv4
|
||||
validate_icmp6
|
||||
);
|
||||
our @EXPORT_OK = qw( );
|
||||
our $VERSION = '4.4_14';
|
||||
our $VERSION = '4.4_17';
|
||||
|
||||
#
|
||||
# Some IPv4/6 useful stuff
|
||||
@ -82,6 +88,10 @@ our @allipv4 = ( '0.0.0.0/0' );
|
||||
our @allipv6 = ( '::/0' );
|
||||
our $allip;
|
||||
our @allip;
|
||||
our @nilipv4 = ( '0.0.0.0' );
|
||||
our @nilipv6 = ( '::' );
|
||||
our $nilip;
|
||||
our @nilip;
|
||||
our $valid_address;
|
||||
our $validate_address;
|
||||
our $validate_net;
|
||||
@ -91,6 +101,8 @@ our $family;
|
||||
|
||||
use constant { ALLIPv4 => '0.0.0.0/0' ,
|
||||
ALLIPv6 => '::/0' ,
|
||||
NILIPv4 => '0.0.0.0' ,
|
||||
NILIPv6 => '::' ,
|
||||
IPv4_MULTICAST => '224.0.0.0/4' ,
|
||||
IPv6_MULTICAST => 'ff00::/8' ,
|
||||
IPv6_LINKLOCAL => 'fe80::/10' ,
|
||||
@ -280,6 +292,14 @@ sub allipv6() {
|
||||
@allipv6;
|
||||
}
|
||||
|
||||
sub nilipv4() {
|
||||
@nilipv4;
|
||||
}
|
||||
|
||||
sub nilipv6() {
|
||||
@nilipv6;
|
||||
}
|
||||
|
||||
sub rfc1918_networks() {
|
||||
@rfc1918_networks
|
||||
}
|
||||
@ -674,6 +694,14 @@ sub allip() {
|
||||
@allip;
|
||||
}
|
||||
|
||||
sub NILIP() {
|
||||
$nilip;
|
||||
}
|
||||
|
||||
sub nilip() {
|
||||
@nilip;
|
||||
}
|
||||
|
||||
sub valid_address ( $ ) {
|
||||
$valid_address->(@_);
|
||||
}
|
||||
@ -710,6 +738,8 @@ sub initialize( $ ) {
|
||||
if ( $family == F_IPV4 ) {
|
||||
$allip = ALLIPv4;
|
||||
@allip = @allipv4;
|
||||
$nilip = NILIPv4;
|
||||
@nilip = @nilipv4;
|
||||
$valid_address = \&valid_4address;
|
||||
$validate_address = \&validate_4address;
|
||||
$validate_net = \&validate_4net;
|
||||
@ -718,6 +748,8 @@ sub initialize( $ ) {
|
||||
} else {
|
||||
$allip = ALLIPv6;
|
||||
@allip = @allipv6;
|
||||
$nilip = NILIPv6;
|
||||
@nilip = @nilipv6;
|
||||
$valid_address = \&valid_6address;
|
||||
$validate_address = \&validate_6address;
|
||||
$validate_net = \&validate_6net;
|
||||
|
@ -155,6 +155,7 @@ sub process_one_masq( )
|
||||
my $exceptionrule = '';
|
||||
my $randomize = '';
|
||||
my $persistent = '';
|
||||
my $conditional = 0;
|
||||
#
|
||||
# Parse the ADDRESSES column
|
||||
#
|
||||
@ -188,7 +189,11 @@ sub process_one_masq( )
|
||||
for my $addr ( split_list $addresses , 'address' ) {
|
||||
if ( $addr =~ /^&(.+)$/ ) {
|
||||
$target = 'SNAT ';
|
||||
$addrlist .= '--to-source ' . record_runtime_address $1;
|
||||
if ( $conditional = conditional_rule( $chainref, $addr ) ) {
|
||||
$addrlist .= '--to-source ' . get_interface_address $1;
|
||||
} else {
|
||||
$addrlist .= '--to-source ' . record_runtime_address $1;
|
||||
}
|
||||
} elsif ( $addr =~ /^.*\..*\..*\./ ) {
|
||||
$target = 'SNAT ';
|
||||
my ($ipaddr, $rest) = split ':', $addr;
|
||||
@ -232,10 +237,7 @@ sub process_one_masq( )
|
||||
'' ,
|
||||
$exceptionrule );
|
||||
|
||||
if ( $detectaddress ) {
|
||||
decr_cmd_level( $chainref );
|
||||
add_commands( $chainref , 'fi' );
|
||||
}
|
||||
conditional_rule_end( $chainref ) if $detectaddress || $conditional;
|
||||
|
||||
if ( $add_snat_aliases ) {
|
||||
my ( $interface, $alias , $remainder ) = split( /:/, $fullinterface, 3 );
|
||||
|
@ -109,9 +109,8 @@ Beta 2
|
||||
file.
|
||||
|
||||
For optional interfaces, if the interface is not usable at the time
|
||||
that the firewall starts the all-zero address (0.0.0.0 in IPv4 and
|
||||
:: in IPv6) will be substituted, resulting in no packets matching
|
||||
the rule.
|
||||
that the firewall starts, the resulting Netfilter rule(s)
|
||||
containing the interface address are not added.
|
||||
|
||||
Beta 1
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user