mirror of
https://gitlab.com/shorewall/code.git
synced 2024-12-23 06:38:53 +01:00
Consult policies when constructing dnat chains; warning when zone specified on NAT-only rules
git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@8061 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
parent
72999ba23f
commit
318b4f002d
@ -23,8 +23,7 @@ Problems corrected in Shorewall 4.1.4.
|
|||||||
2) The compilation date recorded in the firewall.conf file produced by
|
2) The compilation date recorded in the firewall.conf file produced by
|
||||||
Shorewall-perl was previously mangled.
|
Shorewall-perl was previously mangled.
|
||||||
|
|
||||||
3) Previously, the following situation would result in unexpected
|
3) The following situation would result in unexpected behavior.
|
||||||
behavior.
|
|
||||||
|
|
||||||
/etc/shorewall/zones:
|
/etc/shorewall/zones:
|
||||||
|
|
||||||
@ -46,15 +45,30 @@ Problems corrected in Shorewall 4.1.4.
|
|||||||
|
|
||||||
#ACTION SOURCE DEST PROTO DEST
|
#ACTION SOURCE DEST PROTO DEST
|
||||||
# PORT(S)
|
# PORT(S)
|
||||||
ACCEPT+ net dmz tcp 80
|
ACCEPT net dmz tcp 80
|
||||||
REDIRECT loc 3128 tcp 80
|
REDIRECT loc 3128 tcp 80
|
||||||
|
|
||||||
The web server in the dmz (implied by the first rule) is
|
The web server in the dmz (implied by the first rule) is
|
||||||
inaccessible from the 'net' zone because the REDIRECT rule
|
inaccessible from the 'net' zone because the REDIRECT rule
|
||||||
redirects all traffic arriving on 'ppp+' to local port 3128 (the
|
redirects all traffic arriving on 'ppp+' to local port 3128.
|
||||||
ACCEPT+ is behaving like ACCEPT).
|
|
||||||
|
|
||||||
Shorewall 4.1.4 includes a fix for this problem.
|
Shorewall 4.1.4 includes a fix for this problem that also requires
|
||||||
|
a configuration change.
|
||||||
|
|
||||||
|
The basic problem with the above configuration is that 'net' is a
|
||||||
|
sub-zone of 'loc' (since ppp0 is a subset of ppp+) but Shorewall
|
||||||
|
isn't able to recognize that fact.
|
||||||
|
|
||||||
|
By changing the /etc/shorewall/zones file to make the parent/child
|
||||||
|
relationship explicit:
|
||||||
|
|
||||||
|
/etc/shorewall/zones:
|
||||||
|
|
||||||
|
#ZONE TYPE
|
||||||
|
fw firewall
|
||||||
|
loc ipv4
|
||||||
|
net:loc ipv4
|
||||||
|
dmz ipv4
|
||||||
|
|
||||||
Other changes in Shorewall 4.1.4.
|
Other changes in Shorewall 4.1.4.
|
||||||
|
|
||||||
@ -63,6 +77,13 @@ Other changes in Shorewall 4.1.4.
|
|||||||
installed. As always, the full configuration file set is installed
|
installed. As always, the full configuration file set is installed
|
||||||
in /usr/share/shorewall/configfiles.
|
in /usr/share/shorewall/configfiles.
|
||||||
|
|
||||||
|
2) Specifying a destination zone in a NAT-only rule now generates a
|
||||||
|
warning and the destination zone is ignored. NAT-only rules are:
|
||||||
|
|
||||||
|
NONAT
|
||||||
|
REDIRECT-
|
||||||
|
DNAT-
|
||||||
|
|
||||||
Migration Issues.
|
Migration Issues.
|
||||||
|
|
||||||
1) Previously, when HIGH_ROUTE_MARKS=Yes, Shorewall allowed non-zero
|
1) Previously, when HIGH_ROUTE_MARKS=Yes, Shorewall allowed non-zero
|
||||||
@ -78,6 +99,13 @@ Migration Issues.
|
|||||||
b) After the -v and -q options are applied, the resulting value is
|
b) After the -v and -q options are applied, the resulting value is
|
||||||
adjusted to fall within the range -1 through 2.
|
adjusted to fall within the range -1 through 2.
|
||||||
|
|
||||||
|
3) Specifying a destination zone in a NAT-only rule now generates a
|
||||||
|
warning and the destination zone is ignored. NAT-only rules are:
|
||||||
|
|
||||||
|
NONAT
|
||||||
|
REDIRECT-
|
||||||
|
DNAT-
|
||||||
|
|
||||||
New Features in Shorewall 4.1.
|
New Features in Shorewall 4.1.
|
||||||
|
|
||||||
1) Shorewall 4.1 contains experimental support for multiple Internet
|
1) Shorewall 4.1 contains experimental support for multiple Internet
|
||||||
|
@ -978,10 +978,11 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
|
|||||||
# Take care of irregular syntax and targets
|
# Take care of irregular syntax and targets
|
||||||
#
|
#
|
||||||
if ( $actiontype & REDIRECT ) {
|
if ( $actiontype & REDIRECT ) {
|
||||||
|
my $z = $actiontype & NATONLY ? '' : firewall_zone;
|
||||||
if ( $dest eq '-' ) {
|
if ( $dest eq '-' ) {
|
||||||
$dest = join( '', firewall_zone, '::' , $ports =~ /[:,]/ ? '' : $ports );
|
$dest = join( '', $z, '::' , $ports =~ /[:,]/ ? '' : $ports );
|
||||||
} else {
|
} else {
|
||||||
$dest = join( '', firewall_zone, '::', $dest ) unless $dest =~ /:/;
|
$dest = join( '', $z, '::', $dest ) unless $dest =~ /:/;
|
||||||
}
|
}
|
||||||
} elsif ( $action eq 'REJECT' ) {
|
} elsif ( $action eq 'REJECT' ) {
|
||||||
$action = 'reject';
|
$action = 'reject';
|
||||||
@ -1006,7 +1007,7 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
|
|||||||
$source = ALLIPv4;
|
$source = ALLIPv4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $dest =~ /^(.+?):(.*)/ ) {
|
if ( $dest =~ /^(.*?):(.*)/ ) {
|
||||||
$destzone = $1;
|
$destzone = $1;
|
||||||
$dest = $2;
|
$dest = $2;
|
||||||
} else {
|
} else {
|
||||||
@ -1016,8 +1017,13 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
|
|||||||
|
|
||||||
fatal_error "Missing source zone" if $sourcezone eq '-' || $sourcezone =~ /^:/;
|
fatal_error "Missing source zone" if $sourcezone eq '-' || $sourcezone =~ /^:/;
|
||||||
fatal_error "Unknown source zone ($sourcezone)" unless $sourceref = defined_zone( $sourcezone );
|
fatal_error "Unknown source zone ($sourcezone)" unless $sourceref = defined_zone( $sourcezone );
|
||||||
fatal_error "Missing destination zone" if $destzone eq '-' || $destzone =~ /^:/;
|
|
||||||
fatal_error "Unknown destination zone ($destzone)" unless $destref = defined_zone( $destzone );
|
if ( $actiontype & NATONLY ) {
|
||||||
|
warning_message "Destination zone ($destzone) ignored" unless $destzone eq '-' || $destzone eq '';
|
||||||
|
} else {
|
||||||
|
fatal_error "Missing destination zone" if $destzone eq '-' || $destzone eq '';
|
||||||
|
fatal_error "Unknown destination zone ($destzone)" unless $destref = defined_zone( $destzone );
|
||||||
|
}
|
||||||
|
|
||||||
my $restriction = NO_RESTRICT;
|
my $restriction = NO_RESTRICT;
|
||||||
|
|
||||||
@ -1027,16 +1033,7 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
|
|||||||
$restriction = INPUT_RESTRICT if $destzone eq firewall_zone;
|
$restriction = INPUT_RESTRICT if $destzone eq firewall_zone;
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
my ( $chain, $chainref, $policy );
|
||||||
# Check for illegal bridge port rule
|
|
||||||
#
|
|
||||||
if ( $destref->{type} eq 'bport4' ) {
|
|
||||||
unless ( $sourceref->{bridge} eq $destref->{bridge} || single_interface( $sourcezone ) eq $destref->{bridge} ) {
|
|
||||||
return 1 if $wildcard;
|
|
||||||
fatal_error "Rules with a DESTINATION Bridge Port zone must have a SOURCE zone on the same bridge";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# For compatibility with older Shorewall versions
|
# For compatibility with older Shorewall versions
|
||||||
#
|
#
|
||||||
@ -1045,31 +1042,43 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
|
|||||||
#
|
#
|
||||||
# Take care of chain
|
# Take care of chain
|
||||||
#
|
#
|
||||||
my $chain = "${sourcezone}2${destzone}";
|
|
||||||
my $chainref = ensure_chain 'filter', $chain;
|
unless ( $actiontype & NATONLY ) {
|
||||||
my $policy = $chainref->{policy};
|
#
|
||||||
|
# Check for illegal bridge port rule
|
||||||
if ( $policy eq 'NONE' ) {
|
#
|
||||||
return 1 if $wildcard;
|
if ( $destref->{type} eq 'bport4' ) {
|
||||||
fatal_error "Rules may not override a NONE policy";
|
unless ( $sourceref->{bridge} eq $destref->{bridge} || single_interface( $sourcezone ) eq $destref->{bridge} ) {
|
||||||
}
|
return 1 if $wildcard;
|
||||||
|
fatal_error "Rules with a DESTINATION Bridge Port zone must have a SOURCE zone on the same bridge";
|
||||||
#
|
}
|
||||||
# Handle Optimization
|
|
||||||
#
|
|
||||||
if ( $optimize > 0 ) {
|
|
||||||
my $loglevel = $filter_table->{$chainref->{policychain}}{loglevel};
|
|
||||||
if ( $loglevel ne '' ) {
|
|
||||||
return 1 if $target eq "${policy}:$loglevel}";
|
|
||||||
} else {
|
|
||||||
return 1 if $basictarget eq $policy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$chain = "${sourcezone}2${destzone}";
|
||||||
|
$chainref = ensure_chain 'filter', $chain;
|
||||||
|
$policy = $chainref->{policy};
|
||||||
|
|
||||||
|
if ( $policy eq 'NONE' ) {
|
||||||
|
return 1 if $wildcard;
|
||||||
|
fatal_error "Rules may not override a NONE policy";
|
||||||
|
}
|
||||||
|
#
|
||||||
|
# Handle Optimization
|
||||||
|
#
|
||||||
|
if ( $optimize > 0 ) {
|
||||||
|
my $loglevel = $filter_table->{$chainref->{policychain}}{loglevel};
|
||||||
|
if ( $loglevel ne '' ) {
|
||||||
|
return 1 if $target eq "${policy}:$loglevel}";
|
||||||
|
} else {
|
||||||
|
return 1 if $basictarget eq $policy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#
|
||||||
|
# Mark the chain as referenced and add appropriate rules from earlier sections.
|
||||||
|
#
|
||||||
|
$chainref = ensure_filter_chain $chain, 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
|
||||||
# Mark the chain as referenced and add appropriate rules from earlier sections.
|
|
||||||
#
|
|
||||||
$chainref = ensure_filter_chain $chain, 1;
|
|
||||||
#
|
#
|
||||||
# Generate Fixed part of the rule
|
# Generate Fixed part of the rule
|
||||||
#
|
#
|
||||||
@ -1145,7 +1154,11 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
|
|||||||
} else {
|
} else {
|
||||||
fatal_error "A server must be specified in the DEST column in $action rules" if $server eq '';
|
fatal_error "A server must be specified in the DEST column in $action rules" if $server eq '';
|
||||||
|
|
||||||
validate_address $server, 0;
|
if ( $server =~ /^(.+)-(.+)$/ ) {
|
||||||
|
validate_range( $1, $2 );
|
||||||
|
} else {
|
||||||
|
validate_address $server, 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ( $action eq 'SAME' ) {
|
if ( $action eq 'SAME' ) {
|
||||||
fatal_error 'Port mapping not allowed in SAME rules' if $serverport;
|
fatal_error 'Port mapping not allowed in SAME rules' if $serverport;
|
||||||
@ -1209,8 +1222,6 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
|
|||||||
#
|
#
|
||||||
fatal_error "Invalid DEST ($dest) in $action rule" if $dest =~ /:/;
|
fatal_error "Invalid DEST ($dest) in $action rule" if $dest =~ /:/;
|
||||||
|
|
||||||
$sourceref->{options}{nested} = 1;
|
|
||||||
|
|
||||||
$origdest = '' unless $origdest and $origdest ne '-';
|
$origdest = '' unless $origdest and $origdest ne '-';
|
||||||
|
|
||||||
if ( $origdest eq 'detect' ) {
|
if ( $origdest eq 'detect' ) {
|
||||||
@ -1547,6 +1558,8 @@ sub generate_matrix() {
|
|||||||
my $exclusions = $zoneref->{exclusions};
|
my $exclusions = $zoneref->{exclusions};
|
||||||
my $frwd_ref = 0;
|
my $frwd_ref = 0;
|
||||||
my $chain = 0;
|
my $chain = 0;
|
||||||
|
my $dnatref = $nat_table->{dnat_chain $zone};
|
||||||
|
my $nested = $zoneref->{options}{nested};
|
||||||
|
|
||||||
if ( $complex ) {
|
if ( $complex ) {
|
||||||
$frwd_ref = $filter_table->{"${zone}_frwd"};
|
$frwd_ref = $filter_table->{"${zone}_frwd"};
|
||||||
@ -1561,6 +1574,14 @@ sub generate_matrix() {
|
|||||||
push @rule_chains , [ $zone , firewall_zone , $chain2 ];
|
push @rule_chains , [ $zone , firewall_zone , $chain2 ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( $nested && $dnatref->{referenced} ) {
|
||||||
|
for my $zone1 ( all_zones ) {
|
||||||
|
if ( $filter_table->{"${zone}2${zone1}"}->{policy} eq 'CONTINUE' ) {
|
||||||
|
$nested = 0;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#
|
#
|
||||||
# Take care of PREROUTING, INPUT and OUTPUT jumps
|
# Take care of PREROUTING, INPUT and OUTPUT jumps
|
||||||
#
|
#
|
||||||
@ -1594,15 +1615,13 @@ sub generate_matrix() {
|
|||||||
|
|
||||||
my $source = match_source_net $net;
|
my $source = match_source_net $net;
|
||||||
|
|
||||||
my $chainref = $nat_table->{dnat_chain $zone};
|
if ( $dnatref->{referenced} ) {
|
||||||
|
|
||||||
if ( $chainref->{referenced} ) {
|
|
||||||
add_rule $preroutingref, $_ for ( @returnstack );
|
add_rule $preroutingref, $_ for ( @returnstack );
|
||||||
@returnstack = ();
|
@returnstack = ();
|
||||||
add_rule $preroutingref, join( '', match_source_dev( $interface), $source, $ipsec_in_match, '-j ', $chainref->{name} );
|
add_rule $preroutingref, join( '', match_source_dev( $interface), $source, $ipsec_in_match, '-j ', $dnatref->{name} );
|
||||||
}
|
}
|
||||||
|
|
||||||
push @returnstack, join( '', match_source_dev( $interface), $source, $ipsec_in_match, '-j RETURN' ) if $zoneref->{options}{nested};
|
push @returnstack, join( '', match_source_dev( $interface), $source, $ipsec_in_match, '-j RETURN' ) if $nested;
|
||||||
|
|
||||||
if ( $chain2 ) {
|
if ( $chain2 ) {
|
||||||
if ( @$exclusions ) {
|
if ( @$exclusions ) {
|
||||||
|
@ -299,7 +299,7 @@ sub determine_zones()
|
|||||||
in => parse_zone_option_list( $in_options || '', $type ) ,
|
in => parse_zone_option_list( $in_options || '', $type ) ,
|
||||||
out => parse_zone_option_list( $out_options || '', $type ) ,
|
out => parse_zone_option_list( $out_options || '', $type ) ,
|
||||||
complex => ($type eq 'ipsec4' || $options || $in_options || $out_options ? 1 : 0) ,
|
complex => ($type eq 'ipsec4' || $options || $in_options || $out_options ? 1 : 0) ,
|
||||||
nested => 0 } ,
|
nested => @parents > 0 } ,
|
||||||
interfaces => {} ,
|
interfaces => {} ,
|
||||||
children => [] ,
|
children => [] ,
|
||||||
hosts => {}
|
hosts => {}
|
||||||
|
@ -211,7 +211,9 @@ vpn ppp+:192.168.3.0/24</programlisting></para>
|
|||||||
than <ulink
|
than <ulink
|
||||||
url="shorewall-interfaces.html">shorewall-interfaces</ulink>(8) if
|
url="shorewall-interfaces.html">shorewall-interfaces</ulink>(8) if
|
||||||
there is another zone that uses a fixed PPP interface (for example,
|
there is another zone that uses a fixed PPP interface (for example,
|
||||||
if the 'net' zone always interfaces through ppp0).</para>
|
if the 'net' zone always interfaces through ppp0). See <ulink
|
||||||
|
url="shorewall-nesting.html">shorewall-nesting</ulink>(8) for
|
||||||
|
additional information.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
@ -108,12 +108,7 @@
|
|||||||
nesting occurs as a result of the use of wildcard interfaces (interface
|
nesting occurs as a result of the use of wildcard interfaces (interface
|
||||||
names ends in '+').</para>
|
names ends in '+').</para>
|
||||||
|
|
||||||
<para>Here's an example.
|
<para>Here's an example. <filename>/etc/shorewall/zones</filename>:</para>
|
||||||
<filename>/etc/shorewall/zones</filename>:<programlisting> #ZONE TYPE OPTION
|
|
||||||
fw firewall
|
|
||||||
net ipv4
|
|
||||||
loc ipv4
|
|
||||||
dmz ipv4</programlisting></para>
|
|
||||||
|
|
||||||
<para><filename>/etc/shorewall/interfaces</filename>:<programlisting> #ZONE INTERFACE BROADCAST OPTIONS
|
<para><filename>/etc/shorewall/interfaces</filename>:<programlisting> #ZONE INTERFACE BROADCAST OPTIONS
|
||||||
net ppp0
|
net ppp0
|
||||||
@ -152,8 +147,17 @@
|
|||||||
port rewritten to 3128. Hence, the web server running in the DMZ will be
|
port rewritten to 3128. Hence, the web server running in the DMZ will be
|
||||||
inaccessible from the web.</para>
|
inaccessible from the web.</para>
|
||||||
|
|
||||||
<para>The above problem can be corrected in a couple of ways. The first is
|
<para>The above problem can be corrected in several ways.</para>
|
||||||
to rewrite the DNAT rule (assume that the local zone is entirely within
|
|
||||||
|
<para>If you are running Shorewall version 4.1.4 or later, the preferred
|
||||||
|
way is to simply make the nested zones explicit:<programlisting> #ZONE TYPE OPTION
|
||||||
|
fw firewall
|
||||||
|
loc ipv4
|
||||||
|
net:loc ipv4
|
||||||
|
dmz ipv4</programlisting></para>
|
||||||
|
|
||||||
|
<para>When using other Shorewall versions, the first way is to rewrite the
|
||||||
|
DNAT rule (assume that the local zone is entirely within
|
||||||
192.168.2.0/23):<programlisting> #ACTION SOURCE DEST PROTO DEST
|
192.168.2.0/23):<programlisting> #ACTION SOURCE DEST PROTO DEST
|
||||||
# PORT(S)
|
# PORT(S)
|
||||||
ACCEPT net dmz tcp 80
|
ACCEPT net dmz tcp 80
|
||||||
|
@ -645,6 +645,10 @@
|
|||||||
affected. When <emphasis role="bold">all+</emphasis> is used,
|
affected. When <emphasis role="bold">all+</emphasis> is used,
|
||||||
intra-zone traffic is affected.</para>
|
intra-zone traffic is affected.</para>
|
||||||
|
|
||||||
|
<para>Beginning with Shorewall 4.1.4, the
|
||||||
|
<replaceable>zone</replaceable> should be omitted in DNAT-,
|
||||||
|
REDIRECT- and NONAT rules.</para>
|
||||||
|
|
||||||
<para>If the DEST <replaceable>zone</replaceable> is a bport zone,
|
<para>If the DEST <replaceable>zone</replaceable> is a bport zone,
|
||||||
then either:<orderedlist numeration="loweralpha">
|
then either:<orderedlist numeration="loweralpha">
|
||||||
<listitem>
|
<listitem>
|
||||||
|
Loading…
Reference in New Issue
Block a user