diff --git a/Shorewall-core/lib.cli b/Shorewall-core/lib.cli index ac2be0a6d..c1075e5dc 100644 --- a/Shorewall-core/lib.cli +++ b/Shorewall-core/lib.cli @@ -3984,6 +3984,7 @@ shorewall_cli() { g_counters= g_loopback= g_compiled= + g_routestopped= VERBOSE= VERBOSITY=1 diff --git a/Shorewall/Perl/Shorewall/Compiler.pm b/Shorewall/Perl/Shorewall/Compiler.pm index 8239621e5..337650bd6 100644 --- a/Shorewall/Perl/Shorewall/Compiler.pm +++ b/Shorewall/Perl/Shorewall/Compiler.pm @@ -592,8 +592,8 @@ EOF # sub compiler { - my ( $scriptfilename, $directory, $verbosity, $timestamp , $debug, $chains , $log , $log_verbosity, $preview, $confess , $update , $annotate , $convert, $config_path, $shorewallrc , $shorewallrc1 , $directives, $inline, $tcrules ) = - ( '', '', -1, '', 0, '', '', -1, 0, 0, 0, 0, , 0 , '' , '/usr/share/shorewall/shorewallrc', '' , 0 , 0 , 0 ); + my ( $scriptfilename, $directory, $verbosity, $timestamp , $debug, $chains , $log , $log_verbosity, $preview, $confess , $update , $annotate , $convert, $config_path, $shorewallrc , $shorewallrc1 , $directives, $inline, $tcrules, $routestopped ) = + ( '', '', -1, '', 0, '', '', -1, 0, 0, 0, 0, , 0 , '' , '/usr/share/shorewall/shorewallrc', '' , 0 , 0 , 0 , 0 ); $export = 0; $test = 0; @@ -634,6 +634,7 @@ sub compiler { inline => { store => \$inline, validate=> \&validate_boolean } , directives => { store => \$directives, validate=> \&validate_boolean } , tcrules => { store => \$tcrules, validate=> \&validate_boolean } , + routestopped => { store => \$routestopped, validate=> \&validate_boolean } , config_path => { store => \$config_path } , shorewallrc => { store => \$shorewallrc } , shorewallrc1 => { store => \$shorewallrc1 } , @@ -737,7 +738,7 @@ sub compiler { # # Do all of the zone-independent stuff (mostly /proc) # - add_common_rules( $convert, $tcrules ); + add_common_rules( $convert, $tcrules , $routestopped ); # # More /proc # @@ -911,7 +912,7 @@ sub compiler { # S T O P _ F I R E W A L L # (Writes the stop_firewall() function to the compiled script) # - compile_stop_firewall( $test, $export , $have_arptables ); + compile_stop_firewall( $test, $export , $have_arptables, $routestopped ); # # U P D O W N # (Writes the updown() function to the compiled script) @@ -976,14 +977,15 @@ sub compiler { initialize_chain_table(0); if ( $debug ) { - compile_stop_firewall( $test, $export, $have_arptables ); + compile_stop_firewall( $test, $export, $have_arptables, $routestopped ); disable_script; } else { # - # compile_stop_firewall() also validates the routestopped file. Since we don't - # call that function during normal 'check', we must validate routestopped here. + # compile_stop_firewall() also validates the stoppedrules file. Since we don't + # call that function during normal 'check', we must validate stoppedrules here. # - process_routestopped unless process_stoppedrules; + convert_routestopped if $routestopped; + process_stoppedrules; } # # Report used/required capabilities diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm index a98d22759..ebfce1bd9 100644 --- a/Shorewall/Perl/Shorewall/Config.pm +++ b/Shorewall/Perl/Shorewall/Config.pm @@ -4928,8 +4928,10 @@ EOF } exit 0 unless ( $directives || - -f find_file 'blacklist' || - -f find_file 'tcrules' ); + -f find_file 'blacklist' || + -f find_file 'tcrules' || + -f find_file 'routestopped' + ); } } else { fatal_error "$fn does not exist"; diff --git a/Shorewall/Perl/Shorewall/Misc.pm b/Shorewall/Perl/Shorewall/Misc.pm index 42aa86f9a..31f3a6313 100644 --- a/Shorewall/Perl/Shorewall/Misc.pm +++ b/Shorewall/Perl/Shorewall/Misc.pm @@ -42,7 +42,7 @@ our @EXPORT = qw( process_tos setup_ecn add_common_rules setup_mac_lists - process_routestopped + convert_routestopped process_stoppedrules compile_stop_firewall generate_matrix @@ -220,7 +220,7 @@ sub remove_blacklist( $ ) { while ( read_a_line( EMBEDDED_ENABLED | EXPAND_VARIABLES ) ) { my ( $rule, $comment ) = split '#', $currentline, 2; - if ( $rule =~ /blacklist/ ) { + if ( $rule && $rule =~ /blacklist/ ) { $changed = 1; if ( $comment ) { @@ -418,13 +418,37 @@ EOF } } -sub process_routestopped() { +sub convert_routestopped() { if ( my $fn = open_file 'routestopped' ) { my ( @allhosts, %source, %dest , %notrack, @rule ); my $seq = 0; + my ( $stoppedrules, $fn1 ); + + if ( -f ( $fn1 = find_file( 'stoppedrules' ) ) ) { + open $stoppedrules, '>>', $fn1 or fatal_error "Unable to open $fn1: $!"; + } else { + open $stoppedrules, '>', $fn1 or fatal_error "Unable to open $fn1: $!"; + print $stoppedrules <<'EOF'; +# +# Shorewall version 5 - Stopped Rules File +# +# For information about entries in this file, type "man shorewall-stoppedrules" +# +# The manpage is also online at +# http://www.shorewall.net/manpages/shorewall-stoppedrules.html +# +# See http://shorewall.net/starting_and_stopping_shorewall.htm for additional +# information. +# +############################################################################### +#ACTION SOURCE DEST PROTO DEST SOURCE +# PORT(S) PORT(S) +EOF + } + first_entry "$doing $fn..."; while ( read_a_line ( NORMAL_READ ) ) { @@ -445,7 +469,9 @@ sub process_routestopped() { $seq++; - my $rule = do_proto( $proto, $ports, $sports, 0 ); + my $rule = "$proto\t$ports\t$sports"; + + $hosts = ALLIP if $hosts eq '-'; for my $host ( split /,/, $hosts ) { fatal_error "Ipsets not allowed with SAVE_IPSETS=Yes" if $host =~ /^!?\+/ && $config{SAVE_IPSETS}; @@ -486,13 +512,7 @@ sub process_routestopped() { my $chainref = $filter_table->{FORWARD}; for my $host ( split /,/, $hosts ) { - add_ijump( $chainref , - j => 'ACCEPT', - imatch_source_dev( $interface ) , - imatch_dest_dev( $interface ) , - imatch_source_net( $host ) , - imatch_dest_net( $host ) ); - clearrule; + print $stoppedrules "ACCEPT\t$interface:$host\t$interface:$host\n"; } } @@ -501,44 +521,41 @@ sub process_routestopped() { for my $host ( @allhosts ) { my ( $interface, $h, $seq ) = split /\|/, $host; - my $source = match_source_net $h; - my $dest = match_dest_net $h; - my $sourcei = match_source_dev $interface; - my $desti = match_dest_dev $interface; - my $rule = shift @rule; + my $rule = shift @rule; - add_rule $filter_table->{INPUT}, "$sourcei $source $rule -j ACCEPT", 1; - add_rule $filter_table->{OUTPUT}, "$desti $dest $rule -j ACCEPT", 1 unless $config{ADMINISABSENTMINDED}; + print $stoppedrules "ACCEPT\t$interface:$h\t\$FW\t$rule\n"; + print $stoppedrules "ACCEPT\t\$FW\t$interface:$h\t$rule\n" unless $config{ADMINISABSENTMINDED}; my $matched = 0; if ( $source{$host} ) { - add_rule $filter_table->{FORWARD}, "$sourcei $source $rule -j ACCEPT", 1; + print $stoppedrules "ACCEPT\t$interface:$h\t-\t$rule\n"; $matched = 1; } if ( $dest{$host} ) { - add_rule $filter_table->{FORWARD}, "$desti $dest $rule -j ACCEPT", 1; + print $stoppedrules "ACCEPT\t-\t$interface:$h\t$rule\n"; $matched = 1; } if ( $notrack{$host} ) { - add_rule $raw_table->{PREROUTING}, "$sourcei $source $rule -j NOTRACK", 1; - add_rule $raw_table->{OUTPUT}, "$desti $dest $rule -j NOTRACK", 1; + print $stoppedrules "NOTRACK\t$interface:$h\t-\t$rule\n"; + print $stoppedrules "NOTRACK\t\$FW\$interface:$h\t\$rule\n"; } unless ( $matched ) { for my $host1 ( @allhosts ) { unless ( $host eq $host1 ) { my ( $interface1, $h1 , $seq1 ) = split /\|/, $host1; - my $dest1 = match_dest_net $h1; - my $desti1 = match_dest_dev $interface1; - add_rule $filter_table->{FORWARD}, "$sourcei $desti1 $source $dest1 $rule -j ACCEPT", 1; - clearrule; + print $stoppedrules "ACCEPT\t$interface:$h\t$interface1:$h1\t$rule\n"; } } } } + + rename $fn, "$fn.bak"; + progress_message2 "Routestopped file $fn saved in $fn.bak"; + close $stoppedrules; } } @@ -634,8 +651,8 @@ sub process_stoppedrules() { sub setup_mss(); -sub add_common_rules ( $$ ) { - my ( $upgrade_blacklist, $upgrade_tcrules ) = @_; +sub add_common_rules ( $$$ ) { + my ( $upgrade_blacklist, $upgrade_tcrules , $upgrade_routestopped ) = @_; my $interface; my $chainref; my $target; @@ -806,7 +823,7 @@ sub add_common_rules ( $$ ) { run_user_exit1 'initdone'; if ( $upgrade_blacklist ) { - exit 0 unless convert_blacklist || $upgrade_tcrules; + exit 0 unless convert_blacklist || $upgrade_tcrules || $upgrade_routestopped; } $list = find_hosts_by_option 'nosmurfs'; @@ -1684,7 +1701,7 @@ sub add_output_jumps( $$$$$$$ ) { our @vservers; our %output_jump_added; - my $chain1 = rules_target firewall_zone , $zone; + my $chain1 = rules_target( firewall_zone , $zone ); my $chain1ref = $filter_table->{$chain1}; my $nextchain = dest_exclusion( $exclusions, $chain1 ); my $outputref; @@ -2266,8 +2283,8 @@ sub setup_mss( ) { # # Compile the stop_firewall() function # -sub compile_stop_firewall( $$$ ) { - my ( $test, $export, $have_arptables ) = @_; +sub compile_stop_firewall( $$$$ ) { + my ( $test, $export, $have_arptables, $routestopped ) = @_; my $input = $filter_table->{INPUT}; my $output = $filter_table->{OUTPUT}; @@ -2445,7 +2462,8 @@ EOF } } - process_routestopped unless process_stoppedrules; + convert_routestopped if $routestopped; + process_stoppedrules; if ( have_capability 'IFACE_MATCH' ) { add_ijump $input, j => 'ACCEPT', iface => '--dev-in --loopback'; diff --git a/Shorewall/Perl/Shorewall/Zones.pm b/Shorewall/Perl/Shorewall/Zones.pm index c00a5eef3..40cf78072 100644 --- a/Shorewall/Perl/Shorewall/Zones.pm +++ b/Shorewall/Perl/Shorewall/Zones.pm @@ -253,6 +253,7 @@ use constant { NO_UPDOWN => 1, our %validinterfaceoptions; our %prohibitunmanaged = ( + blacklist => 1, bridge => 1, destonly => 1, detectnets => 1, @@ -278,6 +279,7 @@ our %validhostoptions; our %validzoneoptions = ( mss => NUMERIC, nomark => NOTHING, + blacklist => NOTHING, dynamic_shared => NOTHING, strict => NOTHING, next => NOTHING, @@ -294,6 +296,7 @@ use constant { UNRESTRICTED => 1, NOFW => 2 , COMPLEX => 8, IN_OUT_ONLY => 16 }; # Hash of options that have their own key in the returned hash. # our %zonekey = ( mss => UNRESTRICTED | COMPLEX , + blacklist => NOFW, nomark => NOFW | IN_OUT_ONLY, dynamic_shared => IN_OUT_ONLY ); @@ -333,6 +336,7 @@ sub initialize( $$ ) { if ( $family == F_IPV4 ) { %validinterfaceoptions = (arp_filter => BINARY_IF_OPTION, arp_ignore => ENUM_IF_OPTION, + blacklist => SIMPLE_IF_OPTION + IF_OPTION_HOST, bridge => SIMPLE_IF_OPTION, destonly => SIMPLE_IF_OPTION + IF_OPTION_HOST, detectnets => OBSOLETE_IF_OPTION, @@ -361,6 +365,7 @@ sub initialize( $$ ) { wait => NUMERIC_IF_OPTION + IF_OPTION_WILDOK, ); %validhostoptions = ( + blacklist => 1, maclist => 1, nosmurfs => 1, routeback => 1, @@ -380,6 +385,7 @@ sub initialize( $$ ) { 64 => 'local' ); } else { %validinterfaceoptions = ( accept_ra => NUMERIC_IF_OPTION, + blacklist => SIMPLE_IF_OPTION + IF_OPTION_HOST, bridge => SIMPLE_IF_OPTION, destonly => SIMPLE_IF_OPTION + IF_OPTION_HOST, dhcp => SIMPLE_IF_OPTION, @@ -404,6 +410,7 @@ sub initialize( $$ ) { wait => NUMERIC_IF_OPTION + IF_OPTION_WILDOK, ); %validhostoptions = ( + blacklist => 1, maclist => 1, routeback => 1, tcpflags => 1, @@ -610,6 +617,21 @@ sub process_zone( \$ ) { } } + if ( $zoneref->{options}{in_out}{blacklist} ) { + warning_message q(The 'blacklist' option is no longer supported); + for ( qw/in out/ ) { + unless ( $zoneref->{options}{$_}{blacklist} ) { + $zoneref->{options}{$_}{blacklist} = 1; + } else { + warning_message( "Redundant 'blacklist' in " . uc( $_ ) . '_OPTIONS' ); + } + } + } else { + for ( qw/in out/ ) { + warning_message q(The 'blacklist' option is no longer supported), last if $zoneref->{options}{$_}{blacklist}; + } + } + return $zone; } @@ -1200,8 +1222,12 @@ sub process_interface( $$ ) { if ( $type == SIMPLE_IF_OPTION ) { fatal_error "Option $option does not take a value" if defined $value; - $options{$option} = 1; - $hostoptions{$option} = 1 if $hostopt; + if ( $option eq 'blacklist' ) { + warning_message "The 'blacklist' interface option is no longer supported"; + } else { + $options{$option} = 1; + $hostoptions{$option} = 1 if $hostopt; + } } elsif ( $type == BINARY_IF_OPTION ) { $value = 1 unless defined $value; fatal_error "Option value for '$option' must be 0 or 1" unless ( $value eq '0' || $value eq '1' ); @@ -2038,6 +2064,8 @@ sub process_host( ) { $ipsec = $interfaceref->{ipsec} = 1; } elsif ( $option eq 'norfc1918' ) { warning_message "The 'norfc1918' host option is no longer supported" + } elsif ( $option eq 'blacklist' ) { + warning_message "The 'blacklist' option is no longer supported"; } elsif ( $option =~ /^mss=(\d+)$/ ) { fatal_error "Invalid mss ($1)" unless $1 >= 500; require_capability 'TCPMSS_TARGET', $option, 's'; diff --git a/Shorewall/Perl/compiler.pl b/Shorewall/Perl/compiler.pl index 94dd2b8d5..d682c8749 100755 --- a/Shorewall/Perl/compiler.pl +++ b/Shorewall/Perl/compiler.pl @@ -42,6 +42,7 @@ # --config_path= # Search path for config files # --inline # Update alternative column specifications # --tcrules # Create mangle from tcrules +# --routestopped # Create stoppedrules from routestopped # use strict; use FindBin; @@ -77,6 +78,7 @@ usage: compiler.pl [