From 2f96bc518193a51d7c0b86195b381569be5b90b4 Mon Sep 17 00:00:00 2001 From: teastep Date: Mon, 14 Jan 2008 16:34:26 +0000 Subject: [PATCH] More work on DNAT/REDIRECT mess git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@8065 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb --- Shorewall-common/releasenotes.txt | 7 ++++- Shorewall-perl/Shorewall/Rules.pm | 43 +++++++++++++++++++++++++------ manpages/shorewall-nesting.xml | 20 +++++++++----- 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/Shorewall-common/releasenotes.txt b/Shorewall-common/releasenotes.txt index b4ea957f4..1935fe30a 100644 --- a/Shorewall-common/releasenotes.txt +++ b/Shorewall-common/releasenotes.txt @@ -60,7 +60,8 @@ Problems corrected in Shorewall 4.1.4. isn't able to recognize that fact. By changing the /etc/shorewall/zones file to make the parent/child - relationship explicit: + relationship explicit, Shorewall will now know that 'net' is a + sub-zone of 'loc'. /etc/shorewall/zones: @@ -70,6 +71,10 @@ Problems corrected in Shorewall 4.1.4. net:loc ipv4 dmz ipv4 + Be sure that there are no CONTINUE policies from net to another + zone and that IMPLICIT_CONTINUE=No (to prevent implicit CONTINUE + policies from 'net' to all other zones). + Other changes in Shorewall 4.1.4. 1) When installing on Cygwin, /etc/shorewall is no longer fully diff --git a/Shorewall-perl/Shorewall/Rules.pm b/Shorewall-perl/Shorewall/Rules.pm index b7bc27ba0..e66078ecc 100644 --- a/Shorewall-perl/Shorewall/Rules.pm +++ b/Shorewall-perl/Shorewall/Rules.pm @@ -1558,14 +1558,14 @@ sub generate_matrix() { my $exclusions = $zoneref->{exclusions}; my $frwd_ref = 0; my $chain = 0; - my $dnatref = $nat_table->{dnat_chain $zone}; + my $dnatref = $nat_table->{dnat_chain $zone} || {}; my $nested = $zoneref->{options}{nested}; if ( $complex ) { $frwd_ref = $filter_table->{"${zone}_frwd"}; - my $dnat_ref = ensure_chain 'nat' , dnat_chain( $zone ); + $dnatref = ensure_chain 'nat' , dnat_chain( $zone ); if ( @$exclusions ) { - insert_exclusions $dnat_ref, $exclusions if $dnat_ref->{referenced}; + insert_exclusions $dnatref, $exclusions if $dnatref->{referenced}; } } @@ -1574,12 +1574,39 @@ sub generate_matrix() { 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; + if ( $nested ) { + # + # This is a sub-zone. We need to determine if + # + # a) A parent zone defines DNAT/REDIRECT rules; and + # b) The current zone has a CONTINUE policy to some other zone. + # + # If a) but not b), then we must avoid sending packets from this + # zone through the DNAT/REDIRECT chain for the parent. + # + my $parenthasnat = 0; + + for my $parent ( @{$zoneref->{parents}} ) { + my $ref = $nat_table->{dnat_chain $parent} || {}; + $parenthasnat = 1, last if $ref->{referenced}; + } + + if ( $parenthasnat ) { + for my $zone1 ( all_zones ) { + if ( $filter_table->{"${zone}2${zone1}"}->{policy} eq 'CONTINUE' ) { + # + # This zone has a continue policy to another zone. We must + # send packets from this zone through the parent's DNAT/REDIRECT chain. + # + $nested = 0; + last; + } } + } else { + # + # No parent has DNAT so there is nothing to worry about. Don't bother to generate needless RETURN rules in the 'dnat' chain. + # + $nested = 0; } } # diff --git a/manpages/shorewall-nesting.xml b/manpages/shorewall-nesting.xml index 94b17906b..eac0d27ff 100644 --- a/manpages/shorewall-nesting.xml +++ b/manpages/shorewall-nesting.xml @@ -104,9 +104,8 @@ multiple ACCEPT+ rules. This technique also may be used when the ACTION is REDIRECT. - When using Shorewall versions before 4.1.4, care must be taken when - nesting occurs as a result of the use of wildcard interfaces (interface - names ends in '+'). + Care must be taken when nesting occurs as a result of the use of + wildcard interfaces (interface names ends in '+'). Here's an example. /etc/shorewall/zones: @@ -149,21 +148,28 @@ The above problem can be corrected in several ways. - If you are running Shorewall version 4.1.4 or later, the preferred - way is to simply make the nested zones explicit: #ZONE TYPE OPTION + The preferred way is to use the pppd option + to change the 'net' interface to something other than ppp0. That way, it + won't match ppp+. + + If you are running Shorewall version 4.1.4 or later, a second way is + to simply make the nested zones explicit: #ZONE TYPE OPTION fw firewall loc ipv4 net:loc ipv4 dmz ipv4 - When using other Shorewall versions, the first way is to rewrite the + If you take this approach, be sure to set IMPLICIT_CONTINUE=No in + shorewall.conf. + + When using other Shorewall versions, another way is to rewrite the DNAT rule (assume that the local zone is entirely within 192.168.2.0/23): #ACTION SOURCE DEST PROTO DEST # PORT(S) ACCEPT net dmz tcp 80 REDIRECT loc:192.168.2.0/23 3128 tcp 80 - The second way is to restrict the definition of the loc zone: + Another way is to restrict the definition of the loc zone: /etc/shorewall/interfaces: #ZONE INTERFACE BROADCAST OPTIONS net ppp0