Change 'local' to 'loopback' and add 'local' zones that match non-loopback interfaces.

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2013-05-26 14:06:51 -07:00
parent f89c704d01
commit 2de0fbf7d0
5 changed files with 113 additions and 52 deletions

View File

@ -1427,7 +1427,7 @@ sub handle_loopback_traffic() {
my $natout = $nat_table->{OUTPUT};
my $rawout = $raw_table->{OUTPUT};
my $rulenum = 0;
my $local = local_zone;
my $loopback = loopback_zones;
my $outchainref;
my @rule;
@ -1456,7 +1456,7 @@ sub handle_loopback_traffic() {
#
if ( $type1 == FIREWALL ) {
for my $z2 ( @zones ) {
next if $local && $z1 eq $z2;
next if $loopback && $z1 eq $z2;
my $chain = rules_target( $z1, $z2 );
@ -1522,7 +1522,7 @@ sub add_interface_jumps {
our %forward_jump_added;
my @interfaces = grep $_ ne '%vserver%', @_;
my $dummy;
my $lo_jump_added = local_zone && ! get_interface_option( 'lo', 'destonly' );
my $lo_jump_added = interface_zone( 'lo' ) && ! get_interface_option( 'lo', 'destonly' );
#
# Add Nat jumps
#
@ -2121,6 +2121,7 @@ sub generate_matrix() {
my $nested = @{$zoneref->{parents}};
my $parenthasnat = 0;
my $parenthasnotrack = 0;
my $type = $zoneref->{type};
#
# Create the zone's dnat chain
#
@ -2171,14 +2172,14 @@ sub generate_matrix() {
#
# FORWARDING Jump for non-IPSEC host group
#
add_forward_jump( $zone, $interface, $hostref, $net, $exclusions, $frwd_ref, $isport, $bridge ) if $frwd_ref && $hostref->{ipsec} ne 'ipsec' && $zoneref->{type} ne LOCAL;
add_forward_jump( $zone, $interface, $hostref, $net, $exclusions, $frwd_ref, $isport, $bridge ) if $frwd_ref && $hostref->{ipsec} ne 'ipsec' && $type ne LOOPBACK;
}
} # Subnet Loop
} # Hostref Loop
} # Interface Loop
} #Type Loop
next if $zoneref->{type} == LOCAL;
next if $type == LOOPBACK;
if ( $frwd_ref ) {
#
@ -2198,10 +2199,14 @@ sub generate_matrix() {
#
for my $zone1 ( @dest_zones ) {
my $zone1ref = find_zone( $zone1 );
my $type1 = $zone1ref->{type};
next if $filter_table->{rules_chain( ${zone}, ${zone1} )}->{policy} eq 'NONE';
next if $zone1ref->{type} == LOCAL;
next if $type1 == LOOPBACK;
next if $type == LOCAL && $type1 != LOCAL;
next if $type1 == LOCAL && $type != LOCAL;
my $chain = rules_target $zone, $zone1;
@ -2213,7 +2218,7 @@ sub generate_matrix() {
next if ( $num_ifaces = scalar( keys ( %{$zoneref->{interfaces}} ) ) ) < 2 && ! $zoneref->{options}{in_out}{routeback};
}
if ( $zone1ref->{type} & BPORT ) {
if ( $type1 & BPORT ) {
next unless $zoneref->{bridge} eq $zone1ref->{bridge};
}

View File

@ -2378,7 +2378,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
#
$sourceref = find_zone( $chainref->{sourcezone} ) if $chainref->{sourcezone};
#
# And we need the dest zone for local/off-firewall/destonly checks
# And we need the dest zone for local/loopback/off-firewall/destonly checks
#
$destref = find_zone( $chainref->{destzone} ) if $chainref->{destzone};
} else {
@ -2441,16 +2441,18 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
}
}
#
# Handle 'local' warnings
# Handle 'local/loopback' warnings
#
unless ( $wildcard ) {
if ( $sourceref ) {
warning_message( "The SOURCE zone in this rule is 'destonly'" ) if $sourceref->{destonly};
if ( $destref ) {
warning_message( "The SOURCE zone is local and the DEST zone is off-firewall" ) if $sourceref->{type} == LOCAL && ! ( $destref->{type} & ( FIREWALL | VSERVER ) );
warning_message( "The SOURCE zone is off-firewall and the DEST zone is 'local'" ) if $destref->{type} == LOCAL && ! ( $sourceref->{type} & ( FIREWALL | VSERVER ) );
warning_message( "\$FW to \$FW rules are ignored when there is a defined 'local' zone" ) if local_zone && $sourceref->{type} == FIREWALL && $destref->{type} == FIREWALL;
warning_message( "The SOURCE zone is loopback and the DEST zone is off-firewall" ) if $sourceref->{type} == LOOPBACK && ! ( $destref->{type} & ( FIREWALL | VSERVER ) );
warning_message( "The SOURCE zone is off-firewall and the DEST zone is 'loopback'" ) if $destref->{type} == LOOPBACK && ! ( $sourceref->{type} & ( FIREWALL | VSERVER ) );
warning_message( "The SOURCE zone is 'local' and the DEST zone is off-firewall" ) if $sourceref->{type} == LOCAL && ! ( $destref->{type} & ( FIREWALL | VSERVER | LOCAL) );
warning_message( "The SOURCE zone is off-firewall and the DEST zone is 'loopback'" ) if $destref->{type} == LOCAL && ! ( $sourceref->{type} & ( FIREWALL | VSERVER | LOCAL) );
warning_message( "\$FW to \$FW rules are ignored when there is a defined 'loopback' zone" ) if loopback_zones && $sourceref->{type} == FIREWALL && $destref->{type} == FIREWALL;
}
}
}

View File

@ -38,6 +38,7 @@ our @EXPORT = ( qw( NOTHING
IPSECMODE
FIREWALL
VSERVER
LOOPBACK
LOCAL
IP
BPORT
@ -51,7 +52,8 @@ our @EXPORT = ( qw( NOTHING
dump_zone_contents
find_zone
firewall_zone
local_zone
loopback_zones
local_zones
defined_zone
zone_type
zone_interfaces
@ -60,7 +62,6 @@ our @EXPORT = ( qw( NOTHING
all_parent_zones
complex_zones
vserver_zones
local_zone
on_firewall_zones
off_firewall_zones
non_firewall_zones
@ -87,6 +88,7 @@ our @EXPORT = ( qw( NOTHING
interface_has_option
set_interface_option
set_interface_provider
interface_zone
interface_zones
verify_required_interfaces
validate_hosts_file
@ -155,7 +157,8 @@ our @zones;
our %zones;
our %zonetypes;
our $firewall_zone;
our $local_zone;
our @loopback_zones;
our @local_zones;
our %reservedName = ( all => 1,
any => 1,
@ -216,7 +219,8 @@ use constant { FIREWALL => 1,
BPORT => 4,
IPSEC => 8,
VSERVER => 16,
LOCAL => 32
LOOPBACK => 32,
LOCAL => 64,
};
use constant { SIMPLE_IF_OPTION => 1,
@ -283,8 +287,9 @@ sub initialize( $$ ) {
( $family , $upgrade ) = @_;
@zones = ();
%zones = ();
@loopback_zones = ();
@local_zones = ();
$firewall_zone = '';
$local_zone = '';
$have_ipsec = undef;
@interfaces = ();
@ -340,7 +345,7 @@ sub initialize( $$ ) {
sourceonly => 1,
mss => 1,
);
%zonetypes = ( 1 => 'firewall', 2 => 'ipv4', 4 => 'bport4', 8 => 'ipsec4', 16 => 'vserver', 32 => 'local' );
%zonetypes = ( 1 => 'firewall', 2 => 'ipv4', 4 => 'bport4', 8 => 'ipsec4', 16 => 'vserver', 32 => 'loopback', 64 => 'local' );
} else {
%validinterfaceoptions = ( accept_ra => NUMERIC_IF_OPTION,
blacklist => SIMPLE_IF_OPTION + IF_OPTION_HOST,
@ -371,7 +376,7 @@ sub initialize( $$ ) {
tcpflags => 1,
mss => 1,
);
%zonetypes = ( 1 => 'firewall', 2 => 'ipv6', 4 => 'bport6', 8 => 'ipsec4', 16 => 'vserver' );
%zonetypes = ( 1 => 'firewall', 2 => 'ipv6', 4 => 'bport6', 8 => 'ipsec4', 16 => 'vserver', 32 => 'loopback', 64 => 'local' );
}
}
@ -389,7 +394,7 @@ sub parse_zone_option_list($$\$$)
my $fmt;
if ( $list ne '-' ) {
fatal_error "The 'local' zone may not have $column OPTIONS" if $zonetype == LOCAL;
fatal_error "The 'loopback' zone may not have $column OPTIONS" if $zonetype == LOOPBACK;
for my $e ( split_list $list, 'option' ) {
my $val = undef;
@ -499,10 +504,11 @@ sub process_zone( \$ ) {
$type = IP;
$$ip = 1;
} elsif ( $type eq 'local' ) {
fatal_error 'The local zone may not be nested' if @parents;
fatal_error "Only one local zone may be defined ($zone)" if $local_zone;
$local_zone = $zone;
push @local_zones, $zone;
$type = LOCAL;
} elsif ( $type eq 'loopback' ) {
push @loopback_zones, $zone;
$type = LOOPBACK;
} else {
fatal_error "Invalid zone type ($type)";
}
@ -515,6 +521,8 @@ sub process_zone( \$ ) {
fatal_error 'Subzones of a Vserver zone not allowed' if $ptype & VSERVER;
fatal_error 'Subzones of firewall zone not allowed' if $ptype & FIREWALL;
fatal_error 'Loopback zones may only be subzones of other loopback zones' if ( $type | $ptype ) & LOOPBACK && $type != $ptype;
fatal_error 'Local zones may only be subzones of other local zones' if ( $type | $ptype ) & LOCAL && $type != $ptype;
set_super( $zones{$p} ) if $type & IPSEC && ! ( $ptype & IPSEC );
@ -600,7 +608,7 @@ sub determine_zones()
fatal_error "No firewall zone defined" unless $firewall_zone;
fatal_error "No IP zones defined" unless $ip;
fatal_error "The local zone and vserver zones are mutually exclusive" if $local_zone && vserver_zones;
fatal_error "Loopback zones and vserver zones are mutually exclusive" if @loopback_zones && vserver_zones;
#
# Topological sort to place sub-zones before all of their parents
#
@ -765,6 +773,7 @@ sub add_group_to_zone($$$$$)
$interfaceref = $interfaces{$interface};
$zoneref->{interfaces}{$interface} = 1;
$zoneref->{destonly} ||= $interfaceref->{options}{destonly};
$options->{destonly} ||= $interfaceref->{options}{destonly};
$interfaceref->{zones}{$zone} = 1;
@ -906,8 +915,12 @@ sub firewall_zone() {
$firewall_zone;
}
sub local_zone() {
$local_zone;
sub loopback_zones() {
@loopback_zones;
}
sub local_zones() {
@local_zones;
}
#
@ -1307,8 +1320,7 @@ sub process_interface( $$ ) {
if ( $zone ) {
if ( $physical eq 'lo' ) {
fatal_error "Only a local zone may be assigned to 'lo'" unless $zoneref->{type} == LOCAL;
fatal_error "The local zone may not have nets specified" if $netsref;
fatal_error "Only a loopback zone may be assigned to 'lo'" unless $zoneref->{type} == LOOPBACK;
fatal_error "Invalid definition of 'lo'" if $bridge ne $interface;
for ( qw/arp_filter
@ -1334,7 +1346,7 @@ sub process_interface( $$ ) {
fatal_error "The 'lo' interface may not specify the '$_' option" if supplied $options{$_};
}
} else {
fatal_error "The local zone may only be assigned to 'lo'" if $zoneref->{type} == LOCAL;
fatal_error "A loopback zone may only be assigned to 'lo'" if $zoneref->{type} == LOOPBACK;
}
$netsref ||= [ allip ];
@ -1558,6 +1570,15 @@ sub interface_zones( $ ) {
$interfaceref->{zones} || {};
}
#
# Returns the 'zone' member of the passed interface, if any
#
sub interface_zone( $ ) {
my $interfaceref = known_interface( $_[0] );
$interfaceref ? $interfaceref->{zone} : '';
}
#
# Return the 'optional' setting of the passed interface
#
@ -1877,6 +1898,7 @@ sub process_host( ) {
$hosts = $2;
fatal_error "Unknown interface ($interface)" unless ($interfaceref = $interfaces{$interface}) && $interfaceref->{root};
fatal_error "Loopback zones may only be associated with the loopback interface (lo)" if $type == LOOPBACK && $interfaceref->{name} ne 'lo';
} else {
fatal_error "Invalid HOST(S) column contents: $hosts"
}

View File

@ -189,7 +189,7 @@ c:a,b ipv4</programlisting>
</varlistentry>
<varlistentry>
<term><emphasis role="bold">local</emphasis></term>
<term><emphasis role="bold">loopback</emphasis></term>
<listitem>
<para>Added in Shorewall 4.5.17.</para>
@ -217,11 +217,12 @@ c:a,b ipv4</programlisting>
</listitem>
</itemizedlist>
<para>By defining a <emphasis role="bold">local</emphasis>
<para>By defining a <emphasis role="bold">loopback</emphasis>
zone and associating it with the loopback interface in
shorewall-interfaces(5), you can effect a slightly different
model. Suppose that the <emphasis role="bold">local</emphasis>
zone name is 'local'; then:</para>
model. Suppose that the <emphasis
role="bold">loopback</emphasis> zone name is 'local';
then:</para>
<itemizedlist>
<listitem>
@ -240,12 +241,27 @@ c:a,b ipv4</programlisting>
</listitem>
</itemizedlist>
<para>Rules to/from the <emphasis role="bold">local</emphasis>
zone and any zone other than the firewall zone are ignored
with a warning.</para>
<para>Rules to/from the <emphasis
role="bold">loopback</emphasis> zone and any zone other than
the firewall zone are ignored with a warning.</para>
<para>Only one <emphasis role="bold">local</emphasis> zone may
be defined.</para>
<para><emphasis role="bold">loopback</emphasis> zones may be
nested within other <emphasis role="bold">loopback</emphasis>
zones.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>local</term>
<listitem>
<para>Added in Shorewall 4.5.17. <emphasis
role="bold">local</emphasis> is the same as <emphasis
role="bold">ipv4</emphasis> with the exception that the zone
is only accessible from the <emphasis
role="bold">firewall</emphasis>, <emphasis
role="bold">vserver</emphasis> and other <emphasis
role="bold">local</emphasis> zones.</para>
</listitem>
</varlistentry>
</variablelist>

View File

@ -187,7 +187,7 @@ c:a,b ipv6</programlisting>
</varlistentry>
<varlistentry>
<term><emphasis role="bold">local</emphasis></term>
<term><emphasis role="bold">loopback</emphasis></term>
<listitem>
<para>Added in Shorewall 4.5.17.</para>
@ -215,11 +215,12 @@ c:a,b ipv6</programlisting>
</listitem>
</itemizedlist>
<para>By defining a <emphasis role="bold">local</emphasis>
<para>By defining a <emphasis role="bold">loopback</emphasis>
zone and associating it with the loopback interface in
shorewall-interfaces(5), you can effect a slightly different
model. Suppose that the <emphasis role="bold">local</emphasis>
zone name is 'local'; then:</para>
model. Suppose that the <emphasis
role="bold">loopback</emphasis> zone name is 'local';
then:</para>
<itemizedlist>
<listitem>
@ -238,12 +239,27 @@ c:a,b ipv6</programlisting>
</listitem>
</itemizedlist>
<para>Rules to/from the <emphasis role="bold">local</emphasis>
zone and any zone other than the firewall zone are ignored
with a warning.</para>
<para>Rules to/from the <emphasis
role="bold">loopback</emphasis> zone and any zone other than
the firewall zone are ignored with a warning.</para>
<para>Only one <emphasis role="bold">local</emphasis> zone may
be defined.</para>
<para><emphasis role="bold">loopback</emphasis> zones may be
nested within other <emphasis role="bold">loopback</emphasis>
zones.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>local</term>
<listitem>
<para>Added in Shorewall 4.5.17. <emphasis
role="bold">local</emphasis> is the same as <emphasis
role="bold">ipv6</emphasis> with the exception that the zone
is only accessible from the <emphasis
role="bold">firewall</emphasis>, <emphasis
role="bold">vserver</emphasis> and other <emphasis
role="bold">local</emphasis> zones.</para>
</listitem>
</varlistentry>
</variablelist>