diff --git a/Samples6/three-interfaces/shorewall6.conf b/Samples6/three-interfaces/shorewall6.conf index 71bfa5764..6997903a0 100644 --- a/Samples6/three-interfaces/shorewall6.conf +++ b/Samples6/three-interfaces/shorewall6.conf @@ -50,6 +50,8 @@ BLACKLIST_LOGLEVEL= TCP_FLAGS_LOG_LEVEL=info +SMURF_LOG_LEVEL=info + ############################################################################### # L O C A T I O N O F F I L E S A N D D I R E C T O R I E S ############################################################################### diff --git a/Samples6/two-interfaces/shorewall6.conf b/Samples6/two-interfaces/shorewall6.conf index 71bfa5764..6997903a0 100644 --- a/Samples6/two-interfaces/shorewall6.conf +++ b/Samples6/two-interfaces/shorewall6.conf @@ -50,6 +50,8 @@ BLACKLIST_LOGLEVEL= TCP_FLAGS_LOG_LEVEL=info +SMURF_LOG_LEVEL=info + ############################################################################### # L O C A T I O N O F F I L E S A N D D I R E C T O R I E S ############################################################################### diff --git a/Shorewall-common/changelog.txt b/Shorewall-common/changelog.txt index 297f4eb16..7af3e0568 100644 --- a/Shorewall-common/changelog.txt +++ b/Shorewall-common/changelog.txt @@ -2,6 +2,8 @@ Changes in Shorewall 4.3.2 1) Added 'dhcp' option. +2) Add 'allowBcast' and 'dropBcast' builtin actions to Shorewall6. + Changes in Shorewall 4.3.1 1) Allow addresses in rules to be enclosed in square brackets. diff --git a/Shorewall-common/releasenotes.txt b/Shorewall-common/releasenotes.txt index de5d0f303..807b55b6b 100644 --- a/Shorewall-common/releasenotes.txt +++ b/Shorewall-common/releasenotes.txt @@ -14,6 +14,14 @@ Other changes in 4.3.2 1) The 'dhcp' option has been added to accomodate IPv6 DHCP (UDP ports 546 and 547). +2) The 'allowBcast' and 'dropBcast' builtin actions have been added to + Shorewall6. Respectively, they accept or silently drop packets with + an anycast or multicast destination address. + +3) The nosmurfs option has been added to + /etc/shorewall8/interfaces. The option drops incoming packets whose + source address is an anycast or multicast addreess. + Migration Issues. None. diff --git a/Shorewall-perl/Shorewall/Actions.pm b/Shorewall-perl/Shorewall/Actions.pm index fbf4b95c9..c4214bae9 100644 --- a/Shorewall-perl/Shorewall/Actions.pm +++ b/Shorewall-perl/Shorewall/Actions.pm @@ -83,6 +83,8 @@ our %logactionchains; our %macros; +our $family; + # # Commands that can be embedded in a macro file and how many total tokens on the line (0 => unlimited). # @@ -97,7 +99,9 @@ our $macro_commands = { COMMENT => 0, FORMAT => 2 }; # the second and subsequent calls to that function. # -sub initialize() { +sub initialize( $ ) { + + $family = shift; %usedactions = (); %default_actions = ( DROP => 'none' , REJECT => 'none' , @@ -109,7 +113,7 @@ sub initialize() { } INIT { - initialize; + initialize( F_IPV4 ); } # @@ -731,7 +735,12 @@ sub process_actions3 () { add_rule $chainref, '-m addrtype --dst-type BROADCAST -j DROP'; } else { - add_command $chainref, 'for address in $ALL_BCASTS; do'; + if ( $family == F_IPV4 ) { + add_command $chainref, 'for address in $ALL_BCASTS; do'; + } else { + add_command $chainref, 'for address in $ALL_ACASTS; do'; + } + incr_cmd_level $chainref; log_rule_limit $level, $chainref, 'dropBcast' , 'DROP', '', $tag, 'add', ' -d $address ' if $level ne ''; add_rule $chainref, '-d $address -j DROP'; @@ -741,7 +750,12 @@ sub process_actions3 () { log_rule_limit $level, $chainref, 'dropBcast' , 'DROP', '', $tag, 'add', ' -d 224.0.0.0/4 ' if $level ne ''; } - add_rule $chainref, '-d 224.0.0.0/4 -j DROP'; + + if ( $family == F_IPV4 ) { + add_rule $chainref, '-d 224.0.0.0/4 -j DROP'; + } else { + add_rule $chainref, '-d ff00::/10 -j DROP'; + } } sub allowBcast( $$$ ) { @@ -755,16 +769,26 @@ sub process_actions3 () { add_rule $chainref, '-m addrtype --dst-type BROADCAST -j ACCEPT'; } else { - add_command $chainref, 'for address in $ALL_BCASTS; do'; + if ( $family == F_IPV4 ) { + add_command $chainref, 'for address in $ALL_BCASTS; do'; + } else { + add_command $chainref, 'for address in $ALL_MACASTS; do'; + } + incr_cmd_level $chainref; log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -d $address ' if $level ne ''; add_rule $chainref, '-d $address -j ACCEPT'; decr_cmd_level $chainref; add_command $chainref, 'done'; - log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -d 224.0.0.0/4 ' if $level ne ''; + if ( $family == F_IPV4 ) { + log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -d 224.0.0.0/4 ' if $level ne ''; + add_rule $chainref, '-d 224.0.0.0/4 -j ACCEPT'; + } else { + log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -d ff00::/10 ' if $level ne ''; + add_rule $chainref, '-d ff00:/10 -j ACCEPT'; + } } - add_rule $chainref, '-d 224.0.0.0/4 -j ACCEPT'; } sub dropNotSyn ( $$$ ) { diff --git a/Shorewall-perl/Shorewall/Chains.pm b/Shorewall-perl/Shorewall/Chains.pm index d591a72d1..b0eeadfca 100644 --- a/Shorewall-perl/Shorewall/Chains.pm +++ b/Shorewall-perl/Shorewall/Chains.pm @@ -137,6 +137,7 @@ our %EXPORT_TAGS = ( get_interface_address get_interface_addresses get_interface_bcasts + get_interface_acasts get_interface_gateway get_interface_mac set_global_variables @@ -235,6 +236,7 @@ our %interfaceaddrs; our %interfacenets; our %interfacemacs; our %interfacebcasts; +our %interfaceacasts; our %interfacegateways; our @builtins = qw(PREROUTING INPUT FORWARD OUTPUT POSTROUTING); @@ -304,6 +306,7 @@ sub initialize( $ ) { %interfacenets = (); %interfacemacs = (); %interfacebcasts = (); + %interfaceacasts = (); %interfacegateways = (); $family = shift; @@ -960,6 +963,8 @@ sub initialize_chain_table() 'QUEUE!' => STANDARD, 'NFQUEUE' => STANDARD + NFQ, 'NFQUEUE!' => STANDARD + NFQ, + 'dropBcast' => BUILTIN + ACTION, + 'allowBcast' => BUILTIN + ACTION, 'dropNotSyn' => BUILTIN + ACTION, 'rejNotSyn' => BUILTIN + ACTION, 'dropInvalid' => BUILTIN + ACTION, @@ -1789,6 +1794,27 @@ sub get_interface_bcasts ( $ ) { "\$$variable"; } +# +# Returns the name of the shell variable holding the anycast addresses of the passed interface +# +sub interface_acasts( $ ) { + my $variable = chain_base( $_[0] ) . '_acasts'; + uc $variable; +} + +# +# Record that the ruleset requires the anycast addresses on the passed interface +# +sub get_interface_acasts ( $ ) { + my ( $interface ) = $_[0]; + + my $variable = interface_acasts( $interface ); + + $interfaceacasts{$interface} = qq($variable="\$(get_interface_acasts $interface) ff00::/10"); + + "\$$variable"; +} + # # Returns the name of the shell variable holding the gateway through the passed interface # @@ -2388,10 +2414,19 @@ sub set_global_variables() { unless ( $capabilities{ADDRTYPE} ) { emit_comment unless $emitted_comment; emit_test unless $emitted_test; - emit 'ALL_BCASTS="$(get_all_bcasts) 255.255.255.255"'; - for ( values %interfacebcasts ) { - emit $_; + if ( $family == F_IPV4 ) { + emit 'ALL_BCASTS="$(get_all_bcasts) 255.255.255.255"'; + + for ( values %interfacebcasts ) { + emit $_; + } + } else { + emit 'ALL_ACASTS="$(get_all_acasts)"'; + + for ( values %interfaceacasts ) { + emit $_; + } } } diff --git a/Shorewall-perl/Shorewall/Compiler.pm b/Shorewall-perl/Shorewall/Compiler.pm index 1ad965d44..b082425fe 100644 --- a/Shorewall-perl/Shorewall/Compiler.pm +++ b/Shorewall-perl/Shorewall/Compiler.pm @@ -67,7 +67,7 @@ sub reinitialize() { Shorewall::Nat::initialize; Shorewall::Providers::initialize($family); Shorewall::Tc::initialize($family); - Shorewall::Actions::initialize; + Shorewall::Actions::initialize( $family ); Shorewall::Accounting::initialize; Shorewall::Rules::initialize($family); Shorewall::Proxyarp::initialize; diff --git a/Shorewall-perl/Shorewall/Rules.pm b/Shorewall-perl/Shorewall/Rules.pm index 5c99c0132..a07b2fc17 100644 --- a/Shorewall-perl/Shorewall/Rules.pm +++ b/Shorewall-perl/Shorewall/Rules.pm @@ -534,36 +534,48 @@ sub add_common_rules() { $chainref = new_standard_chain 'smurfs'; - if ( $family == F_IPV4 ) { - if ( $capabilities{ADDRTYPE} ) { - add_rule $chainref , '-s 0.0.0.0 -j RETURN'; - add_rule_pair $chainref, '-m addrtype --src-type BROADCAST ', 'DROP', $config{SMURF_LOG_LEVEL} ; - } else { + if ( $capabilities{ADDRTYPE} ) { + add_rule $chainref , '-s 0.0.0.0 -j RETURN'; + add_rule_pair $chainref, '-m addrtype --src-type BROADCAST ', 'DROP', $config{SMURF_LOG_LEVEL} ; + } else { + if ( $family == F_IPV4 ) { add_command $chainref, 'for address in $ALL_BCASTS; do'; - incr_cmd_level $chainref; - log_rule( $config{SMURF_LOG_LEVEL} , $chainref, 'DROP', '-s $address ' ); - add_rule $chainref, '-s $address -j DROP'; - decr_cmd_level $chainref; - add_command $chainref, 'done'; - } - - add_rule_pair $chainref, '-s 224.0.0.0/4 ', 'DROP', $config{SMURF_LOG_LEVEL} ; - - if ( $capabilities{ADDRTYPE} ) { - add_rule $rejectref , '-m addrtype --src-type BROADCAST -j DROP'; } else { - add_command $rejectref, 'for address in $ALL_BCASTS; do'; - incr_cmd_level $rejectref; - add_rule $rejectref, '-d $address -j DROP'; - decr_cmd_level $rejectref; - add_command $rejectref, 'done'; + add_command $chainref, 'for address in $ALL_ACASTS; do'; } + + incr_cmd_level $chainref; + log_rule( $config{SMURF_LOG_LEVEL} , $chainref, 'DROP', '-s $address ' ); + add_rule $chainref, '-s $address -j DROP'; + decr_cmd_level $chainref; + add_command $chainref, 'done'; + } + + if ( $family == F_IPV4 ) { + add_rule_pair $chainref, '-s 224.0.0.0/4 ', 'DROP', $config{SMURF_LOG_LEVEL}; + } else { + add_rule_pair $chainref, '-s ff00::/10 ', 'DROP', $config{SMURF_LOG_LEVEL} if $family == F_IPV4; + } + + if ( $capabilities{ADDRTYPE} ) { + add_rule $rejectref , '-m addrtype --src-type BROADCAST -j DROP'; + } else { + if ( $family == F_IPV4 ) { + add_command $rejectref, 'for address in $ALL_BCASTS; do'; + } else { + add_command $rejectref, 'for address in $ALL_ACASTS; do'; + } + + incr_cmd_level $rejectref; + add_rule $rejectref, '-d $address -j DROP'; + decr_cmd_level $rejectref; + add_command $rejectref, 'done'; + } + if ( $family == F_IPV4 ) { add_rule $rejectref , '-s 224.0.0.0/4 -j DROP'; } else { - my $predicate = '-s ' . IPv6_MULTICAST . ' '; - add_rule_pair $chainref , $predicate, 'DROP' , $config{SMURF_LOG_LEVEL}; - add_rule $rejectref, "$predicate -j DROP"; + add_rule $rejectref , '-s ff00::/10 -j DROP'; } if ( @$list ) { diff --git a/Shorewall-perl/Shorewall/Zones.pm b/Shorewall-perl/Shorewall/Zones.pm index c8b7dd490..859763cbe 100644 --- a/Shorewall-perl/Shorewall/Zones.pm +++ b/Shorewall-perl/Shorewall/Zones.pm @@ -628,8 +628,9 @@ sub validate_interfaces_file( $ ) %validoptions = ( blacklist => SIMPLE_IF_OPTION, bridge => SIMPLE_IF_OPTION, dhcp => SIMPLE_IF_OPTION, + nosmurfs => SIMPLE_IF_OPTION, optional => SIMPLE_IF_OPTION, - routeback => SIMPLE_IF_OPTION + IF_OPTION_ZONEONLY, + routeback => SIMPLE_IF_OPTION + IF_OPTION_ZONEONLY, sourceroute => BINARY_IF_OPTION, tcpflags => SIMPLE_IF_OPTION, mss => NUMERIC_IF_OPTION, diff --git a/Shorewall-perl/prog.functions6 b/Shorewall-perl/prog.functions6 index 1c041e04c..8e0d3e785 100644 --- a/Shorewall-perl/prog.functions6 +++ b/Shorewall-perl/prog.functions6 @@ -156,14 +156,6 @@ restore_dynamic_rules() { fi } -# -# Get a list of all configured broadcast addresses on the system -# -get_all_bcasts() -{ - ip -f inet addr show 2> /dev/null | grep 'inet.*brd' | sed 's/inet.*brd //; s/scope.*//;' | sort -u -} - # # Run the .iptables_restore_input as a set of discrete iptables commands # diff --git a/Shorewall-perl/prog.header6 b/Shorewall-perl/prog.header6 index 5b0531a29..fe0e28abe 100644 --- a/Shorewall-perl/prog.header6 +++ b/Shorewall-perl/prog.header6 @@ -562,39 +562,43 @@ convert_to_anycast() { local m while read address; do - vlsm=${address#*/} - if [ ${vlsm:-128} -ne 128 ]; then - # - # Defines a subnet -- get the anycase address - # - address=$(normalize_address ${address%/*}) + case $address in + 2*|3*) + vlsm=${address#*/} + if [ ${vlsm:-128} -ne 128 ]; then + # + # Defines a subnet -- get the anycast address + # + address=$(normalize_address ${address%/*}) - while [ $vlsm -le 112 ]; do - address=${address%:*} - vlsm=$(($vlsm + 16)) - done + while [ $vlsm -le 112 ]; do + address=${address%:*} + vlsm=$(($vlsm + 16)) + done - if [ $vlsm -lt 128 ]; then - o=$((0x${address##*:})) - m=0 - while [ $vlsm -lt 128 ]; do - m=$((($m >> 1) | 0x8000)) - vlsm=$(($vlsm + 1)) - done + if [ $vlsm -lt 128 ]; then + o=$((0x${address##*:})) + m=0 + while [ $vlsm -lt 128 ]; do + m=$((($m >> 1) | 0x8000)) + vlsm=$(($vlsm + 1)) + done - o=$(($o & $m)) + o=$(($o & $m)) - address=${address%:*}:$(printf %04x $o) - fi + address=${address%:*}:$(printf %04x $o) + fi - list_count $(split $address) + list_count $(split $address) - if [ $? -lt 8 ]; then - address=$address:: - fi + if [ $? -lt 8 ]; then + address=$address:: + fi - echo $address - fi + echo $address + fi + ;; + esac done } @@ -602,7 +606,7 @@ convert_to_anycast() { # Generate a list of anycast addresses for a given interface # -get_interface_bcasts() # $1 = interface +get_interface_acasts() # $1 = interface { local addresses addresses= @@ -610,6 +614,14 @@ get_interface_bcasts() # $1 = interface find_interface_full_addresses $1 | convert_to_anycast | sort -u } +# +# Get a list of all configured anycast addresses on the system +# +get_all_acasts() +{ + find_interface_full_addresses | convert_to_anycast | sort -u +} + # # Internal version of 'which' # diff --git a/Shorewall6/lib.cli b/Shorewall6/lib.cli index 284ad5e76..5a31e164d 100644 --- a/Shorewall6/lib.cli +++ b/Shorewall6/lib.cli @@ -506,6 +506,8 @@ show_command() { case $1 in actions) [ $# -gt 1 ] && usage 1 + echo "allowBcast # Accept Multicast and Anycast Packets" + echo "dropBcast # Silently Drop Multicast and Anycast Packets" echo "allowInvalid # Accept packets that are in the INVALID conntrack state." echo "dropInvalid # Silently Drop packets that are in the INVALID conntrack state" echo "dropNotSyn # Silently Drop Non-syn TCP packets" diff --git a/Shorewall6/shorewall6.conf b/Shorewall6/shorewall6.conf index 31fa024ea..c0ec64144 100644 --- a/Shorewall6/shorewall6.conf +++ b/Shorewall6/shorewall6.conf @@ -50,6 +50,8 @@ BLACKLIST_LOGLEVEL= TCP_FLAGS_LOG_LEVEL=info +SMURF_LOG_LEVEL=info + ############################################################################### # L O C A T I O N O F F I L E S A N D D I R E C T O R I E S ###############################################################################