Change 'local' interface option to a zone type.

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2013-05-19 15:35:20 -07:00
parent 1e6578c759
commit ac02c484f5
7 changed files with 213 additions and 40 deletions

View File

@ -836,7 +836,7 @@ sub add_common_rules ( $ ) {
my $interfaceref = find_interface $interface; my $interfaceref = find_interface $interface;
unless ( $interfaceref->{options}{ignore} & NO_SFILTER || $interfaceref->{options}{rpfilter} ) { unless ( $interfaceref->{options}{ignore} & NO_SFILTER || $interfaceref->{options}{rpfilter} || $interfaceref->{physical} eq 'lo' ) {
my @filters = @{$interfaceref->{filter}}; my @filters = @{$interfaceref->{filter}};
@ -1520,7 +1520,7 @@ sub add_interface_jumps {
my @interfaces = grep $_ ne '%vserver%', @_; my @interfaces = grep $_ ne '%vserver%', @_;
my $dummy; my $dummy;
my $loref = known_interface('lo'); my $loref = known_interface('lo');
my $lo_jump_added = $loref && $loref->{options}{local} && ! $loref->{options}{destonly}; my $lo_jump_added = local_zone;
# #
# Add Nat jumps # Add Nat jumps
# #
@ -2169,13 +2169,15 @@ sub generate_matrix() {
# #
# FORWARDING Jump for non-IPSEC host group # 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' && ! $hostref->{options}{local} ); add_forward_jump( $zone, $interface, $hostref, $net, $exclusions, $frwd_ref, $isport, $bridge ) if $frwd_ref && $hostref->{ipsec} ne 'ipsec' && $zoneref->{type} ne LOCAL;
} }
} # Subnet Loop } # Subnet Loop
} # Hostref Loop } # Hostref Loop
} # Interface Loop } # Interface Loop
} #Type Loop } #Type Loop
next if $zoneref->{type} == LOCAL;
if ( $frwd_ref ) { if ( $frwd_ref ) {
# #
# F O R W A R D I N G # F O R W A R D I N G
@ -2197,6 +2199,8 @@ sub generate_matrix() {
next if $filter_table->{rules_chain( ${zone}, ${zone1} )}->{policy} eq 'NONE'; next if $filter_table->{rules_chain( ${zone}, ${zone1} )}->{policy} eq 'NONE';
next if $zone1ref->{type} == LOCAL;
my $chain = rules_target $zone, $zone1; my $chain = rules_target $zone, $zone1;
next unless $chain; # CONTINUE policy with no rules next unless $chain; # CONTINUE policy with no rules
@ -2216,7 +2220,7 @@ sub generate_matrix() {
for my $typeref ( values %{$zone1ref->{hosts}} ) { for my $typeref ( values %{$zone1ref->{hosts}} ) {
for my $interface ( sort { interface_number( $a ) <=> interface_number( $b ) } keys %$typeref ) { for my $interface ( sort { interface_number( $a ) <=> interface_number( $b ) } keys %$typeref ) {
for my $hostref ( @{$typeref->{$interface}} ) { for my $hostref ( @{$typeref->{$interface}} ) {
next if $hostref->{options}{sourceonly} || $hostref->{options}{local}; next if $hostref->{options}{sourceonly};
if ( $zone ne $zone1 || $num_ifaces > 1 || $hostref->{options}{routeback} ) { if ( $zone ne $zone1 || $num_ifaces > 1 || $hostref->{options}{routeback} ) {
my @ipsec_out_match = match_ipsec_out $zone1 , $hostref; my @ipsec_out_match = match_ipsec_out $zone1 , $hostref;
my $dest_exclusion = dest_exclusion( $hostref->{exclusions}, $chain); my $dest_exclusion = dest_exclusion( $hostref->{exclusions}, $chain);

View File

@ -2441,15 +2441,15 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
} }
} }
# #
# Handle 'local' zone warnings # Handle 'local' warnings
# #
unless ( $wildcard ) { unless ( $wildcard ) {
if ( $sourceref ) { if ( $sourceref ) {
warning_message( "The SOURCE zone in this rule is 'destonly'" ) if $sourceref->{destonly}; warning_message( "The SOURCE zone in this rule is 'destonly'" ) if $sourceref->{destonly};
if ( $destref ) { if ( $destref ) {
warning_message( "The SOURCE zone is local and the DEST zone is off-firewall" ) if $sourceref->{local} && ! ( $destref->{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 ) );
warning_message( "The SOURCE zone is off-firewall and the DEST zone is 'local'" ) if $destref->{local} && ! ( $sourceref->{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 ) );
} }
} }
} }

View File

@ -38,6 +38,7 @@ our @EXPORT = ( qw( NOTHING
IPSECMODE IPSECMODE
FIREWALL FIREWALL
VSERVER VSERVER
LOCAL
IP IP
BPORT BPORT
IPSEC IPSEC
@ -50,6 +51,7 @@ our @EXPORT = ( qw( NOTHING
dump_zone_contents dump_zone_contents
find_zone find_zone
firewall_zone firewall_zone
local_zone
defined_zone defined_zone
zone_type zone_type
zone_interfaces zone_interfaces
@ -58,6 +60,7 @@ our @EXPORT = ( qw( NOTHING
all_parent_zones all_parent_zones
complex_zones complex_zones
vserver_zones vserver_zones
local_zone
on_firewall_zones on_firewall_zones
off_firewall_zones off_firewall_zones
non_firewall_zones non_firewall_zones
@ -152,6 +155,7 @@ our @zones;
our %zones; our %zones;
our %zonetypes; our %zonetypes;
our $firewall_zone; our $firewall_zone;
our $local_zone;
our %reservedName = ( all => 1, our %reservedName = ( all => 1,
any => 1, any => 1,
@ -211,7 +215,9 @@ use constant { FIREWALL => 1,
IP => 2, IP => 2,
BPORT => 4, BPORT => 4,
IPSEC => 8, IPSEC => 8,
VSERVER => 16 }; VSERVER => 16,
LOCAL => 32
};
use constant { SIMPLE_IF_OPTION => 1, use constant { SIMPLE_IF_OPTION => 1,
BINARY_IF_OPTION => 2, BINARY_IF_OPTION => 2,
@ -278,6 +284,7 @@ sub initialize( $$ ) {
@zones = (); @zones = ();
%zones = (); %zones = ();
$firewall_zone = ''; $firewall_zone = '';
$local_zone = '';
$have_ipsec = undef; $have_ipsec = undef;
@interfaces = (); @interfaces = ();
@ -303,7 +310,6 @@ sub initialize( $$ ) {
dhcp => SIMPLE_IF_OPTION, dhcp => SIMPLE_IF_OPTION,
ignore => NUMERIC_IF_OPTION + IF_OPTION_WILDOK, ignore => NUMERIC_IF_OPTION + IF_OPTION_WILDOK,
maclist => SIMPLE_IF_OPTION + IF_OPTION_HOST, maclist => SIMPLE_IF_OPTION + IF_OPTION_HOST,
local => SIMPLE_IF_OPTION + IF_OPTION_HOST,
logmartians => BINARY_IF_OPTION, logmartians => BINARY_IF_OPTION,
nets => IPLIST_IF_OPTION + IF_OPTION_ZONEONLY + IF_OPTION_VSERVER, nets => IPLIST_IF_OPTION + IF_OPTION_ZONEONLY + IF_OPTION_VSERVER,
norfc1918 => OBSOLETE_IF_OPTION, norfc1918 => OBSOLETE_IF_OPTION,
@ -334,7 +340,7 @@ sub initialize( $$ ) {
sourceonly => 1, sourceonly => 1,
mss => 1, mss => 1,
); );
%zonetypes = ( 1 => 'firewall', 2 => 'ipv4', 4 => 'bport4', 8 => 'ipsec4', 16 => 'vserver' ); %zonetypes = ( 1 => 'firewall', 2 => 'ipv4', 4 => 'bport4', 8 => 'ipsec4', 16 => 'vserver', 32 => 'local' );
} else { } else {
%validinterfaceoptions = ( accept_ra => NUMERIC_IF_OPTION, %validinterfaceoptions = ( accept_ra => NUMERIC_IF_OPTION,
blacklist => SIMPLE_IF_OPTION + IF_OPTION_HOST, blacklist => SIMPLE_IF_OPTION + IF_OPTION_HOST,
@ -342,7 +348,6 @@ sub initialize( $$ ) {
destonly => SIMPLE_IF_OPTION + IF_OPTION_HOST, destonly => SIMPLE_IF_OPTION + IF_OPTION_HOST,
dhcp => SIMPLE_IF_OPTION, dhcp => SIMPLE_IF_OPTION,
ignore => NUMERIC_IF_OPTION + IF_OPTION_WILDOK, ignore => NUMERIC_IF_OPTION + IF_OPTION_WILDOK,
local => SIMPLE_IF_OPTION + IF_OPTION_HOST,
maclist => SIMPLE_IF_OPTION + IF_OPTION_HOST, maclist => SIMPLE_IF_OPTION + IF_OPTION_HOST,
nets => IPLIST_IF_OPTION + IF_OPTION_ZONEONLY + IF_OPTION_VSERVER, nets => IPLIST_IF_OPTION + IF_OPTION_ZONEONLY + IF_OPTION_VSERVER,
nosmurfs => SIMPLE_IF_OPTION + IF_OPTION_HOST, nosmurfs => SIMPLE_IF_OPTION + IF_OPTION_HOST,
@ -384,6 +389,8 @@ sub parse_zone_option_list($$\$$)
my $fmt; my $fmt;
if ( $list ne '-' ) { if ( $list ne '-' ) {
fatal_error "The 'local' zone may not have $column OPTIONS" if $zonetype == LOCAL;
for my $e ( split_list $list, 'option' ) { for my $e ( split_list $list, 'option' ) {
my $val = undef; my $val = undef;
my $invert = ''; my $invert = '';
@ -491,6 +498,11 @@ sub process_zone( \$ ) {
} elsif ( $type eq '-' ) { } elsif ( $type eq '-' ) {
$type = IP; $type = IP;
$$ip = 1; $$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;
$type = LOCAL;
} else { } else {
fatal_error "Invalid zone type ($type)"; fatal_error "Invalid zone type ($type)";
} }
@ -568,6 +580,8 @@ sub process_zone( \$ ) {
# #
# Parse the zones file. # Parse the zones file.
# #
sub vserver_zones();
sub determine_zones() sub determine_zones()
{ {
my @z; my @z;
@ -586,6 +600,7 @@ sub determine_zones()
fatal_error "No firewall zone defined" unless $firewall_zone; fatal_error "No firewall zone defined" unless $firewall_zone;
fatal_error "No IP zones defined" unless $ip; fatal_error "No IP zones defined" unless $ip;
fatal_error "The local zone and vserver zones are mutually exclusive" if $local_zone && vserver_zones;
# #
# Topological sort to place sub-zones before all of their parents # Topological sort to place sub-zones before all of their parents
# #
@ -750,7 +765,6 @@ sub add_group_to_zone($$$$$)
$interfaceref = $interfaces{$interface}; $interfaceref = $interfaces{$interface};
$zoneref->{interfaces}{$interface} = 1; $zoneref->{interfaces}{$interface} = 1;
$zoneref->{destonly} ||= $interfaceref->{options}{destonly}; $zoneref->{destonly} ||= $interfaceref->{options}{destonly};
$zoneref->{local} ||= $interfaceref->{options}{local};
$interfaceref->{zones}{$zone} = 1; $interfaceref->{zones}{$zone} = 1;
@ -892,6 +906,10 @@ sub firewall_zone() {
$firewall_zone; $firewall_zone;
} }
sub local_zone() {
$local_zone;
}
# #
# Determine if the passed physical device is a bridge # Determine if the passed physical device is a bridge
# #
@ -1287,6 +1305,37 @@ sub process_interface( $$ ) {
}; };
if ( $zone ) { 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 "Invalid definition of 'lo'" if $bridge ne $interface;
for ( qw/arp_filter
arp_ignore
blacklist
bridge
detectnets
dhcp
maclist
logmartians
norfc1918
nosmurts
proxyarp
routeback
routefilter
rpfilter
sfilter
sourceroute
upnp
upnpclient
mss
/ ) {
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;
}
$netsref ||= [ allip ]; $netsref ||= [ allip ];
add_group_to_zone( $zone, $zoneref->{type}, $interface, $netsref, $hostoptionsref ); add_group_to_zone( $zone, $zoneref->{type}, $interface, $netsref, $hostoptionsref );
add_group_to_zone( $zone, add_group_to_zone( $zone,

View File

@ -150,6 +150,11 @@ loc eth2 -</programlisting>
<member>wait</member> <member>wait</member>
</simplelist> </simplelist>
<para>Beginning with Shorewall 4.5.17, if you specify a zone for the
'lo' interface, then that zone must be defined as type
<option>local</option> in <ulink
url="shorewall6-zones.html">shorewall6-zones</ulink>(5).</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -205,7 +210,7 @@ loc eth2 -</programlisting>
changed; the value assigned to the setting will be the value changed; the value assigned to the setting will be the value
specified (if any) or 1 if no value is given.</para> specified (if any) or 1 if no value is given.</para>
<para/> <para></para>
<note> <note>
<para>This option does not work with a wild-card <para>This option does not work with a wild-card
@ -239,7 +244,7 @@ loc eth2 -</programlisting>
<para>8 - do not reply for all local addresses</para> <para>8 - do not reply for all local addresses</para>
<para/> <para></para>
<note> <note>
<para>This option does not work with a wild-card <para>This option does not work with a wild-card
@ -247,7 +252,7 @@ loc eth2 -</programlisting>
the INTERFACE column.</para> the INTERFACE column.</para>
</note> </note>
<para/> <para></para>
<warning> <warning>
<para>Do not specify <emphasis <para>Do not specify <emphasis
@ -374,16 +379,6 @@ loc eth2 -</programlisting>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><emphasis role="bold">local</emphasis></term>
<listitem>
<para>Added in Shorewall 4.5.17. Causes the compiler to omit
rules from this interface to other interfaces and from other
interfaces to this interface.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><emphasis <term><emphasis
role="bold">logmartians[={0|1}]</emphasis></term> role="bold">logmartians[={0|1}]</emphasis></term>
@ -416,7 +411,7 @@ loc eth2 -</programlisting>
1 1
teastep@lists:~$ </programlisting> teastep@lists:~$ </programlisting>
<para/> <para></para>
<note> <note>
<para>This option does not work with a wild-card <para>This option does not work with a wild-card

View File

@ -135,8 +135,8 @@ c:a,b ipv4</programlisting>
<para>This is the standard Shorewall zone type and is the <para>This is the standard Shorewall zone type and is the
default if you leave this column empty or if you enter "-" in default if you leave this column empty or if you enter "-" in
the column. Communication with some zone hosts may be the column. Communication with some zone hosts may be
encrypted. Encrypted hosts are designated using the encrypted. Encrypted hosts are designated using the 'ipsec'
'ipsec' option in <ulink option in <ulink
url="shorewall-hosts.html">shorewall-hosts</ulink>(5).</para> url="shorewall-hosts.html">shorewall-hosts</ulink>(5).</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -187,6 +187,71 @@ c:a,b ipv4</programlisting>
firewall zone.</para> firewall zone.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><emphasis role="bold">local</emphasis></term>
<listitem>
<para>Added in Shorewall 4.5.17.</para>
<para>Normally, Shorewall treats the loopback interface (lo)
in the following way:</para>
<itemizedlist>
<listitem>
<para>By default, all traffic through the interface is
ACCEPTed.</para>
</listitem>
<listitem>
<para>If a $FW -&gt; $FW policy is defined or $FW -&gt;
$FW rules are defined, they are placed in a chain named
${FW}2${F2} or ${FW}-${FW} (e.g., 'fw2fw' or 'fw-fw' )
depending on the ZONE2ZONE setting in <ulink
url="shorewall.conf.html">shorewall.conf</ulink>(5).</para>
</listitem>
<listitem>
<para>$FW -&gt; $FW traffic is only filtered in the OUTPUT
chain.</para>
</listitem>
</itemizedlist>
<para>By defining a <emphasis role="bold">local</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>
<itemizedlist>
<listitem>
<para>Both $FW -&gt; local and local -&gt; $FW chains are
created.</para>
</listitem>
<listitem>
<para>The $FW -&gt; local and local -&gt; $FW policies may
be different.</para>
</listitem>
<listitem>
<para>Both $FW -&gt; local and local -&gt; $FW rules may
be specified.</para>
</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>Only one <emphasis role="bold">local</emphasis> zone may
be defined.</para>
<para>When a local zone is defined, you should ensure that the
$FW -&gt; $FW policy is ACCEPT; otherwise, extraneous chains
and rules will be created.</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -84,6 +84,11 @@
loc eth1 - loc eth1 -
loc eth2 -</programlisting> loc eth2 -</programlisting>
</blockquote> </blockquote>
<para>Beginning with Shorewall 4.5.17, if you specify a zone for the
'lo' interface, then that zone must be defined as type
<option>local</option> in <ulink
url="shorewall6-zones.html">shorewall6-zones</ulink>(5).</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -315,16 +320,6 @@ loc eth2 -</programlisting>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><emphasis role="bold">local</emphasis></term>
<listitem>
<para>Added in Shorewall 4.5.17. Causes the compiler to omit
rules from this interface to other interfaces and from other
interfaces to this interface.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><emphasis <term><emphasis
role="bold">mss</emphasis>=<emphasis>number</emphasis></term> role="bold">mss</emphasis>=<emphasis>number</emphasis></term>

View File

@ -133,8 +133,8 @@ c:a,b ipv6</programlisting>
<para>This is the standard Shorewall6 zone type and is the <para>This is the standard Shorewall6 zone type and is the
default if you leave this column empty or if you enter "-" in default if you leave this column empty or if you enter "-" in
the column. Communication with some zone hosts may be the column. Communication with some zone hosts may be
encrypted. Encrypted hosts are designated using the encrypted. Encrypted hosts are designated using the 'ipsec'
'ipsec' option in <ulink option in <ulink
url="shorewall6-hosts.html">shorewall6-hosts</ulink>(5).</para> url="shorewall6-hosts.html">shorewall6-hosts</ulink>(5).</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -185,6 +185,71 @@ c:a,b ipv6</programlisting>
firewall zone.</para> firewall zone.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><emphasis role="bold">local</emphasis></term>
<listitem>
<para>Added in Shorewall 4.5.17.</para>
<para>Normally, Shorewall treats the loopback interface (lo)
in the following way:</para>
<itemizedlist>
<listitem>
<para>By default, all traffic through the interface is
ACCEPTed.</para>
</listitem>
<listitem>
<para>If a $FW -&gt; $FW policy is defined or $FW -&gt;
$FW rules are defined, they are placed in a chain named
${FW}2${F2} or ${FW}-${FW} (e.g., 'fw2fw' or 'fw-fw' )
depending on the ZONE2ZONE setting in <ulink
url="shorewall6.conf.html">shorewall6.conf</ulink>(5).</para>
</listitem>
<listitem>
<para>$FW -&gt; $FW traffic is only filtered in the OUTPUT
chain.</para>
</listitem>
</itemizedlist>
<para>By defining a <emphasis role="bold">local</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>
<itemizedlist>
<listitem>
<para>Both $FW -&gt; local and local -&gt; $FW chains are
created.</para>
</listitem>
<listitem>
<para>The $FW -&gt; local and local -&gt; $FW policies may
be different.</para>
</listitem>
<listitem>
<para>Both $FW -&gt; local and local -&gt; $FW rules may
be specified.</para>
</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>Only one <emphasis role="bold">local</emphasis> zone may
be defined.</para>
<para>When a local zone is defined, you should ensure that the
$FW -&gt; $FW policy is ACCEPT; otherwise, extraneous chains
and rules will be created.</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</listitem> </listitem>
</varlistentry> </varlistentry>