mirror of
https://gitlab.com/shorewall/code.git
synced 2024-11-23 08:03:11 +01:00
More IPv6 Infrastructure
git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@8856 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
parent
618d8a440a
commit
2db8cc0207
@ -37,6 +37,7 @@ our @ISA = qw(Exporter);
|
||||
our @EXPORT = qw(
|
||||
add_rule
|
||||
add_jump
|
||||
add_6jump
|
||||
insert_rule
|
||||
new_chain
|
||||
new_manual_chain
|
||||
@ -90,12 +91,15 @@ our %EXPORT_TAGS = (
|
||||
forward_chain
|
||||
zone_forward_chain
|
||||
use_forward_chain
|
||||
use_forward_6chain
|
||||
input_chain
|
||||
zone_input_chain
|
||||
use_input_chain
|
||||
use_input_6chain
|
||||
output_chain
|
||||
zone_output_chain
|
||||
use_output_chain
|
||||
use_output_6chain
|
||||
masq_chain
|
||||
syn_flood_chain
|
||||
mac_chain
|
||||
@ -630,6 +634,33 @@ sub add_jump( $$;$ ) {
|
||||
add_rule ($fromref, join( '', $predicate, "-j $to" ) );
|
||||
}
|
||||
|
||||
sub add_6jump( $$;$ ) {
|
||||
my ( $fromref, $to, $predicate ) = @_;
|
||||
|
||||
$predicate |= '';
|
||||
|
||||
my $toref;
|
||||
#
|
||||
# The second argument may be a scalar (chain name or builtin target) or a chain reference
|
||||
#
|
||||
if ( reftype $to ) {
|
||||
$toref = $to;
|
||||
$to = $toref->{name};
|
||||
} else {
|
||||
#
|
||||
# Ensure that we have the chain unless it is a builtin like 'ACCEPT'
|
||||
#
|
||||
$toref = ensure_6chain( $fromref->{table} , $to ) unless ( $targets6{$to} || 0 ) & STANDARD;
|
||||
}
|
||||
|
||||
#
|
||||
# If the destination is a chain, mark it referenced
|
||||
#
|
||||
$toref->{referenced} = 1 if $toref;
|
||||
|
||||
add_rule ($fromref, join( '', $predicate, "-j $to" ) );
|
||||
}
|
||||
|
||||
#
|
||||
# Insert a rule into a chain. Arguments are:
|
||||
#
|
||||
@ -718,6 +749,15 @@ sub use_forward_chain($) {
|
||||
$interfaceref->{nets} > 1;
|
||||
}
|
||||
|
||||
sub use_forward_6chain($) {
|
||||
my $interface = $_[0];
|
||||
my $interfaceref = find_6interface($interface);
|
||||
#
|
||||
# We must use the interfaces's chain if the interface is associated with multiple zone nets
|
||||
#
|
||||
$interfaceref->{nets} > 1;
|
||||
}
|
||||
|
||||
#
|
||||
# Input Chain for an interface
|
||||
#
|
||||
@ -762,6 +802,32 @@ sub use_input_chain($) {
|
||||
! $chainref->{referenced};
|
||||
}
|
||||
|
||||
sub use_input_6chain($) {
|
||||
my $interface = $_[0];
|
||||
my $interfaceref = find_6interface($interface);
|
||||
my $nets = $interfaceref->{nets};
|
||||
#
|
||||
# We must use the interfaces's chain if the interface is associated with multiple zone nets
|
||||
#
|
||||
return 1 if $nets > 1;
|
||||
#
|
||||
# Don't need it if it isn't associated with any zone
|
||||
#
|
||||
return 0 unless $nets;
|
||||
#
|
||||
# Interface associated with a single zone -- use the zone's input chain if it has one
|
||||
#
|
||||
my $chainref = $filter6_table->{zone_input_chain $interfaceref->{zone}};
|
||||
|
||||
return 0 if $chainref;
|
||||
#
|
||||
# Use the '<zone>2fw' chain if it is referenced.
|
||||
#
|
||||
$chainref = $filter6_table->{join( '' , $interfaceref->{zone} , '2' , firewall_zone )};
|
||||
|
||||
! $chainref->{referenced};
|
||||
}
|
||||
|
||||
#
|
||||
# Output Chain for an interface
|
||||
#
|
||||
@ -806,6 +872,32 @@ sub use_output_chain($) {
|
||||
! $chainref->{referenced};
|
||||
}
|
||||
|
||||
sub use_output_6chain($) {
|
||||
my $interface = $_[0];
|
||||
my $interfaceref = find_6interface($interface);
|
||||
my $nets = $interfaceref->{nets};
|
||||
#
|
||||
# We must use the interfaces's chain if the interface is associated with multiple zone nets
|
||||
#
|
||||
return 1 if $nets > 1;
|
||||
#
|
||||
# Don't need it if it isn't associated with any zone
|
||||
#
|
||||
return 0 unless $nets;
|
||||
#
|
||||
# Interface associated with a single zone -- use the zone's output chain if it has one
|
||||
#
|
||||
my $chainref = $filter6_table->{zone_output_chain $interfaceref->{zone}};
|
||||
|
||||
return 0 if $chainref;
|
||||
#
|
||||
# Use the 'fw2<zone>' chain if it is referenced.
|
||||
#
|
||||
$chainref = $filter6_table->{join( '', firewall_zone , '2', $interfaceref->{zone} )};
|
||||
|
||||
! $chainref->{referenced};
|
||||
}
|
||||
|
||||
#
|
||||
# Masquerade Chain for an interface
|
||||
#
|
||||
@ -2767,35 +2859,6 @@ sub create_chainlist_reload($) {
|
||||
emit "}\n";
|
||||
}
|
||||
|
||||
#
|
||||
# Returns true if we're to use the interface's output chain
|
||||
#
|
||||
sub use_output_6chain($) {
|
||||
my $interface = $_[0];
|
||||
my $interfaceref = find_interface6($interface);
|
||||
my $nets = $interfaceref->{nets};
|
||||
#
|
||||
# We must use the interfaces's chain if the interface is associated with multiple zone nets
|
||||
#
|
||||
return 1 if $nets > 1;
|
||||
#
|
||||
# Don't need it if it isn't associated with any zone
|
||||
#
|
||||
return 0 unless $nets;
|
||||
#
|
||||
# Interface associated with a single zone -- use the zone's output chain if it has one
|
||||
#
|
||||
my $chainref = $filter6_table->{zone_output_chain $interfaceref->{zone4}};
|
||||
|
||||
return 0 if $chainref;
|
||||
#
|
||||
# Use the 'fw2<zone>' chain if it is referenced.
|
||||
#
|
||||
$chainref = $filter6_table->{join( '', firewall_zone , '2', $interfaceref->{zone} )};
|
||||
|
||||
! $chainref->{referenced};
|
||||
}
|
||||
|
||||
#
|
||||
# Create a new 6chain and return a reference to it.
|
||||
#
|
||||
|
@ -2041,7 +2041,7 @@ sub process_6rule ( $$$$$$$$$$$ ) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
my $destzone = (split( /:/, $dest, 2 ) )[0];
|
||||
my $destzone = (split( /;/, $dest, 2 ) )[0];
|
||||
$destzone = firewall_zone unless defined_zone( $destzone ); # We do this to allow 'REDIRECT all ...'; process_rule1 will catch the case where the dest zone is invalid
|
||||
if ( $intrazone || ( $zone ne $destzone ) ) {
|
||||
process_6rule1 $target, $zone, $dest , $proto, $ports, $sports, $ratelimit, $user, $mark, $connlimit, $time, 1;
|
||||
@ -2051,7 +2051,7 @@ sub process_6rule ( $$$$$$$$$$$ ) {
|
||||
}
|
||||
} elsif ( $dest eq 'all' ) {
|
||||
for my $zone ( all_6zones ) {
|
||||
my $sourcezone = ( split( /:/, $source, 2 ) )[0];
|
||||
my $sourcezone = ( split( /;/, $source, 2 ) )[0];
|
||||
if ( ( $includedstfw || ( zone_type( $zone ) ne 'firewall') ) && ( ( $sourcezone ne $zone ) || $intrazone) ) {
|
||||
process_6rule1 $target, $source, $zone , $proto, $ports, $sports, $ratelimit, $user, $mark, $connlimit, $time, 1;
|
||||
}
|
||||
@ -2109,6 +2109,57 @@ sub process_6rules() {
|
||||
$section = 'DONE';
|
||||
}
|
||||
|
||||
#
|
||||
# Helper functions for generate_matrix()
|
||||
#-----------------------------------------
|
||||
#
|
||||
# Return the target for rules from $zone to $zone1.
|
||||
#
|
||||
sub rules_target( $$ ) {
|
||||
my ( $zone, $zone1 ) = @_;
|
||||
my $chain = "${zone}2${zone1}";
|
||||
my $chainref = $filter_table->{$chain};
|
||||
|
||||
return $chain if $chainref && $chainref->{referenced};
|
||||
return 'ACCEPT' if $zone eq $zone1;
|
||||
|
||||
fatal_error "Internal Error in rules_target()" unless $chainref;
|
||||
|
||||
if ( $chainref->{policy} ne 'CONTINUE' ) {
|
||||
my $policyref = $filter_table->{$chainref->{policychain}};
|
||||
return $policyref->{name} if $policyref;
|
||||
fatal_error "No policy defined for zone $zone to zone $zone1";
|
||||
}
|
||||
|
||||
'';
|
||||
}
|
||||
|
||||
#
|
||||
# Insert the passed exclusions at the front of the passed chain.
|
||||
#
|
||||
sub insert_exclusions( $$ ) {
|
||||
my ( $chainref, $exclusionsref ) = @_;
|
||||
|
||||
my $num = 1;
|
||||
|
||||
for my $host ( @{$exclusionsref} ) {
|
||||
my ( $interface, $net ) = split /:/, $host;
|
||||
insert_rule $chainref , $num++, join( '', match_dest_dev $interface , match_dest_net( $net ), '-j RETURN' );
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Add the passed exclusions at the end of the passed chain.
|
||||
#
|
||||
sub add_exclusions ( $$ ) {
|
||||
my ( $chainref, $exclusionsref ) = @_;
|
||||
|
||||
for my $host ( @{$exclusionsref} ) {
|
||||
my ( $interface, $net ) = split /:/, $host;
|
||||
add_rule $chainref , join( '', match_dest_dev $interface, match_dest_net( $net ), '-j RETURN' );
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# To quote an old comment, "generate_matrix makes a sow's ear out of a silk purse".
|
||||
#
|
||||
@ -2118,76 +2169,7 @@ sub process_6rules() {
|
||||
# The function traverses the full "source-zone by destination-zone" matrix and generates the rules necessary to direct traffic through the right set of filter-table rules.
|
||||
#
|
||||
sub generate_matrix() {
|
||||
#
|
||||
# Helper functions for generate_matrix()
|
||||
#-----------------------------------------
|
||||
#
|
||||
# Return the target for rules from $zone to $zone1.
|
||||
#
|
||||
sub rules_target( $$ ) {
|
||||
my ( $zone, $zone1 ) = @_;
|
||||
my $chain = "${zone}2${zone1}";
|
||||
my $chainref = $filter_table->{$chain};
|
||||
|
||||
return $chain if $chainref && $chainref->{referenced};
|
||||
return 'ACCEPT' if $zone eq $zone1;
|
||||
|
||||
fatal_error "Internal Error in rules_target()" unless $chainref;
|
||||
|
||||
if ( $chainref->{policy} ne 'CONTINUE' ) {
|
||||
my $policyref = $filter_table->{$chainref->{policychain}};
|
||||
return $policyref->{name} if $policyref;
|
||||
fatal_error "No policy defined for zone $zone to zone $zone1";
|
||||
}
|
||||
|
||||
'';
|
||||
}
|
||||
|
||||
#
|
||||
# Add a jump to the passed chain ($chainref) to the dynamic zone chain for the passed zone.
|
||||
#
|
||||
sub create_zone_dyn_chain( $$ ) {
|
||||
my ( $zone , $chainref ) = @_;
|
||||
add_jump $chainref, zone_dynamic_chain $zone;
|
||||
}
|
||||
|
||||
#
|
||||
# Insert the passed exclusions at the front of the passed chain.
|
||||
#
|
||||
sub insert_exclusions( $$ ) {
|
||||
my ( $chainref, $exclusionsref ) = @_;
|
||||
|
||||
my $num = 1;
|
||||
|
||||
for my $host ( @{$exclusionsref} ) {
|
||||
my ( $interface, $net ) = split /:/, $host;
|
||||
insert_rule $chainref , $num++, join( '', match_dest_dev $interface , match_dest_net( $net ), '-j RETURN' );
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Add the passed exclusions at the end of the passed chain.
|
||||
#
|
||||
sub add_exclusions ( $$ ) {
|
||||
my ( $chainref, $exclusionsref ) = @_;
|
||||
|
||||
for my $host ( @{$exclusionsref} ) {
|
||||
my ( $interface, $net ) = split /:/, $host;
|
||||
add_rule $chainref , join( '', match_dest_dev $interface, match_dest_net( $net ), '-j RETURN' );
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Set a breakpoint in this function if you want to step through generate_matrix().
|
||||
#
|
||||
sub start_matrix() {
|
||||
progress_message2 'Generating Rule Matrix...';
|
||||
}
|
||||
|
||||
#
|
||||
# G e n e r a t e _ M a t r i x ( ) S t a r t s H e r e
|
||||
#
|
||||
start_matrix;
|
||||
progress_message2 'Generating Rule Matrix...';
|
||||
|
||||
my $exclusion_seq = 1;
|
||||
my %chain_exclusions;
|
||||
@ -2646,6 +2628,419 @@ sub generate_matrix() {
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Helper functions for generate_6matrix()
|
||||
#-----------------------------------------
|
||||
#
|
||||
# Return the target for rules from $zone to $zone1.
|
||||
#
|
||||
sub rules6_target( $$ ) {
|
||||
my ( $zone, $zone1 ) = @_;
|
||||
my $chain = "${zone}2${zone1}";
|
||||
my $chainref = $filter6_table->{$chain};
|
||||
|
||||
return $chain if $chainref && $chainref->{referenced};
|
||||
return 'ACCEPT' if $zone eq $zone1;
|
||||
|
||||
fatal_error "Internal Error in rules6_target()" unless $chainref;
|
||||
|
||||
if ( $chainref->{policy} ne 'CONTINUE' ) {
|
||||
my $policyref = $filter6_table->{$chainref->{policychain}};
|
||||
return $policyref->{name} if $policyref;
|
||||
fatal_error "No policy defined for zone $zone to zone $zone1";
|
||||
}
|
||||
|
||||
'';
|
||||
}
|
||||
|
||||
sub generate_6matrix() {
|
||||
progress_message2 'Generating IPv6 Rule Matrix...';
|
||||
|
||||
my $exclusion_seq = 1;
|
||||
my %chain_exclusions;
|
||||
my %policy_exclusions;
|
||||
my @interfaces = ( all_6interfaces );
|
||||
my $fw = firewall_zone;
|
||||
my @zones = non_firewall_6zones;
|
||||
|
||||
#
|
||||
# Special processing for complex configurations
|
||||
#
|
||||
for my $zone ( @zones ) {
|
||||
my $zoneref = find_zone( $zone );
|
||||
|
||||
next if @zones <= 2 && ! $zoneref->{options}{complex};
|
||||
|
||||
my $exclusions = $zoneref->{exclusions};
|
||||
my $frwd_ref = new_standard_chain zone_forward_chain( $zone );
|
||||
|
||||
if ( @$exclusions ) {
|
||||
my $in_ref = new_standard_chain zone_input_chain $zone;
|
||||
my $out_ref = new_standard_chain zone_output_chain $zone;
|
||||
|
||||
add_rule ensure_filter_chain( "${zone}2${zone}", 1 ) , '-j ACCEPT' if rules_target( $zone, $zone ) eq 'ACCEPT';
|
||||
|
||||
for my $host ( @$exclusions ) {
|
||||
my ( $interface, $net ) = split /:/, $host;
|
||||
my $rule = match_source_dev( $interface ) . match_source_net( $net ) . '-j RETURN';
|
||||
add_rule $frwd_ref , $rule;
|
||||
add_rule $in_ref , $rule;
|
||||
add_rule $out_ref , match_dest_dev( $interface ) . match_dest_net( $net ) . '-j RETURN';
|
||||
}
|
||||
}
|
||||
|
||||
if ( $capabilities{POLICY_MATCH} ) {
|
||||
my $type = $zoneref->{type};
|
||||
my $source_ref = ( $zoneref->{hosts}{ipsec4} ) || {};
|
||||
|
||||
for my $interface ( sort { interface_number( $a ) <=> interface_number( $b ) } keys %$source_ref ) {
|
||||
my $sourcechainref;
|
||||
my $interfacematch = '';
|
||||
|
||||
if ( use_forward_chain( $interface ) ) {
|
||||
$sourcechainref = $filter_table->{forward_chain $interface};
|
||||
} else {
|
||||
$sourcechainref = $filter_table->{FORWARD};
|
||||
$interfacematch = match_source_dev $interface;
|
||||
move_rules( $filter_table->{forward_chain $interface} , $frwd_ref );
|
||||
}
|
||||
|
||||
my $arrayref = $source_ref->{$interface};
|
||||
|
||||
for my $hostref ( @{$arrayref} ) {
|
||||
my $ipsec_match = match_ipsec_in $zone , $hostref;
|
||||
for my $net ( @{$hostref->{hosts}} ) {
|
||||
add_jump6(
|
||||
$sourcechainref,
|
||||
$frwd_ref,
|
||||
join( '', $interfacematch , match_source_net( $net ), $ipsec_match )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#
|
||||
# Main source-zone matrix-generation loop
|
||||
#
|
||||
for my $zone ( @zones ) {
|
||||
my $zoneref = find_6zone( $zone );
|
||||
my $source_hosts_ref = $zoneref->{hosts};
|
||||
my $chain1 = rules6_target firewall_zone , $zone;
|
||||
my $chain2 = rules6_target $zone, firewall_zone;
|
||||
my $chain3 = rules6_target $zone, $zone;
|
||||
my $complex = $zoneref->{options}{complex} || 0;
|
||||
my $type = $zoneref->{type};
|
||||
my $exclusions = $zoneref->{exclusions};
|
||||
my $frwd_ref = $filter6_table->{zone_forward_chain $zone};
|
||||
my $chain = 0;
|
||||
#
|
||||
# Take care of INPUT and OUTPUT jumps
|
||||
#
|
||||
for my $typeref ( values %$source_hosts_ref ) {
|
||||
for my $interface ( sort { interface_number( $a ) <=> interface_number( $b ) } keys %$typeref ) {
|
||||
my $arrayref = $typeref->{$interface};
|
||||
for my $hostref ( @$arrayref ) {
|
||||
my $ipsec_in_match = match_ipsec_in $zone , $hostref;
|
||||
my $ipsec_out_match = match_ipsec_out $zone , $hostref;
|
||||
for my $net ( @{$hostref->{hosts}} ) {
|
||||
my $dest = match_dest_6net $net;
|
||||
|
||||
if ( $chain1 ) {
|
||||
my $nextchain;
|
||||
my $outputref;
|
||||
my $interfacematch = '';
|
||||
|
||||
if ( use_output_6chain $interface ) {
|
||||
$outputref = $filter6_table->{output_chain $interface};
|
||||
} else {
|
||||
$outputref = $filter6_table->{OUTPUT};
|
||||
$interfacematch = match_dest_6dev $interface;
|
||||
}
|
||||
|
||||
if ( @$exclusions ) {
|
||||
my $output = zone_output_chain $zone;
|
||||
add_6jump $outputref , $output, join( '', $interfacematch, $dest, $ipsec_out_match );
|
||||
add_6jump $filter_table->{$output} , $chain1;
|
||||
$nextchain = $output;
|
||||
} else {
|
||||
add_6jump $outputref , $chain1, join( '', $interfacematch, $dest, $ipsec_out_match );
|
||||
$nextchain = $chain1;
|
||||
}
|
||||
|
||||
add_6jump( $outputref , $nextchain, join('', $interfacematch, '-d 255.255.255.255 ' , $ipsec_out_match ) )
|
||||
if $hostref->{options}{broadcast};
|
||||
|
||||
move_rules( $filter6_table->{output_chain $interface} , $filter_table->{$nextchain} ) unless use_output_6chain $interface;
|
||||
}
|
||||
|
||||
next if $hostref->{options}{destonly};
|
||||
|
||||
clearrule;
|
||||
|
||||
my $source = match_source_net $net;
|
||||
my $inputchainref;
|
||||
my $interfacematch = '';
|
||||
|
||||
if ( use_input_6chain $interface ) {
|
||||
$inputchainref = $filter6_table->{input_chain $interface};
|
||||
} else {
|
||||
$inputchainref = $filter6_table->{INPUT};
|
||||
$interfacematch = match_source_6dev $interface;
|
||||
}
|
||||
|
||||
if ( $chain2 ) {
|
||||
my $nextchain;
|
||||
|
||||
if ( @$exclusions ) {
|
||||
my $input = zone_input_chain $zone;
|
||||
add_6jump $inputchainref, $input, join( '', $interfacematch, $source, $ipsec_in_match );
|
||||
add_6jump $filter6_table->{ $input } , $chain2;
|
||||
$nextchain = $input;
|
||||
} else {
|
||||
add_6jump $inputchainref, $chain2, join( '', $interfacematch, $source, $ipsec_in_match );
|
||||
$nextchain = $chain2;
|
||||
}
|
||||
|
||||
move_rules( $filter6_table->{input_chain $interface} , $filter_table->{$nextchain} ) unless use_input_6chain $interface;
|
||||
}
|
||||
|
||||
if ( $frwd_ref && $hostref->{ipsec} ne 'ipsec' ) {
|
||||
if ( use_forward_6chain $interface ) {
|
||||
add_6jump $filter6_table->{forward_chain $interface} , $frwd_ref, join( '', $source, $ipsec_in_match );
|
||||
} else {
|
||||
add_6jump $filter6_table->{FORWARD} , $frwd_ref, join( '', match_source_6dev( $interface ) , $source, $ipsec_in_match );
|
||||
move_rules ( $filter6_table->{forward_chain $interface} , $frwd_ref );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# F O R W A R D I N G
|
||||
#
|
||||
my @dest_zones;
|
||||
my $last_chain = '';
|
||||
|
||||
if ( $config{OPTIMIZE} > 0 ) {
|
||||
my @temp_zones;
|
||||
|
||||
ZONE1:
|
||||
for my $zone1 ( @zones ) {
|
||||
my $zone1ref = find_6zone( $zone1 );
|
||||
my $policy = $filter6_table->{"${zone}2${zone1}"}->{policy};
|
||||
|
||||
next if $policy eq 'NONE';
|
||||
|
||||
my $chain = rules6_target $zone, $zone1;
|
||||
|
||||
next unless $chain;
|
||||
|
||||
if ( $zone eq $zone1 ) {
|
||||
next if ( scalar ( keys( %{ $zoneref->{interfaces}} ) ) < 2 ) && ! ( $zoneref->{options}{in_out}{routeback} || @$exclusions );
|
||||
}
|
||||
|
||||
if ( $zone1ref->{type} eq 'bport6' ) {
|
||||
next unless $zoneref->{bridge} eq $zone1ref->{bridge};
|
||||
}
|
||||
|
||||
if ( $chain =~ /2all$/ ) {
|
||||
if ( $chain ne $last_chain ) {
|
||||
$last_chain = $chain;
|
||||
push @dest_zones, @temp_zones;
|
||||
@temp_zones = ( $zone1 );
|
||||
} elsif ( $policy eq 'ACCEPT' ) {
|
||||
push @temp_zones , $zone1;
|
||||
} else {
|
||||
$last_chain = $chain;
|
||||
@temp_zones = ( $zone1 );
|
||||
}
|
||||
} else {
|
||||
push @dest_zones, @temp_zones, $zone1;
|
||||
@temp_zones = ();
|
||||
$last_chain = '';
|
||||
}
|
||||
}
|
||||
|
||||
if ( $last_chain && @temp_zones == 1 ) {
|
||||
push @dest_zones, @temp_zones;
|
||||
$last_chain = '';
|
||||
}
|
||||
} else {
|
||||
@dest_zones = @zones ;
|
||||
}
|
||||
#
|
||||
# Here it is -- THE BIG UGLY!!!!!!!!!!!!
|
||||
#
|
||||
# We now loop through the destination zones creating jumps to the rules chain for each source/dest combination.
|
||||
# @dest_zones is the list of destination zones that we need to handle from this source zone
|
||||
#
|
||||
ZONE1:
|
||||
for my $zone1 ( @dest_zones ) {
|
||||
my $zone1ref = find_6zone( $zone1 );
|
||||
my $policy = $filter6_table->{"${zone}2${zone1}"}->{policy};
|
||||
|
||||
next if $policy eq 'NONE';
|
||||
|
||||
my $chain = rules6_target $zone, $zone1;
|
||||
|
||||
next unless $chain; # CONTINUE policy with no rules
|
||||
|
||||
my $num_ifaces = 0;
|
||||
|
||||
if ( $zone eq $zone1 ) {
|
||||
next ZONE1 if ( $num_ifaces = scalar( keys ( %{$zoneref->{interfaces}} ) ) ) < 2 && ! ( $zoneref->{options}{in_out}{routeback} || @$exclusions );
|
||||
}
|
||||
|
||||
if ( $zone1ref->{type} eq 'bport6' ) {
|
||||
next ZONE1 unless $zoneref->{bridge} eq $zone1ref->{bridge};
|
||||
}
|
||||
|
||||
my $chainref = $filter_table->{$chain};
|
||||
my $exclusions1 = $zone1ref->{exclusions};
|
||||
|
||||
my $dest_hosts_ref = $zone1ref->{hosts};
|
||||
|
||||
if ( @$exclusions1 ) {
|
||||
if ( $chain eq "all2$zone1" ) {
|
||||
unless ( $chain_exclusions{$chain} ) {
|
||||
$chain_exclusions{$chain} = 1;
|
||||
insert_exclusions $chainref , $exclusions1;
|
||||
}
|
||||
} elsif ( $chain =~ /2all$/ ) {
|
||||
my $chain1 = $policy_exclusions{"${chain}_${zone1}"};
|
||||
|
||||
unless ( $chain1 ) {
|
||||
$chain1 = newexclusionchain;
|
||||
$policy_exclusions{"${chain}_${zone1}"} = $chain1;
|
||||
my $chain1ref = ensure_filter_chain $chain1, 0;
|
||||
add_exclusions $chain1ref, $exclusions1;
|
||||
add_6jump $chain1ref, $chain;
|
||||
}
|
||||
|
||||
$chain = $chain1;
|
||||
} else {
|
||||
fatal_error "Fatal Error in generate_matrix()" if $chain eq 'ACCEPT';
|
||||
insert_exclusions $chainref , $exclusions1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $frwd_ref ) {
|
||||
for my $typeref ( values %$dest_hosts_ref ) {
|
||||
for my $interface ( sort { interface_number( $a ) <=> interface_number( $b ) } keys %$typeref ) {
|
||||
my $arrayref = $typeref->{$interface};
|
||||
for my $hostref ( @$arrayref ) {
|
||||
next if $hostref->{options}{sourceonly};
|
||||
if ( $zone ne $zone1 || $num_ifaces > 1 || $hostref->{options}{routeback} ) {
|
||||
my $ipsec_out_match = match_ipsec_out $zone1 , $hostref;
|
||||
for my $net ( @{$hostref->{hosts}} ) {
|
||||
add_6jump $frwd_ref, $chain, join( '', match_dest_6dev( $interface) , match_dest_6net($net), $ipsec_out_match );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for my $typeref ( values %$source_hosts_ref ) {
|
||||
for my $interface ( keys %$typeref ) {
|
||||
my $arrayref = $typeref->{$interface};
|
||||
my $chain3ref;
|
||||
my $match_source_dev = '';
|
||||
|
||||
if ( use_forward_chain $interface ) {
|
||||
$chain3ref = $filter6_table->{forward_chain $interface};
|
||||
} else {
|
||||
$chain3ref = $filter_table->{FORWARD};
|
||||
$match_source_dev = match_source_6dev $interface;
|
||||
}
|
||||
|
||||
for my $hostref ( @$arrayref ) {
|
||||
next if $hostref->{options}{destonly};
|
||||
for my $net ( @{$hostref->{hosts}} ) {
|
||||
for my $type1ref ( values %$dest_hosts_ref ) {
|
||||
for my $interface1 ( keys %$type1ref ) {
|
||||
my $array1ref = $type1ref->{$interface1};
|
||||
for my $host1ref ( @$array1ref ) {
|
||||
next if $host1ref->{options}{sourceonly};
|
||||
my $ipsec_out_match = match_ipsec_out $zone1 , $host1ref;
|
||||
for my $net1 ( @{$host1ref->{hosts}} ) {
|
||||
unless ( $interface eq $interface1 && $net eq $net1 && ! $host1ref->{options}{routeback} ) {
|
||||
#
|
||||
# We defer evaluation of the source net match to accomodate systems without $capabilities{KLUDEFREE};
|
||||
#
|
||||
add_6jump(
|
||||
$chain3ref ,
|
||||
$chain ,
|
||||
join( '',
|
||||
$match_source_dev,
|
||||
match_dest_6dev($interface1),
|
||||
match_source_6net($net),
|
||||
match_dest_6net($net1),
|
||||
$ipsec_out_match )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#
|
||||
# E N D F O R W A R D I N G
|
||||
#
|
||||
# Now add an unconditional jump to the last unique policy-only chain determined above, if any
|
||||
#
|
||||
add_6jump $frwd_ref , $last_chain if $last_chain;
|
||||
}
|
||||
}
|
||||
#
|
||||
# Add the jumps to the interface chains from filter FORWARD, INPUT, OUTPUT
|
||||
#
|
||||
for my $interface ( @interfaces ) {
|
||||
|
||||
add_6jump( $filter6_table->{FORWARD} , forward_chain $interface , match_source_dev( $interface ) ) if use_forward_6chain $interface;
|
||||
add_6jump( $filter6_table->{INPUT} , input_chain $interface , match_source_dev( $interface ) ) if use_input_6chain $interface;
|
||||
|
||||
if ( use_output_6chain $interface ) {
|
||||
add_6jump $filter6_table->{OUTPUT} , output_chain $interface , "-o $interface " unless get_interface_option( $interface, 'port' );
|
||||
}
|
||||
}
|
||||
|
||||
my $chainref = $filter6_table->{"${fw}2${fw}"};
|
||||
|
||||
add_rule $filter_table->{OUTPUT} , "-o lo -j " . ($chainref->{referenced} ? "$chainref->{name}" : 'ACCEPT' );
|
||||
add_rule $filter_table->{INPUT} , '-i lo -j ACCEPT';
|
||||
|
||||
my %builtins = ( mangle => [ qw/PREROUTING INPUT FORWARD POSTROUTING/ ] ,
|
||||
nat=> [ qw/PREROUTING OUTPUT POSTROUTING/ ] ,
|
||||
filter=> [ qw/INPUT FORWARD OUTPUT/ ] );
|
||||
|
||||
complete_standard_6chain $filter6_table->{INPUT} , 'all' , firewall_zone , 'DROP';
|
||||
complete_standard_6chain $filter6_table->{OUTPUT} , firewall_zone , 'all', 'REJECT';
|
||||
complete_standard_6chain $filter6_table->{FORWARD} , 'all' , 'all', 'REJECT';
|
||||
|
||||
if ( $config{LOGALLNEW} ) {
|
||||
for my $table qw/mangle filter/ {
|
||||
for my $chain ( @{$builtins{$table}} ) {
|
||||
log_rule_limit
|
||||
$config{LOGALLNEW} ,
|
||||
$chain6_table{$table}{$chain} ,
|
||||
$table ,
|
||||
$chain ,
|
||||
'' ,
|
||||
'' ,
|
||||
'insert' ,
|
||||
'-m state --state NEW ';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub setup_mss( ) {
|
||||
my $clampmss = $config{CLAMPMSS};
|
||||
my $option;
|
||||
|
Loading…
Reference in New Issue
Block a user