From 4322d7b2af09d0e569d1de82909ac75e17c8d9eb Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Wed, 18 Aug 2010 16:10:58 -0700 Subject: [PATCH] Zone exclusion Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Rules.pm | 56 +++++++++++++++++-------- Shorewall/releasenotes.txt | 9 +++++ manpages/shorewall-exclusion.xml | 65 +++++++++++++++++++++++++++--- manpages/shorewall-rules.xml | 17 ++++++-- manpages6/shorewall6-exclusion.xml | 45 +++++++++++++++++++++ manpages6/shorewall6-rules.xml | 10 +++-- 6 files changed, 173 insertions(+), 29 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index 63b3ac611..69c900914 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -1541,11 +1541,14 @@ sub process_rule ( ) { my $wild = 0; my $thisline = $currentline; my $action = isolate_basic_target $target; + my $fw = firewall_zone; my $any; my $rest; my @source; my @dest; - + my $exclude; + my %exclude; + # # Section Names are optional so once we get to an actual rule, we need to be sure that # we close off any missing sections. @@ -1564,30 +1567,41 @@ sub process_rule ( ) { $any = ( $source =~ s/^any/all/ ); - if ( $source =~ /^(all[-+]*)(:.*)?/ ) { + if ( $source =~ /^(all[-+]*)(![^:]+)?(:.*)?/ ) { $source = $1; - $rest = $2; + $exclude = $2; + $rest = $3; - my $includefw = 1; + if ( defined $exclude ) { + $exclude =~ s/!//; + fatal_error "Invalid exclusion list (!$exclude)" if $exclude =~ /^,|!|,,|,$/; + for ( split /,/, $exclude ) { + fatal_error "Unknown zone ($_)" unless defined_zone $_; + $exclude{$_} = 1; + } + } unless ( $source eq 'all' ) { if ( $source eq 'all+' ) { $intrazone = 1; } elsif ( ( $source eq 'all+-' ) || ( $source eq 'all-+' ) ) { $intrazone = 1; - $includefw = 0; + $exclude{$fw} = 1; } elsif ( $source eq 'all-' ) { - $includefw = 0; + $exclude{$fw} = 1; } else { fatal_error "Invalid SOURCE ($source)"; } } - @source = $any ? all_parent_zones : non_firewall_zones; + @source = grep ! $exclude{$_}, $any ? all_parent_zones : non_firewall_zones; - unshift @source, firewall_zone if $includefw; + unshift @source, $fw unless $exclude{$fw}; $wild = 1; + + %exclude = (); + } elsif ( $source =~ /^([^:]+,[^:]+)(:.*)?$/ ) { $source = $1; $rest = $2; @@ -1609,28 +1623,36 @@ sub process_rule ( ) { $any = ( $dest =~ s/^any/all/ ); - if ( $dest =~ /^(all[-+]*)(:.*)?/ ) { - $dest = $1; - $rest = $2; + if ( $dest =~ /^(all[-+]*)(![^:]+)?(:.*)?/ ) { + $dest = $1; + $exclude = $2; + $rest = $3; - my $includefw = 1; + if ( defined $exclude ) { + $exclude =~ s/!//; + fatal_error "Invalid exclusion list (!$exclude)" if $exclude =~ /^,|!|,,|,$/; + for ( split /,/, $exclude ) { + fatal_error "Unknown zone ($_)" unless defined_zone $_; + $exclude{$_} = 1; + } + } unless ( $dest eq 'all' ) { if ( $dest eq 'all+' ) { $intrazone = 1; } elsif ( ( $dest eq 'all+-' ) || ( $dest eq 'all-+' ) ) { $intrazone = 1; - $includefw = 0; + $exclude{$fw} = 1; } elsif ( $dest eq 'all-' ) { - $includefw = 0; + $exclude{$fw} = 1; } else { fatal_error "Invalid DEST ($dest)"; } } - @dest = $any ? all_parent_zones : non_firewall_zones; + @dest = grep ! $exclude{$_}, $any ? all_parent_zones : non_firewall_zones; - unshift @dest, firewall_zone if $includefw; + unshift @dest, $fw unless $exclude{$fw}; $wild = 1; } elsif ( $dest =~ /^([^:]+,[^:]+)(:.*)?$/ ) { $dest = $1; @@ -1654,7 +1676,7 @@ sub process_rule ( ) { for $dest ( @dest ) { my $sourcezone = (split( /:/, $source, 2 ) )[0]; my $destzone = (split( /:/, $dest, 2 ) )[0]; - $destzone = $action =~ /^REDIRECT/ ? firewall_zone : '' unless defined_zone $destzone; + $destzone = $action =~ /^REDIRECT/ ? $fw : '' unless defined_zone $destzone; if ( ! $wild || $intrazone || ( $sourcezone ne $destzone ) ) { process_rule1 $target, $source, $dest , $proto, $ports, $sports, $origdest, $ratelimit, $user, $mark, $connlimit, $time, $wild; } diff --git a/Shorewall/releasenotes.txt b/Shorewall/releasenotes.txt index d302103e2..52634f26d 100644 --- a/Shorewall/releasenotes.txt +++ b/Shorewall/releasenotes.txt @@ -45,6 +45,15 @@ None. fw,dmz:90.90.191.120/29 all:+blacklist + The 'all' and 'any' keywords now support exclusion in the form of a + comma-separated list of excluded zones. + + Examples: + + all!fw (same as all-). + any+!dmz,loc (All zones except 'dmz' and 'loc' and + include intra-zone rules). + ---------------------------------------------------------------------------- I V. R E L E A S E 4 . 4 H I G H L I G H T S ---------------------------------------------------------------------------- diff --git a/manpages/shorewall-exclusion.xml b/manpages/shorewall-exclusion.xml index b4a95216c..3b860a72d 100644 --- a/manpages/shorewall-exclusion.xml +++ b/manpages/shorewall-exclusion.xml @@ -20,17 +20,22 @@ address-or-range[,address-or-range] + + + zone-name[,zone-name] + Description - Exclusion is used when you wish to exclude one or more addresses - from a definition. An exclaimation point is followed by a comma-separated - list of addresses. The addresses may be single host addresses (e.g., - 192.168.1.4) or they may be network addresses in CIDR format (e.g., - 192.168.1.0/24). If your kernel and iptables include iprange support, you - may also specify ranges of ip addresses of the form + The first form of exclusion is used when you wish to exclude one or + more addresses from a definition. An exclaimation point is followed by a + comma-separated list of addresses. The addresses may be single host + addresses (e.g., 192.168.1.4) or they may be network addresses in CIDR + format (e.g., 192.168.1.0/24). If your kernel and iptables include iprange + support, you may also specify ranges of ip addresses of the form lowaddress-highaddress No embedded whitespace is allowed. @@ -39,6 +44,46 @@ ranges. In that case, the final list of address is formed by taking the first list and then removing the addresses defined in the exclusion. + + Beginning in Shorewall 4.4.13, the second form of exclusion is + allowed after all and any in the SOURCE and DEST columns of + /etc/shorewall/rules. It allows you to omit arbitrary zones from the list + generated by those key words. + + + If you omit a sub-zone and there is an explicit or explicit + CONTINUE policy, a connection to/from that zone can still be matched by + the rule generated for a parent zone. + + For example: + +
+ /etc/shorewall/zones: + + #ZONE TYPE +z1 ip +z2:z1 ip +... + + /etc/shorewall/policy: + + #SOURCE DEST POLICY +z1 net CONTINUE +z2 net REJECT + + /etc/shorewall/rules: + + #ACTION SOURCE DEST PROTO DEST +# PORT(S) +ACCEPT all!z2 net tcp 22 + + In this case, SSH connections from z2 to net will + be accepted by the generated z1 to + net ACCEPT rule. +
+
@@ -79,6 +124,14 @@ 192.168.1.0/24!192.168.1.3,192.168.1.9 + + + Example 5 - All parent zones except loc + + + any!loc + + diff --git a/manpages/shorewall-rules.xml b/manpages/shorewall-rules.xml index 0fc2dc9bb..03ed5326c 100644 --- a/manpages/shorewall-rules.xml +++ b/manpages/shorewall-rules.xml @@ -533,8 +533,10 @@ used either in the SOURCE or DEST column intra-zone traffic is not affected. When all+[-] is "used, intra-zone traffic is - affected. + role="bold">-] is "used, intra-zone traffic is affected. + Beginning with Shorewall 4.4.13, exclusion is supported -- see see + shorewall-exclusion(5). Except when all[+][-] or @@ -546,6 +548,13 @@ mac addresses must begin with "~" and must use "-" as a separator. + The above restriction on all[+][-] and + any[+][-] is + removed in Shorewall-4.4.13. + any is equivalent to all when there are no nested zones. When there are nested zones, any @@ -667,7 +676,9 @@ the SOURCE or DEST column intra-zone traffic is not affected. When all+ is used, - intra-zone traffic is affected. + intra-zone traffic is affected. Beginning with Shorewall 4.4.13, + exclusion is supported -- see see shorewall-exclusion(5). any is equivalent to all when there are no nested zones. diff --git a/manpages6/shorewall6-exclusion.xml b/manpages6/shorewall6-exclusion.xml index d8421332d..ee70a2794 100644 --- a/manpages6/shorewall6-exclusion.xml +++ b/manpages6/shorewall6-exclusion.xml @@ -20,6 +20,11 @@ address-or-range[,address-or-range] + + + zone-name[,zone-name] + @@ -39,6 +44,46 @@ ranges. In that case, the final list of address is formed by taking the first list and then removing the addresses defined in the exclusion. + + Beginning in Shorewall 4.4.13, the second form of exclusion is + allowed after all and any in the SOURCE and DEST columns of + /etc/shorewall/rules. It allows you to omit arbitrary zones from the list + generated by those key words. + + + If you omit a sub-zone and there is an explicit or explicit + CONTINUE policy, a connection to/from that zone can still be matched by + the rule generated for a parent zone. + + For example: + +
+ /etc/shorewall6/zones: + + #ZONE TYPE +z1 ip +z2:z1 ip +... + + /etc/shorewall6/policy: + + #SOURCE DEST POLICY +z1 net CONTINUE +z2 net REJECT + + /etc/shorewall6/rules: + + #ACTION SOURCE DEST PROTO DEST +# PORT(S) +ACCEPT all!z2 net tcp 22 + + In this case, SSH connections from z2 to net will + be accepted by the generated z1 to + net ACCEPT rule. +
+
diff --git a/manpages6/shorewall6-rules.xml b/manpages6/shorewall6-rules.xml index 6ca7a6fdc..fd14cd719 100644 --- a/manpages6/shorewall6-rules.xml +++ b/manpages6/shorewall6-rules.xml @@ -393,8 +393,10 @@ used either in the SOURCE or DEST column intra-zone traffic is not affected. When all+[-] is "used, intra-zone traffic is - affected. + role="bold">-] is "used, intra-zone traffic is affected. + Beginning with Shorewall 4.4.13, exclusion is supported -- see see + shorewall6-exclusion(5). Except when all[+][-] or @@ -527,7 +529,9 @@ url="shorewall-zones.html">shorewall-zones (5). Ths zone-list may be optionally followed by "+" to indicate that the rule is to apply to intra-zone traffic as - well as inter-zone traffic. + well as inter-zone traffic. Beginning with Shorewall-4.4.13, + exclusion is supported -- see see shorewall6-exclusion(5). When none is used either in the SOURCE or