From a141478319ca250bfeca97c28de9903761568f59 Mon Sep 17 00:00:00 2001 From: teastep Date: Fri, 28 Mar 2008 00:05:25 +0000 Subject: [PATCH] Resolve RFC 1918 Mess git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@8372 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb --- Shorewall-common/changelog.txt | 2 +- Shorewall-common/macro.Rfc1918 | 14 +++++ Shorewall-common/macro.template | 19 +++--- Shorewall-common/releasenotes.txt | 31 ++++++---- Shorewall-common/shorewall.conf | 2 + Shorewall-perl/Shorewall/Actions.pm | 90 +++++++++-------------------- Shorewall-perl/Shorewall/Chains.pm | 4 -- Shorewall-perl/Shorewall/Config.pm | 44 ++------------ Shorewall-perl/Shorewall/Rules.pm | 42 +++++++++++--- 9 files changed, 115 insertions(+), 133 deletions(-) create mode 100644 Shorewall-common/macro.Rfc1918 diff --git a/Shorewall-common/changelog.txt b/Shorewall-common/changelog.txt index 45cc3edcb..420d00c13 100644 --- a/Shorewall-common/changelog.txt +++ b/Shorewall-common/changelog.txt @@ -16,7 +16,7 @@ Changes in 4.1.7 8) Fix ":" parsing errors. -9) Add macros for RFC 1918 filtering. +9) Add ORIGINAL DEST column to macros. Changes in 4.1.6 diff --git a/Shorewall-common/macro.Rfc1918 b/Shorewall-common/macro.Rfc1918 new file mode 100644 index 000000000..5cb8992f8 --- /dev/null +++ b/Shorewall-common/macro.Rfc1918 @@ -0,0 +1,14 @@ +# +# Shorewall version 4 - Macro Template +# +# /usr/share/shorewall/macro.Rfc1918 +# +# This macro handles pkts with a SOURCE or ORIGINAL DEST address reserved by RFC 1918 +############################################################################################# +#ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE USER/ +# PORT(S) PORT(S) DEST LIMIT GROUP +FORMAT 2 +PARAM SOURCE:10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 \ + DEST - - - - - - +PARAM SOURCE DEST - - - 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 +#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall-common/macro.template b/Shorewall-common/macro.template index 729087b46..ae357d1bd 100644 --- a/Shorewall-common/macro.template +++ b/Shorewall-common/macro.template @@ -264,6 +264,10 @@ # Otherwise, a separate rule will be generated for each # port. # +# ORIGINAL Original destination IP address. Must be omitted ( +# DEST or '-') if the macro is to be used from within +# an action. See 'man shorewall-rules'. +# # RATE LIMIT You may rate-limit the rule by placing a value in # this colume: # @@ -304,8 +308,8 @@ # # /etc/shorewall/macro.FwdFTP: # -# #ACTION SOURCE DEST PROTO DEST SOURCE RATE USER/ -# # PORT(S) PORT(S) LIMIT GROUP +# #ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE USER/ +# # PORT(S) PORT(S) DEST LIMIT GROUP # DNAT - - tcp 21 # # /etc/shorewall/rules: @@ -345,7 +349,6 @@ # the rules file is appended with a ":" # separator. # -# # Example: ############################################### # #ACTION SOURCE DEST PROTO DEST # # PORT(S) @@ -356,8 +359,10 @@ # Remaining Any value in the rules file REPLACES the value # columns given in the macro file. # -# -############################################################################### -#ACTION SOURCE DEST PROTO DEST SOURCE RATE USER/ -# PORT(S) PORT(S) LIMIT GROUP +####################################################################################################### +# DO NOT REMOVE THE FOLLOWING LINE +FORMAT 2 +####################################################################################################### +#ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE USER/ ORIGINAL +# PORT(S) PORT(S) DEST LIMIT GROUP DEST #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall-common/releasenotes.txt b/Shorewall-common/releasenotes.txt index f7be7ee23..671248477 100644 --- a/Shorewall-common/releasenotes.txt +++ b/Shorewall-common/releasenotes.txt @@ -71,6 +71,10 @@ Migration Issues. 5) The value of IMPLICIT_CONTINUE in shorewall.conf (and samples) has been changed from Yes to No. +6) The 'norfc1918' option is deprecated. Use explicit rules instead. + Note that there is a new 'Rfc1918' option that acts on addresses + reserved by RFC 1918. + Problems corrected in Shorewall-perl 4.1.7. 1) Perl run-time errors occurred if an unknown service was named in @@ -188,22 +192,29 @@ New Features in 4.1.7. This allows for another application running on your firewall to take over the mangle table and use it for it's own purposes. -4) Shorewall-perl implements four new built-in actions that deal with - RFC 1918 addresses. These actions should be used in place of +4) Shorewall-perl now supports an ORIGINAL DEST column in macro files. + The column must be left empty if the macro is to be used in the + body of an action. + + Note that the position of the ORIGINAL DEST column is different + from its position in the /etc/shorewall/rules file. Beware! + +5) Shorewall-perl implements a new Rfc1918 macro that deals with + RFC 1918 addresses. This macro should be used in place of the 'norfc1918' interface option which is deprecated. - drop1918src - Drops packets with an RFC 1918 source address. - drop1918dst - Drops packets with an RFC 1918 original - destination IP address. - rej1918dst - Rejects packets with an RFC 1918 source address. - rej1918dst - Rejectss packets with an RFC 1918 original - destination IP address. + The macro body is: + + #ACTION SOURCE DEST PROTO DEST SOURCE RATE USER/ ORIGINAL + # PORT(S) PORT(S) LIMIT GROUP DEST + PARAM SOURCE:10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 \ + DEST - - - - - - + PARAM SOURCE DEST - - - - - 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 The 'norfc1918' option on the interface associated with zone 'z' and with RFC1018_STRICT=Yes is equivalent to: - drop1918src z all - drop1918dst z all + Rfc1918(DROP) z all New Features in Shorewall 4.1. diff --git a/Shorewall-common/shorewall.conf b/Shorewall-common/shorewall.conf index 036afdc81..6ebe8f624 100644 --- a/Shorewall-common/shorewall.conf +++ b/Shorewall-common/shorewall.conf @@ -183,6 +183,8 @@ AUTO_COMMENT=Yes MANGLE_ENABLED=Yes +NEW_MACRO_LAYOUT=No + ############################################################################### # P A C K E T D I S P O S I T I O N ############################################################################### diff --git a/Shorewall-perl/Shorewall/Actions.pm b/Shorewall-perl/Shorewall/Actions.pm index 5d39c1dd5..b428a9185 100644 --- a/Shorewall-perl/Shorewall/Actions.pm +++ b/Shorewall-perl/Shorewall/Actions.pm @@ -53,6 +53,7 @@ our @EXPORT = qw( merge_levels %actions %macros + %macro_commands ); our @EXPORT_OK = qw( initialize ); our $VERSION = 4.1.1; @@ -82,6 +83,11 @@ our %logactionchains; our %macros; +# +# Commands that can be embedded in a macro file and how many total tokens on the line (0 => unlimited). +# +our %macro_commands = ( COMMENT => 0, FORMAT => 2 ); + # # Initialize globals -- we take this novel approach to globals initialization to allow # the compiler to run multiple times in the same process. The @@ -401,9 +407,9 @@ sub process_macro1 ( $$ ) { push_open( $macrofile ); while ( read_a_line ) { - my ( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $mrate, $muser ) = split_line1 1, 8, 'macro file'; + my ( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $morigdest, $mrate, $muser ) = split_line1 1, 9, 'macro file', \%macro_commands; - next if $mtarget eq 'COMMENT'; + next if $mtarget eq 'COMMENT' || $mtarget eq 'FORMAT'; $mtarget =~ s/:.*$//; @@ -576,6 +582,8 @@ sub process_macro3( $$$$$$$$$$$ ) { my $nocomment = no_comment; + my $format = 1; + macro_comment $macro; my $fn = $macros{$macro}; @@ -586,18 +594,34 @@ sub process_macro3( $$$$$$$$$$$ ) { while ( read_a_line ) { - my ( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $mrate, $muser ) = split_line1 1, 8, 'macro file'; + my ( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $morigdest, $mrate, $muser ); + + if ( $format == 1 ) { + ( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $mrate, $muser, $morigdest ) = split_line1 1, 9, 'macro file', \%macro_commands; + } else { + ( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $morigdest, $mrate, $muser ) = split_line1 1, 9, 'macro file', \%macro_commands; + } if ( $mtarget eq 'COMMENT' ) { process_comment unless $nocomment; next; } + if ( $mtarget eq 'FORMAT' ) { + fatal_error "Invalid FORMAT ($msource)" unless $msource =~ /^[12]$/; + $format = $msource; + next; + } + + fatal_error "Invalid macro file entry (too many columns)" if $morigdest ne '-' && $format == 1; + if ( $mtarget =~ /^PARAM:?/ ) { fatal_error 'PARAM requires that a parameter be supplied in macro invocation' unless $param; $mtarget = substitute_param $param, $mtarget; } + fatal_error "Macros used within Actions may not specify an ORIGINAL DEST " if $morigdest ne '-'; + if ( $msource ) { if ( ( $msource eq '-' ) || ( $msource eq 'SOURCE' ) ) { $msource = $source || ''; @@ -815,62 +839,6 @@ sub process_actions3 () { add_rule $chainref, '-j ACCEPT'; } - sub drop1918src( $$$ ) { - my ($chainref, $level, $tag) = @_; - - if ( $level ne '' ) { - log_rule_limit $level, $chainref, 'dropRFC1918src', 'DROP', '', $tag, 'add', '-s 10.0.0.0/8 '; - log_rule_limit $level, $chainref, 'dropRFC1918src', 'DROP', '', $tag, 'add', '-s 172.16.0.0/12 '; - log_rule_limit $level, $chainref, 'dropRFC1918src', 'DROP', '', $tag, 'add', '-s 192.168.0.0/16 '; - } - - add_rule $chainref, '-s 10.0.0.0/8 -j DROP'; - add_rule $chainref, '-s 172.16.0.0/12 -j DROP'; - add_rule $chainref, '-s 192.168.0.0/16 -j DROP'; - } - - sub drop1918dst( $$$ ) { - my ($chainref, $level, $tag) = @_; - - if ( $level ne '' ) { - log_rule_limit $level, $chainref, 'drop1918src', 'DROP', '', $tag, 'add', '-m conntrack --ctorigdst 10.0.0.0/8 '; - log_rule_limit $level, $chainref, 'drop1918src', 'DROP', '', $tag, 'add', '-m conntrack --ctorigdst 172.16.0.0/12 '; - log_rule_limit $level, $chainref, 'drop1918src', 'DROP', '', $tag, 'add', '-m conntrack --ctorigdst 192.168.0.0/16 '; - } - - add_rule $chainref, '-m conntrack --ctorigdst 10.0.0.0/8 -j DROP'; - add_rule $chainref, '-m conntrack --ctorigdst 172.16.0.0/12 -j DROP'; - add_rule $chainref, '-m conntrack --ctorigdst 192.168.0.0/16 -j DROP'; - } - - sub rej1918src( $$$ ) { - my ($chainref, $level, $tag) = @_; - - if ( $level ne '' ) { - log_rule_limit $level, $chainref, 'rej1918src', 'REJECT', '', $tag, 'add', '-s 10.0.0.0/8 '; - log_rule_limit $level, $chainref, 'rej1918src', 'REJECT', '', $tag, 'add', '-s 172.16.0.0/12 '; - log_rule_limit $level, $chainref, 'rej1918src', 'REJECT', '', $tag, 'add', '-s 192.168.0.0/16 '; - } - - add_rule $chainref, '-s 10.0.0.0/8 -j reject'; - add_rule $chainref, '-s 172.16.0.0/12 -j reject'; - add_rule $chainref, '-s 192.168.0.0/16 -j reject'; - } - - sub rej1918dst( $$$ ) { - my ($chainref, $level, $tag) = @_; - - if ( $level ne '' ) { - log_rule_limit $level, $chainref, 'rej1918src', 'REJECT', '', $tag, 'add', '-m conntrack --ctorigdst 10.0.0.0/8 '; - log_rule_limit $level, $chainref, 'rej1918src', 'REJECT', '', $tag, 'add', '-m conntrack --ctorigdst 172.16.0.0/12 '; - log_rule_limit $level, $chainref, 'rej1918src', 'REJECT', '', $tag, 'add', '-m conntrack --ctorigdst 192.168.0.0/16 '; - } - - add_rule $chainref, '-m conntrack --ctorigdst 10.0.0.0/8 -j reject'; - add_rule $chainref, '-m conntrack --ctorigdst 172.16.0.0/12 -j reject'; - add_rule $chainref, '-m conntrack --ctorigdst 192.168.0.0/16 -j reject'; - } - my %builtinops = ( 'dropBcast' => \&dropBcast, 'allowBcast' => \&allowBcast, 'dropNotSyn' => \&dropNotSyn, @@ -879,10 +847,6 @@ sub process_actions3 () { 'allowInvalid' => \&allowInvalid, 'allowinUPnP' => \&allowinUPnP, 'forwardUPnP' => \&forwardUPnP, - 'drop1918src' => \&drop1918src, - 'drop1918dst' => \&drop1918dst, - 'rej1918src' => \&drop1918src, - 'rej1918dst' => \&drop1918dst, 'Limit' => \&Limit, ); for my $wholeaction ( keys %usedactions ) { diff --git a/Shorewall-perl/Shorewall/Chains.pm b/Shorewall-perl/Shorewall/Chains.pm index ab5ac234a..33cb1fdf8 100644 --- a/Shorewall-perl/Shorewall/Chains.pm +++ b/Shorewall-perl/Shorewall/Chains.pm @@ -309,10 +309,6 @@ sub initialize() { 'allowInvalid' => BUILTIN + ACTION, 'allowinUPnP' => BUILTIN + ACTION, 'forwardUPnP' => BUILTIN + ACTION, - 'drop1918src' => BUILTIN + ACTION, - 'drop1918dst' => BUILTIN + ACTION, - 'rej1918src' => BUILTIN + ACTION, - 'rej1918dst' => BUILTIN + ACTION, 'Limit' => BUILTIN + ACTION, ); # diff --git a/Shorewall-perl/Shorewall/Config.pm b/Shorewall-perl/Shorewall/Config.pm index 01fcd1e4f..f6a9d4245 100644 --- a/Shorewall-perl/Shorewall/Config.pm +++ b/Shorewall-perl/Shorewall/Config.pm @@ -80,7 +80,6 @@ our %EXPORT_TAGS = ( internal => [ qw( create_temp_object split_list split_line split_line1 - split_line2 first_entry open_file close_file @@ -920,52 +919,19 @@ sub split_line( $$$ ) { } # -# Version of 'split_line' that handles COMMENT lines +# Version of 'split_line' used on files with exceptions # -sub split_line1( $$$ ) { - my ( $mincolumns, $maxcolumns, $description ) = @_; +sub split_line1( $$$;$ ) { + my ( $mincolumns, $maxcolumns, $description, $nopad) = @_; fatal_error "Shorewall Configuration file entries may not contain double quotes, single back quotes or backslashes" if $currentline =~ /["`\\]/; my @line = split( ' ', $currentline ); - return @line if $line[0] eq 'COMMENT'; - - fatal_error "Shorewall Configuration file entries may not contain single quotes" if $currentline =~ /'/; - fatal_error "Non-ASCII gunk in file" if $currentline =~ /[^\s[:print:]]/; - - my $line = @line; - - fatal_error "Invalid $description entry (too many columns)" if $line > $maxcolumns; - - $line-- while $line > 0 && $line[$line-1] eq '-'; - - fatal_error "Invalid $description entry (too few columns)" if $line < $mincolumns; - - push @line, '-' while @line < $maxcolumns; - - @line; -} - -# -# When splitting a line in the rules file, don't pad out the columns with '-' if the first column contains one of these -# - -my %no_pad = ( COMMENT => 0, - SECTION => 2 ); - -# -# Version of 'split_line' used on rules file entries -# -sub split_line2( $$$ ) { - my ( $mincolumns, $maxcolumns, $description ) = @_; - - fatal_error "Shorewall Configuration file entries may not contain double quotes, single back quotes or backslashes" if $currentline =~ /["`\\]/; - - my @line = split( ' ', $currentline ); + $nopad = { COMMENT => 0 } unless $nopad; my $first = $line[0]; - my $columns = $no_pad{$first}; + my $columns = $nopad->{$first}; if ( defined $columns ) { if ( $columns ) { diff --git a/Shorewall-perl/Shorewall/Rules.pm b/Shorewall-perl/Shorewall/Rules.pm index c153191d0..6fbed1b22 100644 --- a/Shorewall-perl/Shorewall/Rules.pm +++ b/Shorewall-perl/Shorewall/Rules.pm @@ -60,6 +60,14 @@ our $sectioned; our $macro_nest_level; our $current_param; our @param_stack; + +# +# When splitting a line in the rules file, don't pad out the columns with '-' if the first column contains one of these +# + +my %rules_commands = ( COMMENT => 0, + SECTION => 2 ); + # # Initialize globals -- we take this novel approach to globals initialization to allow # the compiler to run multiple times in the same process. The @@ -215,7 +223,7 @@ sub setup_rfc1918_filteration( $ ) { my $rfc1918ref = new_standard_chain 'rfc1918'; my $chainref = $norfc1918ref; - warning_message q(The 'norfc1918' option is deprecated in favor of the RFC1918-oriented built-in actions); + warning_message q(The 'norfc1918' option is deprecated); log_rule $config{RFC1918_LOG_LEVEL} , $rfc1918ref , 'DROP' , ''; @@ -834,6 +842,8 @@ sub process_macro ( $$$$$$$$$$$$$ ) { my $nocomment = no_comment; + my $format = 1; + macro_comment $macro; my $macrofile = $macros{$macro}; @@ -844,13 +854,27 @@ sub process_macro ( $$$$$$$$$$$$$ ) { while ( read_a_line ) { - my ( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $mrate, $muser ) = split_line1 1, 8, 'macro file'; + my ( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $morigdest, $mrate, $muser ); + + if ( $format == 1 ) { + ( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $mrate, $muser, $morigdest ) = split_line1 1, 9, 'macro file', \%macro_commands; + } else { + ( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $morigdest, $mrate, $muser ) = split_line1 1, 9, 'macro file', \%macro_commands; + } if ( $mtarget eq 'COMMENT' ) { process_comment unless $nocomment; next; } + if ( $mtarget eq 'FORMAT' ) { + fatal_error "Invalid FORMAT ($msource)" unless $msource =~ /^[12]$/; + $format = $msource; + next; + } + + fatal_error "Invalid macro file entry (too many columns)" if $morigdest ne '-' && $format == 1; + $mtarget = merge_levels $target, $mtarget; if ( $mtarget =~ /^PARAM(:.*)?$/ ) { @@ -896,12 +920,12 @@ sub process_macro ( $$$$$$$$$$$$$ ) { $mtarget, $msource, $mdest, - merge_macro_column( $mproto, $proto ) , - merge_macro_column( $mports, $ports ) , - merge_macro_column( $msports, $sports ) , - $origdest, - merge_macro_column( $mrate, $rate ) , - merge_macro_column( $muser, $user ) , + merge_macro_column( $mproto, $proto ) , + merge_macro_column( $mports, $ports ) , + merge_macro_column( $msports, $sports ) , + merge_macro_column( $morigdest, $origdest ) , + merge_macro_column( $mrate, $rate ) , + merge_macro_column( $muser, $user ) , $mark, $wildcard ); @@ -1397,7 +1421,7 @@ sub process_rules() { while ( read_a_line ) { - my ( $target, $source, $dest, $proto, $ports, $sports, $origdest, $ratelimit, $user, $mark ) = split_line2 1, 10, 'rules file'; + my ( $target, $source, $dest, $proto, $ports, $sports, $origdest, $ratelimit, $user, $mark ) = split_line1 1, 10, 'rules file', \%rules_commands; if ( $target eq 'COMMENT' ) { process_comment;