From 131c1f432bfa37a4f8ff05d9fbaa2589d2449d01 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Thu, 4 Jul 2013 14:07:09 -0700 Subject: [PATCH 1/3] Add iverify_source_interface() Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 39 ++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 4e6379312..b445407df 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -6944,6 +6944,45 @@ sub verify_source_interface( $$$$ ) { $rule; } +sub iverify_source_interface( $$$$ ) { + my ( $iiface, $restriction, $table, $chainref ) = @_; + + my @rule; + + fatal_error "Unknown Interface ($iiface)" unless known_interface $iiface; + + if ( $restriction & POSTROUTE_RESTRICT ) { + # + # An interface in the SOURCE column of a masq file + # + fatal_error "Bridge ports may not appear in the SOURCE column of this file" if port_to_bridge( $iiface ); + fatal_error "A wildcard interface ( $iiface) is not allowed in this context" if $iiface =~ /\+$/; + + if ( $table eq 'nat' ) { + warning_message qq(Using an interface as the masq SOURCE requires the interface to be up and configured when $Product starts/restarts) unless $idiotcount++; + } else { + warning_message qq(Using an interface as the SOURCE in a T: rule requires the interface to be up and configured when $Product starts/restarts) unless $idiotcount1++; + } + + push_command $chainref, join( '', 'for source in ', get_interface_nets( $iiface) , '; do' ), 'done'; + + push @rule, ( s => '$source' ); + } else { + if ( $restriction & OUTPUT_RESTRICT ) { + if ( $chainref->{accounting} ) { + fatal_error "Source Interface ($iiface) not allowed in the $chainref->{name} chain"; + } else { + fatal_error "Source Interface ($iiface) not allowed when the SOURCE is the firewall"; + } + } + + $chainref->{restricted} |= $restriction; + push @rule, imatch_source_dev( $iiface ); + } + + @rule; +} + # # Splits an interface:address pair. Updates that passed rule and returns ($rule, $interface, $address ) # From 512163445727cf4a19ac26fe04234b12c7ccacec Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Thu, 4 Jul 2013 14:37:24 -0700 Subject: [PATCH 2/3] Add ihandle_original_dest() Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index b445407df..8bb92a508 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -7104,8 +7104,8 @@ sub verify_dest_interface( $$$$ ) { # # Handles the original destination. Updates the passed rule and returns ( $networks, $exclusion, $rule ) # -sub handle_original_dest( $$$ ) { - my ( $origdest, $chainref, $rule ) = @_; +sub ihandle_original_dest( $$;@ ) { + my ( $origdest, $chainref, @rule ) = @_; my ( $onets, $oexcl ); if ( $origdest eq '-' || ! have_capability( 'CONNTRACK_MATCH' ) ) { @@ -7129,14 +7129,14 @@ sub handle_original_dest( $$$ ) { push_command( $chainref , 'if [ $address != 0.0.0.0 ]; then' , 'fi' ) if $optional; - $rule .= '-m conntrack --ctorigdst $address '; + push @rule, ( conntrack => '--ctoregdst $address' ); } else { my $interface = $interfaces[0]; my $variable = get_interface_address( $interface ); push_command( $chainref , "if [ $variable != 0.0.0.0 ]; then" , 'fi' ) if interface_is_optional( $interface ); - $rule .= "-m conntrack --ctorigdst $variable "; + push @rule, ( conntrack => '--ctorigdst $variable' ); } $onets = $oexcl = ''; @@ -7157,13 +7157,13 @@ sub handle_original_dest( $$$ ) { unless ( $onets ) { my @oexcl = split_host_list( $oexcl, $config{DEFER_DNS_RESOLUTION} ); if ( @oexcl == 1 ) { - $rule .= match_orig_dest( "!$oexcl" ); + push @rule, imatch_orig_dest( "!$oexcl" ); $oexcl = ''; } } } - ( $onets, $oexcl, $rule ); + ( $onets, $oexcl, @rule ); } # From cd83d7727c9bc4b20ec662e0d959b9360165e5ef Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Thu, 4 Jul 2013 14:51:06 -0700 Subject: [PATCH 3/3] Restore handle_original_dest(). Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 62 ++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 8bb92a508..6c802834b 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -7104,6 +7104,68 @@ sub verify_dest_interface( $$$$ ) { # # Handles the original destination. Updates the passed rule and returns ( $networks, $exclusion, $rule ) # +sub handle_original_dest( $$$ ) { + my ( $origdest, $chainref, $rule ) = @_; + my ( $onets, $oexcl ); + + if ( $origdest eq '-' || ! have_capability( 'CONNTRACK_MATCH' ) ) { + $onets = $oexcl = ''; + } elsif ( $origdest =~ /^detect:(.*)$/ ) { + # + # Either the filter part of a DNAT rule or 'detect' was given in the ORIG DEST column + # + my @interfaces = split /\s+/, $1; + + if ( @interfaces > 1 ) { + my $list = ""; + my $optional; + + for my $interface ( @interfaces ) { + $optional++ if interface_is_optional $interface; + $list = join( ' ', $list , get_interface_address( $interface ) ); + } + + push_command( $chainref , "for address in $list; do" , 'done' ); + + push_command( $chainref , 'if [ $address != 0.0.0.0 ]; then' , 'fi' ) if $optional; + + $rule .= '-m conntrack --ctorigdst $address '; + } else { + my $interface = $interfaces[0]; + my $variable = get_interface_address( $interface ); + + push_command( $chainref , "if [ $variable != 0.0.0.0 ]; then" , 'fi' ) if interface_is_optional( $interface ); + + $rule .= "-m conntrack --ctorigdst $variable "; + } + + $onets = $oexcl = ''; + } else { + fatal_error "Invalid ORIGINAL DEST" if $origdest =~ /^([^!]+)?,!([^!]+)$/ || $origdest =~ /.*!.*!/; + + if ( $origdest =~ /^([^!]+)?!([^!]+)$/ ) { + # + # Exclusion + # + $onets = $1; + $oexcl = $2; + } else { + $oexcl = ''; + $onets = $origdest; + } + + unless ( $onets ) { + my @oexcl = split_host_list( $oexcl, $config{DEFER_DNS_RESOLUTION} ); + if ( @oexcl == 1 ) { + $rule .= match_orig_dest( "!$oexcl" ); + $oexcl = ''; + } + } + } + + ( $onets, $oexcl, $rule ); +} + sub ihandle_original_dest( $$;@ ) { my ( $origdest, $chainref, @rule ) = @_; my ( $onets, $oexcl );