mirror of
https://gitlab.com/shorewall/code.git
synced 2025-02-10 23:09:17 +01:00
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
|
do_headers
|
||||||
have_ipset_rules
|
have_ipset_rules
|
||||||
record_runtime_address
|
record_runtime_address
|
||||||
|
conditional_rule
|
||||||
|
conditional_rule_end
|
||||||
match_source_dev
|
match_source_dev
|
||||||
match_dest_dev
|
match_dest_dev
|
||||||
iprange_match
|
iprange_match
|
||||||
@ -2689,6 +2691,38 @@ sub record_runtime_address( $ ) {
|
|||||||
get_interface_address( $interface ) . ' ';
|
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( $ );
|
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
|
# 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} );
|
my $exclude = '-j MARK --or-mark ' . in_hex( $globals{EXCLUSION_MASK} );
|
||||||
|
|
||||||
add_rule $chainref, ( match_source_net $_ , $restriction ) . $exclude for ( mysplit $iexcl );
|
for ( mysplit $iexcl ) {
|
||||||
add_rule $chainref, ( match_dest_net $_ ) . $exclude for ( mysplit $dexcl );
|
my $cond = conditional_rule( $chainref, $_ );
|
||||||
add_rule $chainref, ( match_orig_dest $_ ) . $exclude for ( mysplit $oexcl );
|
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'
|
# Augment the rule to include 'not excluded'
|
||||||
#
|
#
|
||||||
@ -3819,24 +3869,46 @@ sub expand_rule( $$$$$$$$$$;$ )
|
|||||||
#
|
#
|
||||||
for my $onet ( mysplit $onets ) {
|
for my $onet ( mysplit $onets ) {
|
||||||
|
|
||||||
|
my $cond = conditional_rule( $chainref, $onet );
|
||||||
|
|
||||||
$onet = match_orig_dest $onet;
|
$onet = match_orig_dest $onet;
|
||||||
|
|
||||||
for my $inet ( mysplit $inets ) {
|
for my $inet ( mysplit $inets ) {
|
||||||
|
|
||||||
|
my $cond = conditional_rule( $chainref, $inet );
|
||||||
|
|
||||||
my $source_match = match_source_net( $inet, $restriction ) if have_capability( 'KLUDGEFREE' );
|
my $source_match = match_source_net( $inet, $restriction ) if have_capability( 'KLUDGEFREE' );
|
||||||
|
|
||||||
for my $dnet ( mysplit $dnets ) {
|
for my $dnet ( mysplit $dnets ) {
|
||||||
$source_match = match_source_net( $inet, $restriction ) unless have_capability( 'KLUDGEFREE' );
|
$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 );
|
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
|
# Generate RETURNs for each exclusion
|
||||||
#
|
#
|
||||||
add_rule $echainref, ( match_source_net $_ , $restriction ) . '-j RETURN' for ( mysplit $iexcl );
|
for ( mysplit $iexcl ) {
|
||||||
add_rule $echainref, ( match_dest_net $_ ) . '-j RETURN' for ( mysplit $dexcl );
|
my $cond = conditional_rule( $echainref, $_ );
|
||||||
add_rule $echainref, ( match_orig_dest $_ ) . '-j RETURN' for ( mysplit $oexcl );
|
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
|
# Log rule
|
||||||
#
|
#
|
||||||
@ -3863,10 +3935,15 @@ sub expand_rule( $$$$$$$$$$;$ )
|
|||||||
# No non-trivial exclusions or we're using marks to handle them
|
# No non-trivial exclusions or we're using marks to handle them
|
||||||
#
|
#
|
||||||
for my $onet ( mysplit $onets ) {
|
for my $onet ( mysplit $onets ) {
|
||||||
|
my $cond = conditional_rule( $chainref, $onet );
|
||||||
|
|
||||||
$onet = match_orig_dest $onet;
|
$onet = match_orig_dest $onet;
|
||||||
|
|
||||||
for my $inet ( mysplit $inets ) {
|
for my $inet ( mysplit $inets ) {
|
||||||
my $source_match;
|
my $source_match;
|
||||||
|
|
||||||
|
my $cond = conditional_rule( $chainref, $inet );
|
||||||
|
|
||||||
$source_match = match_source_net( $inet, $restriction ) if have_capability( 'KLUDGEFREE' );
|
$source_match = match_source_net( $inet, $restriction ) if have_capability( 'KLUDGEFREE' );
|
||||||
|
|
||||||
for my $dnet ( mysplit $dnets ) {
|
for my $dnet ( mysplit $dnets ) {
|
||||||
@ -3874,6 +3951,8 @@ sub expand_rule( $$$$$$$$$$;$ )
|
|||||||
my $dest_match = match_dest_net( $dnet );
|
my $dest_match = match_dest_net( $dnet );
|
||||||
my $matches = join( '', $rule, $source_match, $dest_match, $onet );
|
my $matches = join( '', $rule, $source_match, $dest_match, $onet );
|
||||||
|
|
||||||
|
my $cond = conditional_rule( $chainref, $dnet );
|
||||||
|
|
||||||
if ( $loglevel eq '' ) {
|
if ( $loglevel eq '' ) {
|
||||||
#
|
#
|
||||||
# No logging -- add the target rule with matches to the rule chain
|
# No logging -- add the target rule with matches to the rule chain
|
||||||
@ -3916,8 +3995,14 @@ sub expand_rule( $$$$$$$$$$;$ )
|
|||||||
$matches,
|
$matches,
|
||||||
1 );
|
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 @ISA = qw(Exporter);
|
||||||
our @EXPORT = qw( ALLIPv4
|
our @EXPORT = qw( ALLIPv4
|
||||||
ALLIPv6
|
ALLIPv6
|
||||||
|
NILIPv4
|
||||||
|
NILIPv6
|
||||||
IPv4_MULTICAST
|
IPv4_MULTICAST
|
||||||
IPv6_MULTICAST
|
IPv6_MULTICAST
|
||||||
IPv6_LINKLOCAL
|
IPv6_LINKLOCAL
|
||||||
@ -44,6 +46,7 @@ our @EXPORT = qw( ALLIPv4
|
|||||||
IPv6_SITE_ALLNODES
|
IPv6_SITE_ALLNODES
|
||||||
IPv6_SITE_ALLRTRS
|
IPv6_SITE_ALLRTRS
|
||||||
ALLIP
|
ALLIP
|
||||||
|
NILIP
|
||||||
ALL
|
ALL
|
||||||
TCP
|
TCP
|
||||||
UDP
|
UDP
|
||||||
@ -63,6 +66,9 @@ our @EXPORT = qw( ALLIPv4
|
|||||||
allipv4
|
allipv4
|
||||||
allipv6
|
allipv6
|
||||||
allip
|
allip
|
||||||
|
nilipv4
|
||||||
|
nilipv6
|
||||||
|
nilip
|
||||||
rfc1918_networks
|
rfc1918_networks
|
||||||
resolve_proto
|
resolve_proto
|
||||||
proto_name
|
proto_name
|
||||||
@ -73,7 +79,7 @@ our @EXPORT = qw( ALLIPv4
|
|||||||
validate_icmp6
|
validate_icmp6
|
||||||
);
|
);
|
||||||
our @EXPORT_OK = qw( );
|
our @EXPORT_OK = qw( );
|
||||||
our $VERSION = '4.4_14';
|
our $VERSION = '4.4_17';
|
||||||
|
|
||||||
#
|
#
|
||||||
# Some IPv4/6 useful stuff
|
# Some IPv4/6 useful stuff
|
||||||
@ -82,6 +88,10 @@ our @allipv4 = ( '0.0.0.0/0' );
|
|||||||
our @allipv6 = ( '::/0' );
|
our @allipv6 = ( '::/0' );
|
||||||
our $allip;
|
our $allip;
|
||||||
our @allip;
|
our @allip;
|
||||||
|
our @nilipv4 = ( '0.0.0.0' );
|
||||||
|
our @nilipv6 = ( '::' );
|
||||||
|
our $nilip;
|
||||||
|
our @nilip;
|
||||||
our $valid_address;
|
our $valid_address;
|
||||||
our $validate_address;
|
our $validate_address;
|
||||||
our $validate_net;
|
our $validate_net;
|
||||||
@ -91,6 +101,8 @@ our $family;
|
|||||||
|
|
||||||
use constant { ALLIPv4 => '0.0.0.0/0' ,
|
use constant { ALLIPv4 => '0.0.0.0/0' ,
|
||||||
ALLIPv6 => '::/0' ,
|
ALLIPv6 => '::/0' ,
|
||||||
|
NILIPv4 => '0.0.0.0' ,
|
||||||
|
NILIPv6 => '::' ,
|
||||||
IPv4_MULTICAST => '224.0.0.0/4' ,
|
IPv4_MULTICAST => '224.0.0.0/4' ,
|
||||||
IPv6_MULTICAST => 'ff00::/8' ,
|
IPv6_MULTICAST => 'ff00::/8' ,
|
||||||
IPv6_LINKLOCAL => 'fe80::/10' ,
|
IPv6_LINKLOCAL => 'fe80::/10' ,
|
||||||
@ -280,6 +292,14 @@ sub allipv6() {
|
|||||||
@allipv6;
|
@allipv6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub nilipv4() {
|
||||||
|
@nilipv4;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub nilipv6() {
|
||||||
|
@nilipv6;
|
||||||
|
}
|
||||||
|
|
||||||
sub rfc1918_networks() {
|
sub rfc1918_networks() {
|
||||||
@rfc1918_networks
|
@rfc1918_networks
|
||||||
}
|
}
|
||||||
@ -674,6 +694,14 @@ sub allip() {
|
|||||||
@allip;
|
@allip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub NILIP() {
|
||||||
|
$nilip;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub nilip() {
|
||||||
|
@nilip;
|
||||||
|
}
|
||||||
|
|
||||||
sub valid_address ( $ ) {
|
sub valid_address ( $ ) {
|
||||||
$valid_address->(@_);
|
$valid_address->(@_);
|
||||||
}
|
}
|
||||||
@ -710,6 +738,8 @@ sub initialize( $ ) {
|
|||||||
if ( $family == F_IPV4 ) {
|
if ( $family == F_IPV4 ) {
|
||||||
$allip = ALLIPv4;
|
$allip = ALLIPv4;
|
||||||
@allip = @allipv4;
|
@allip = @allipv4;
|
||||||
|
$nilip = NILIPv4;
|
||||||
|
@nilip = @nilipv4;
|
||||||
$valid_address = \&valid_4address;
|
$valid_address = \&valid_4address;
|
||||||
$validate_address = \&validate_4address;
|
$validate_address = \&validate_4address;
|
||||||
$validate_net = \&validate_4net;
|
$validate_net = \&validate_4net;
|
||||||
@ -718,6 +748,8 @@ sub initialize( $ ) {
|
|||||||
} else {
|
} else {
|
||||||
$allip = ALLIPv6;
|
$allip = ALLIPv6;
|
||||||
@allip = @allipv6;
|
@allip = @allipv6;
|
||||||
|
$nilip = NILIPv6;
|
||||||
|
@nilip = @nilipv6;
|
||||||
$valid_address = \&valid_6address;
|
$valid_address = \&valid_6address;
|
||||||
$validate_address = \&validate_6address;
|
$validate_address = \&validate_6address;
|
||||||
$validate_net = \&validate_6net;
|
$validate_net = \&validate_6net;
|
||||||
|
@ -155,6 +155,7 @@ sub process_one_masq( )
|
|||||||
my $exceptionrule = '';
|
my $exceptionrule = '';
|
||||||
my $randomize = '';
|
my $randomize = '';
|
||||||
my $persistent = '';
|
my $persistent = '';
|
||||||
|
my $conditional = 0;
|
||||||
#
|
#
|
||||||
# Parse the ADDRESSES column
|
# Parse the ADDRESSES column
|
||||||
#
|
#
|
||||||
@ -188,7 +189,11 @@ sub process_one_masq( )
|
|||||||
for my $addr ( split_list $addresses , 'address' ) {
|
for my $addr ( split_list $addresses , 'address' ) {
|
||||||
if ( $addr =~ /^&(.+)$/ ) {
|
if ( $addr =~ /^&(.+)$/ ) {
|
||||||
$target = 'SNAT ';
|
$target = 'SNAT ';
|
||||||
|
if ( $conditional = conditional_rule( $chainref, $addr ) ) {
|
||||||
|
$addrlist .= '--to-source ' . get_interface_address $1;
|
||||||
|
} else {
|
||||||
$addrlist .= '--to-source ' . record_runtime_address $1;
|
$addrlist .= '--to-source ' . record_runtime_address $1;
|
||||||
|
}
|
||||||
} elsif ( $addr =~ /^.*\..*\..*\./ ) {
|
} elsif ( $addr =~ /^.*\..*\..*\./ ) {
|
||||||
$target = 'SNAT ';
|
$target = 'SNAT ';
|
||||||
my ($ipaddr, $rest) = split ':', $addr;
|
my ($ipaddr, $rest) = split ':', $addr;
|
||||||
@ -232,10 +237,7 @@ sub process_one_masq( )
|
|||||||
'' ,
|
'' ,
|
||||||
$exceptionrule );
|
$exceptionrule );
|
||||||
|
|
||||||
if ( $detectaddress ) {
|
conditional_rule_end( $chainref ) if $detectaddress || $conditional;
|
||||||
decr_cmd_level( $chainref );
|
|
||||||
add_commands( $chainref , 'fi' );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $add_snat_aliases ) {
|
if ( $add_snat_aliases ) {
|
||||||
my ( $interface, $alias , $remainder ) = split( /:/, $fullinterface, 3 );
|
my ( $interface, $alias , $remainder ) = split( /:/, $fullinterface, 3 );
|
||||||
|
@ -109,9 +109,8 @@ Beta 2
|
|||||||
file.
|
file.
|
||||||
|
|
||||||
For optional interfaces, if the interface is not usable at the time
|
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
|
that the firewall starts, the resulting Netfilter rule(s)
|
||||||
:: in IPv6) will be substituted, resulting in no packets matching
|
containing the interface address are not added.
|
||||||
the rule.
|
|
||||||
|
|
||||||
Beta 1
|
Beta 1
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user