diff --git a/Shorewall/Perl/Shorewall/Accounting.pm b/Shorewall/Perl/Shorewall/Accounting.pm index aac363e1e..933b52617 100644 --- a/Shorewall/Perl/Shorewall/Accounting.pm +++ b/Shorewall/Perl/Shorewall/Accounting.pm @@ -158,7 +158,7 @@ sub process_accounting_rule( ) { our $disposition = ''; sub reserved_chain_name($) { - $_[0] =~ /^acc(?:ount(?:fwd|in|ing|out)|ipsecin|ipsecout)$/; + $_[0] =~ /^acc(?:ount(?:fwd|in|ing|out|pre|post)|ipsecin|ipsecout)$/; } sub ipsec_chain_name($) { diff --git a/Shorewall/Perl/Shorewall/Compiler.pm b/Shorewall/Perl/Shorewall/Compiler.pm index f23ddae02..98a900b43 100644 --- a/Shorewall/Perl/Shorewall/Compiler.pm +++ b/Shorewall/Perl/Shorewall/Compiler.pm @@ -763,6 +763,10 @@ sub compiler { # setup_mac_lists 1; # + # Prevent Hairpins on non-routeback interfaces + # + prevent_hairpins; + # # Process the rules file. # process_rules; diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm index 4c82f21f6..6bea43b7d 100644 --- a/Shorewall/Perl/Shorewall/Config.pm +++ b/Shorewall/Perl/Shorewall/Config.pm @@ -447,6 +447,7 @@ sub initialize( $ ) { LOG_MARTIANS => undef, LOG_VERBOSITY => undef, STARTUP_LOG => undef, + ROUTEBACK_LOG_LEVEL => undef, # # Location of Files # @@ -550,6 +551,7 @@ sub initialize( $ ) { TCP_FLAGS_DISPOSITION => undef, BLACKLIST_DISPOSITION => undef, SMURF_DISPOSITION => undef, + ROUTEBACK_DISPOSITION => undef, # # Mark Geometry # @@ -3377,6 +3379,14 @@ sub get_configuration( $ ) { default_log_level 'SMURF_LOG_LEVEL', ''; default_log_level 'LOGALLNEW', ''; + default_log_level 'ROUTEBACK_LOG_LEVEL', 'info'; + + if ( $val = $config{ROUTEBACK_DISPOSITION} ) { + fatal_error "Invalid ROUTEBACK_DISPOSITION setting ($val)" unless $val =~ /^(?:A_)?DROP$/; + } else { + $config{ROUTEBACK_DISPOSITION} = 'DROP'; + } + if ( $val = $config{MACLIST_DISPOSITION} ) { if ( $val =~ /^(?:A_)?DROP$/ ) { $globals{MACLIST_TARGET} = $val; diff --git a/Shorewall/Perl/Shorewall/Proc.pm b/Shorewall/Perl/Shorewall/Proc.pm index 28878ea72..f795b115a 100644 --- a/Shorewall/Perl/Shorewall/Proc.pm +++ b/Shorewall/Perl/Shorewall/Proc.pm @@ -106,7 +106,7 @@ sub setup_route_filtering() { my $val = ''; - if ( $config{ROUTE_FILTER} ne '' ) { + if ( $config ne '' ) { $val = $config eq 'on' ? 1 : $config eq 'off' ? 0 : $config; emit ( 'for file in /proc/sys/net/ipv4/conf/*; do', diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index 8ce521384..7dc2e780d 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -49,6 +49,7 @@ our @EXPORT = qw( process_actions process_rules verify_audit + prevent_hairpins ); our @EXPORT_OK = qw( initialize ); @@ -650,6 +651,8 @@ sub complete_standard_chain ( $$$$ ) { policy_rules $stdchainref , $policy , $loglevel, $defaultaction, 0; } +sub require_audit($$); + # # Create and populate the synflood chains corresponding to entries in /etc/shorewall/policy # @@ -1182,7 +1185,46 @@ sub require_audit($$) { return ensure_audit_chain $target, $action; } + +# +# Generate rules to prevent hairpins +# +sub prevent_hairpins() { + my $loglevel = $config{ROUTEBACK_LOG_LEVEL}; + my $target = $config{ROUTEBACK_DISPOSITION}; + my $audit = $target eq 'A_DROP'; + + require_capability 'AUDIT_TARGET' , 'ROUTEBACK_DISPOSITION=A_DROP', 's' if $audit; + if ( $loglevel ) { + my $chainref = new_standard_chain 'routeback'; + log_rule $loglevel , $chainref , $target, ''; + + if ( $audit ) { + if ( $config{FAKE_AUDIT} ) { + add_jump( $chainref, 'AUDIT', 0, '-m comment --comment "--type drop"' , 0 ); + } else { + add_rule $chainref, 'AUDIT --type drop'; + } + } + + add_jump $chainref, $target, 1; + $target = $chainref; + } else { + $target = require_audit( 'DROP', $audit ? 'audit' : '' ); + } + + for my $interface (all_interfaces) { + my $interfaceref = find_interface( $interface ); + + add_jump( $filter_table->{forward_chain $interface}, + $target, + 1, + match_dest_dev( $interface ) ) + unless $interfaceref->{routefilter} || $interfaceref->{options}{routeback} || $interfaceref->{options}{ignore}; + } +} + # # The following small functions generate rules for the builtin actions of the same name # diff --git a/Shorewall/changelog.txt b/Shorewall/changelog.txt index 6d2be4b79..59e955a1a 100644 --- a/Shorewall/changelog.txt +++ b/Shorewall/changelog.txt @@ -4,6 +4,8 @@ Changes in Shorewall 4.4.20 Beta 5 2) Add -T option to compile and check +3) Implement ROUTEBACK_LOG_LEVEL and ROUTEBACK_AUDIT + Changes in Shorewall 4.4.20 Beta 4 1) Smarten up the tc devnum algorithm. diff --git a/Shorewall/configfiles/shorewall.conf b/Shorewall/configfiles/shorewall.conf index 31a96f50e..e2454f573 100644 --- a/Shorewall/configfiles/shorewall.conf +++ b/Shorewall/configfiles/shorewall.conf @@ -18,7 +18,7 @@ STARTUP_ENABLED=No VERBOSITY=1 ############################################################################### -# L O G G I N G +# L O G G I N G ############################################################################### LOGFILE=/var/log/messages @@ -45,6 +45,8 @@ SMURF_LOG_LEVEL=info LOG_MARTIANS=Yes +ROUTEBACK_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 ############################################################################### @@ -212,4 +214,6 @@ TCP_FLAGS_DISPOSITION=DROP SMURF_DISPOSITION=DROP +ROUTEBACK_DISPOSITION=DROP + #LAST LINE -- DO NOT REMOVE diff --git a/Shorewall/releasenotes.txt b/Shorewall/releasenotes.txt index be0e39509..5eb0520ff 100644 --- a/Shorewall/releasenotes.txt +++ b/Shorewall/releasenotes.txt @@ -19,6 +19,33 @@ VI. PROBLEMS CORRECTED AND NEW FEATURES IN PRIOR RELEASES did not specify a number. Now, the compiler selects the lowest unallocated number when no device number is explicitly allocated. +2) Eric Leblond, creator of NuFW, has discovered an exploit that + allows locally-connected hosts to poke holes in the firewall. The + known ways to protect against the exploit are: + + a) rt_filter (Shorewall's routefilter). Only applicable to IPv4. + b) Insert a DROP rule that prevents hairpinning (routeback). The rule + must be inserted before any RELATED firewall rules. This + approach is not appropriate for bridges. + + To deal with this issue, Shorewall will insert a hairpin-prevention + rule for each interface that has none of these options: + + - ignore + - routeback + - routefilter + + To control logging and auditing of these DROP operations, two new + options are added to shorewall.conf (shorewall6.conf): + + - ROUTEBACK_LOG_LEVEL - Default is 'info'. If you don't want these + DROPs logged, set ROUTEBACK_LOG_LEVEL=none + + - ROUTEBACK_AUDIT - Defaults to 'No'; 'Yes' causes auditing. + + This leaves IPv6 bridges still unprotected unless each of its ports + is described as bridge ports in /etc/shorewall/interfaces. + ---------------------------------------------------------------------------- I I. K N O W N P R O B L E M S R E M A I N I N G ---------------------------------------------------------------------------- diff --git a/Shorewall6/shorewall6.conf b/Shorewall6/shorewall6.conf index eaea952a3..baadbfffc 100644 --- a/Shorewall6/shorewall6.conf +++ b/Shorewall6/shorewall6.conf @@ -42,6 +42,8 @@ TCP_FLAGS_LOG_LEVEL=info SMURF_LOG_LEVEL=info +ROUTEBACK_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 ############################################################################### @@ -173,4 +175,6 @@ TCP_FLAGS_DISPOSITION=DROP SMURF_DISPOSITION=DROP +ROUTEBACK_DISPOSITION=DROP + #LAST LINE -- DO NOT REMOVE