diff --git a/Shorewall/Macros/macro.Amanda b/Shorewall/Macros/macro.Amanda index 32450d194..bf45c2d69 100644 --- a/Shorewall/Macros/macro.Amanda +++ b/Shorewall/Macros/macro.Amanda @@ -8,9 +8,16 @@ # files from those nodes. # ############################################################################### +FORMAT 2 #ACTION SOURCE DEST PROTO DEST SOURCE RATE USER/ # PORT(S) PORT(S) LIMIT GROUP -PARAM - - udp 10080 + +?if ( __CT_TARGET && ! $AUTOHELPERS && __AMANDA_HELPER ) + PARAM - - udp 10080 ; helper=amanda +?else + PARAM - - udp 10080 +?endif + PARAM - - tcp 10080 # # You may also need this rule. With AMANDA 2.4.4 on Linux kernel 2.6, diff --git a/Shorewall/Macros/macro.BLACKLIST b/Shorewall/Macros/macro.BLACKLIST index c51675fb1..cebff9453 100644 --- a/Shorewall/Macros/macro.BLACKLIST +++ b/Shorewall/Macros/macro.BLACKLIST @@ -8,8 +8,8 @@ ############################################################################### #ACTION SOURCE DEST PROTO DEST SOURCE RATE USER/ # PORT(S) PORT(S) LIMIT GROUP -?IF $BLACKLIST_LOGLEVEL +?if $BLACKLIST_LOGLEVEL blacklog -?ELSE +?else $BLACKLIST_DISPOSITION -?ENDIF +?endif diff --git a/Shorewall/Macros/macro.FTP b/Shorewall/Macros/macro.FTP index 431407ddc..038857a53 100644 --- a/Shorewall/Macros/macro.FTP +++ b/Shorewall/Macros/macro.FTP @@ -6,6 +6,11 @@ # This macro handles FTP traffic. # ############################################################################### +FORMAT 2 #ACTION SOURCE DEST PROTO DEST SOURCE RATE USER/ # PORT(S) PORT(S) LIMIT GROUP -PARAM - - tcp 21 +?if ( __CT_TARGET && ! $AUTOHELPERS && __FTP_HELPER ) + PARAM - - tcp 21 ; helper=ftp +?else + PARAM - - tcp 21 +?endif diff --git a/Shorewall/Macros/macro.IRC b/Shorewall/Macros/macro.IRC index a2576058d..020bee064 100644 --- a/Shorewall/Macros/macro.IRC +++ b/Shorewall/Macros/macro.IRC @@ -6,6 +6,12 @@ # This macro handles IRC traffic (Internet Relay Chat). # ############################################################################### +FORMAT 2 #ACTION SOURCE DEST PROTO DEST SOURCE RATE USER/ # PORT(S) PORT(S) LIMIT GROUP -PARAM - - tcp 6667 + +?if ( __CT_TARGET && ! $AUTOHELPERS && __IRC_HELPER ) + PARAM - - tcp 6667 ; helper=irc +?else + PARAM - - tcp 6667 +?endif diff --git a/Shorewall/Macros/macro.PPtP b/Shorewall/Macros/macro.PPtP index aa9f4b73c..b4ba427e8 100644 --- a/Shorewall/Macros/macro.PPtP +++ b/Shorewall/Macros/macro.PPtP @@ -6,8 +6,14 @@ # This macro handles PPTP traffic. # ############################################################################### +?FORMAT 2 #ACTION SOURCE DEST PROTO DEST SOURCE RATE USER/ # PORT(S) PORT(S) LIMIT GROUP PARAM - - 47 PARAM DEST SOURCE 47 -PARAM - - tcp 1723 + +?if ( __CT_TARGET && ! $AUTOHELPERS && __PPTP_HELPER ) + PARAM - - tcp 1723 ; helper=pptp +?else + PARAM - - tcp 1723 +?endif diff --git a/Shorewall/Macros/macro.SANE b/Shorewall/Macros/macro.SANE index 5fa2f198f..40721e64d 100644 --- a/Shorewall/Macros/macro.SANE +++ b/Shorewall/Macros/macro.SANE @@ -6,9 +6,16 @@ # This macro handles SANE network scanning. # ############################################################################### +FORMAT 2 #ACTION SOURCE DEST PROTO DEST SOURCE RATE USER/ # PORT(S) PORT(S) LIMIT GROUP -PARAM - - tcp 6566 + +?if ( __CT_TARGET && ! $AUTOHELPERS && __SANE_HELPER ) + PARAM - - tcp 6566 ; helper=sane +?else + PARAM - - tcp 6566 +?endif + # # Kernels 2.6.23+ has nf_conntrack_sane module which will handle # sane data connection. diff --git a/Shorewall/Macros/macro.SIP b/Shorewall/Macros/macro.SIP new file mode 100644 index 000000000..015d8b688 --- /dev/null +++ b/Shorewall/Macros/macro.SIP @@ -0,0 +1,17 @@ +# +# Shorewall version 4 - SIP Macro +# +# /usr/share/shorewall/macro.SIP +# +# This macro handles SIP traffic. +# +############################################################################### +FORMAT 2 +#ACTION SOURCE DEST PROTO DEST SOURCE RATE USER/ +# PORT(S) PORT(S) LIMIT GROUP + +?if ( __CT_TARGET && ! $AUTOHELPERS && __SIP_HELPER ) + PARAM - - udp 5060 ; helper=sip +?else + PARAM - - udp 5060 +?endif diff --git a/Shorewall/Macros/macro.SMB b/Shorewall/Macros/macro.SMB index 56bb8222a..20208fdf3 100644 --- a/Shorewall/Macros/macro.SMB +++ b/Shorewall/Macros/macro.SMB @@ -10,9 +10,17 @@ # between hosts you fully trust. # ############################################################################### +FORMAT 2 #ACTION SOURCE DEST PROTO DEST SOURCE RATE USER/ # PORT(S) PORT(S) LIMIT GROUP PARAM - - udp 135,445 -PARAM - - udp 137:139 + +?if ( __CT_TARGET && ! $AUTOHELPERS && __NETBIOS_NS_HELPER ) + PARAM - - udp 137 ; helper=netbios-ns + PARAM - - udp 138:139 +?else + PARAM - - udp 137:139 +?endif + PARAM - - udp 1024: 137 PARAM - - tcp 135,139,445 diff --git a/Shorewall/Macros/macro.SMBBI b/Shorewall/Macros/macro.SMBBI index 99351e6a8..08311d3fe 100644 --- a/Shorewall/Macros/macro.SMBBI +++ b/Shorewall/Macros/macro.SMBBI @@ -10,13 +10,28 @@ # allow SMB traffic between hosts you fully trust. # ############################################################################### +FORMAT 2 #ACTION SOURCE DEST PROTO DEST SOURCE RATE USER/ # PORT(S) PORT(S) LIMIT GROUP PARAM - - udp 135,445 -PARAM - - udp 137:139 + +?if ( __CT_TARGET && ! $AUTOHELPERS && __NETBIOS_NS_HELPER ) + PARAM - - udp 137 ; helper=netbios-ns + PARAM - - udp 138:139 +?else + PARAM - - udp 137:139 +?endif + PARAM - - udp 1024: 137 PARAM - - tcp 135,139,445 PARAM DEST SOURCE udp 135,445 -PARAM DEST SOURCE udp 137:139 + +?if ( __CT_TARGET && ! $AUTOHELPERS && __NETBIOS_NS_HELPER ) + PARAM DEST SOURCE udp 137 ; helper=netbios-ns + PARAM DEST SOURCE udp 138:139 +?else + PARAM DEST SOURCE udp 137:139 +?endif + PARAM DEST SOURCE udp 1024: 137 PARAM DEST SOURCE tcp 135,139,445 diff --git a/Shorewall/Macros/macro.SNMP b/Shorewall/Macros/macro.SNMP index 221a22921..bbc906fbc 100644 --- a/Shorewall/Macros/macro.SNMP +++ b/Shorewall/Macros/macro.SNMP @@ -6,7 +6,15 @@ # This macro handles SNMP traffic (including traps). # ############################################################################### +FORMAT 2 #ACTION SOURCE DEST PROTO DEST SOURCE RATE USER/ # PORT(S) PORT(S) LIMIT GROUP -PARAM - - udp 161:162 + +?if ( __CT_TARGET && ! $AUTOHELPERS && __SNMP_HELPER ) + PARAM - - udp 161 ; helper=snmp + PARAM - - udp 162 +?else + PARAM - - udp 161:162 +?endif + PARAM - - tcp 161 diff --git a/Shorewall/Macros/macro.TFTP b/Shorewall/Macros/macro.TFTP index 0e630428b..8e7ccb4f3 100644 --- a/Shorewall/Macros/macro.TFTP +++ b/Shorewall/Macros/macro.TFTP @@ -8,6 +8,12 @@ # Internet. # ############################################################################### +FORMAT 2 #ACTION SOURCE DEST PROTO DEST SOURCE RATE USER/ # PORT(S) PORT(S) LIMIT GROUP -PARAM - - udp 69 + +?if ( __CT_TARGET && ! $AUTOHELPERS && __TFTP_HELPER ) + PARAM - - udp 69 ; helper=tftp +?else + PARAM - - udp 69 +?endif diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 7e1393a27..514e60ac2 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -101,6 +101,7 @@ our %EXPORT_TAGS = ( CHAIN SET AUDIT + HELPER NO_RESTRICT PREROUTE_RESTRICT DESTIFACE_DISALLOW @@ -352,6 +353,7 @@ use constant { STANDARD => 1, #defined by Netfilter CHAIN => 1024, #Manual Chain SET => 2048, #SET AUDIT => 4096, #A_ACCEPT, etc + HELPER => 8192, #CT:helper }; # # Valid Targets -- value is a combination of one or more of the above @@ -2979,6 +2981,51 @@ sub optimize_level4( $$ ) { } } + # + # Identify short chains with a single reference and replace the reference with the chain rules + # + my @chains = grep ( $_->{referenced} && + ! $_->{optflags} && + @{$_->{rules}} < 4 && + keys %{$_->{references}} == 1 , values %$tableref ); + + if ( my $chains = @chains ) { + $passes++; + + progress_message "\n Table $table pass $passes, $chains short chains, level 4b..."; + + for my $chainref ( @chains ) { + my $name = $chainref->{name}; + for my $sourceref ( map $tableref->{$_}, keys %{$chainref->{references}} ) { + my $name1 = $sourceref->{name}; + + if ( $chainref->{references}{$name1} == 1 ) { + my $rulenum = 0; + my $rulesref = $sourceref->{rules}; + my $rules = @{$chainref->{rules}}; + + for ( @$rulesref ) { + if ( $_->{simple} && ( $_->{target} || '' ) eq $name ) { + trace( $sourceref, 'D', $rulenum + 1, $_ ) if $debug; + splice @$rulesref, $rulenum, 1, @{$chainref->{rules}}; + if ( $debug ) { + while ( my $ruleref = shift @{$chainref->{rules}} ) { + trace ( $sourceref, 'I', $rulenum++, $ruleref ); + } + } + + delete $chainref->{references}{$name1}; + delete_chain $chainref; + last; + } + $rulenum++; + + } + } + } + } + } + $passes; } @@ -3282,6 +3329,62 @@ sub combine_dports { \@rules; } +# +# Delete duplicate rules from the passed chain. +# +# The arguments are a reference to the chain followed by references to each +# of its rules. +# +sub delete_duplicates { + my @rules; + my $chainref = shift; + my $lastrule = @_; + my $baseref = pop; + my $ruleref; + my $duplicate = 0; + + while ( @_ && ! $duplicate ) { + { + my $ports1; + my @keys1 = sort( keys( %$baseref ) ); + my $rulenum = @_; + my $duplicate = 0; + + RULE: + + while ( --$rulenum >= 0 ) { + $ruleref = $_[$rulenum]; + + my @keys2 = sort(keys( %$ruleref ) ); + + next unless @keys1 == @keys2 ; + + my $keynum = 0; + + for my $key ( @keys1 ) { + next RULE unless $key eq $keys2[$keynum++]; + next RULE unless compare_values( $baseref->{$key}, $ruleref->{$key} ); + } + + $duplicate = 1; + } + + if ( $duplicate ) { + trace( $chainref, 'D', $lastrule, $baseref ) if $debug; + } else { + unshift @rules, $baseref; + } + + $baseref = pop @_; + $lastrule--; + } + } + + unshift @rules, $baseref if $baseref; + + \@rules; +} + sub optimize_level16( $$$ ) { my ( $table, $tableref , $passes ) = @_; my @chains = ( grep $_->{referenced}, values %{$tableref} ); @@ -3290,11 +3393,23 @@ sub optimize_level16( $$$ ) { progress_message "\n Table $table pass $passes, $chains referenced user chains, level 16..."; + if ( $table eq 'raw' ) { + # + # Helpers in rules have the potential for generating lots of duplicate iptables rules + # in the raw table. This step eliminates those duplicates + # + for my $chainref ( @chains ) { + $chainref->{rules} = delete_duplicates( $chainref, @{$chainref->{rules}} ); + } + + $passes++; + } + for my $chainref ( @chains ) { $chainref->{rules} = combine_dports( $chainref, @{$chainref->{rules}} ); } - $passes++; + ++$passes; } # @@ -3483,7 +3598,7 @@ sub source_exclusion( $$ ) { my $table = reftype $target ? $target->{table} : 'filter'; - my $chainref = new_chain( $table , newexclusionchain( $table ) ); + my $chainref = dont_move new_chain( $table , newexclusionchain( $table ) ); add_ijump( $chainref, j => 'RETURN', imatch_source_net( $_ ) ) for @$exclusions; add_ijump( $chainref, g => $target ); @@ -3505,7 +3620,7 @@ sub source_iexclusion( $$$$$;@ ) { $source = $1; @exclusion = mysplit( $2 ); - my $chainref1 = new_chain( $table , newexclusionchain( $table ) ); + my $chainref1 = dont_move new_chain( $table , newexclusionchain( $table ) ); add_ijump( $chainref1 , j => 'RETURN', imatch_source_net( $_ ) ) for @exclusion; @@ -3534,7 +3649,7 @@ sub dest_exclusion( $$ ) { my $table = reftype $target ? $target->{table} : 'filter'; - my $chainref = new_chain( $table , newexclusionchain( $table ) ); + my $chainref = dont_move new_chain( $table , newexclusionchain( $table ) ); add_ijump( $chainref, j => 'RETURN', imatch_dest_net( $_ ) ) for @$exclusions; add_ijump( $chainref, g => $target ); @@ -3556,7 +3671,7 @@ sub dest_iexclusion( $$$$$;@ ) { $dest = $1; @exclusion = mysplit( $2 ); - my $chainref1 = new_chain( $table , newexclusionchain( $table ) ); + my $chainref1 = dont_move new_chain( $table , newexclusionchain( $table ) ); add_ijump( $chainref1 , j => 'RETURN', imatch_dest_net( $_ ) ) for @exclusion; diff --git a/Shorewall/Perl/Shorewall/Compiler.pm b/Shorewall/Perl/Shorewall/Compiler.pm index 9e6b01f98..16005639c 100644 --- a/Shorewall/Perl/Shorewall/Compiler.pm +++ b/Shorewall/Perl/Shorewall/Compiler.pm @@ -666,11 +666,6 @@ sub compiler { # (Produces no output to the compiled script) # process_policies; - # - # N O T R A C K - # (Produces no output to the compiled script) - # - setup_notrack; enable_script; @@ -710,12 +705,10 @@ sub compiler { # setup_proxy_arp; - my $setting = supplied $config{HELPERS} ? 0 : 1; - - emit( "#\n# Set automatic helper association on kernel 3.5.0 and later\n#" , + emit( "#\n# Disable automatic helper association on kernel 3.5.0 and later\n#" , 'if [ -f /proc/sys/net/netfilter/nf_conntrack_helper ]; then' , - ' progress_message "Setting up Automatic Helper Association"', - " echo $setting > /proc/sys/net/netfilter/nf_conntrack_helper", + ' progress_message "Disabling Kernel Automatic Helper Association"', + " echo 0 > /proc/sys/net/netfilter/nf_conntrack_helper", 'fi', '' ); @@ -799,6 +792,10 @@ sub compiler { # process_rules( $convert ); # + # Process the conntrack file + # + setup_conntrack; + # # Add Tunnel rules. # setup_tunnels; diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm index 2adf5bccc..b3e870dde 100644 --- a/Shorewall/Perl/Shorewall/Config.pm +++ b/Shorewall/Perl/Shorewall/Config.pm @@ -606,7 +606,6 @@ sub initialize( $;$ ) { EXPORT => 0, KLUDGEFREE => '', STATEMATCH => '-m state --state', - UNTRACKED => 0, VERSION => "4.5.6", CAPVERSION => 40507 , ); @@ -731,6 +730,7 @@ sub initialize( $;$ ) { LEGACY_FASTSTART => undef, USE_PHYSICAL_NAMES => undef, HELPERS => undef, + AUTOHELPERS => undef, # # Packet Disposition # @@ -4529,6 +4529,7 @@ sub get_configuration( $$$ ) { default_yes_no 'LEGACY_FASTSTART' , 'Yes'; default_yes_no 'USE_PHYSICAL_NAMES' , ''; default_yes_no 'IPSET_WARNINGS' , 'Yes'; + default_yes_no 'AUTOHELPERS' , 'Yes'; if ( supplied $config{HELPERS} ) { my %helpers_temp = %helpers_enabled; diff --git a/Shorewall/Perl/Shorewall/Misc.pm b/Shorewall/Perl/Shorewall/Misc.pm index 89b7b840d..487aab3c0 100644 --- a/Shorewall/Perl/Shorewall/Misc.pm +++ b/Shorewall/Perl/Shorewall/Misc.pm @@ -681,7 +681,7 @@ sub add_common_rules ( $ ) { my $chain; my $dynamicref; - my @state = $config{BLACKLISTNEWONLY} ? $globals{UNTRACKED} ? state_imatch 'NEW,INVALID,UNTRACKED' : state_imatch 'NEW,INVALID' : (); + my @state = $config{BLACKLISTNEWONLY} ? have_capability( 'RAW_TABLE' ) ? state_imatch 'NEW,INVALID,UNTRACKED' : state_imatch 'NEW,INVALID' : (); my $faststate = $config{RELATED_DISPOSITION} eq 'ACCEPT' && $config{RELATED_LOG_LEVEL} eq '' ? 'ESTABLISHED,RELATED' : 'ESTABLISHED'; my $level = $config{BLACKLIST_LOGLEVEL}; my $rejectref = $filter_table->{reject}; @@ -882,7 +882,7 @@ sub add_common_rules ( $ ) { add_ijump( $chainref, g => $smurfdest, s => IPv6_MULTICAST ); } - my @state = $globals{UNTRACKED} ? state_imatch 'NEW,INVALID,UNTRACKED' : state_imatch 'NEW,INVALID'; + my @state = have_capability( 'RAW_TABLE' ) ? state_imatch 'NEW,INVALID,UNTRACKED' : state_imatch 'NEW,INVALID'; for my $hostref ( @$list ) { $interface = $hostref->[0]; @@ -1187,7 +1187,7 @@ sub setup_mac_lists( $ ) { my @policy = have_ipsec ? ( policy => "--pol $ipsec --dir in" ) : (); my @source = imatch_source_net $hostref->[2]; - my @state = $globals{UNTRACKED} ? state_imatch 'NEW,UNTRACKED' : state_imatch 'NEW'; + my @state = have_capability( 'RAW_TABLE' ) ? state_imatch 'NEW,UNTRACKED' : state_imatch 'NEW'; if ( $table eq 'filter' ) { my $chainref = source_exclusion( $hostref->[3], $filter_table->{mac_chain $interface} ); diff --git a/Shorewall/Perl/Shorewall/Raw.pm b/Shorewall/Perl/Shorewall/Raw.pm index 9bd9b4001..284163ede 100644 --- a/Shorewall/Perl/Shorewall/Raw.pm +++ b/Shorewall/Perl/Shorewall/Raw.pm @@ -32,8 +32,8 @@ use Shorewall::Chains qw(:DEFAULT :internal); use strict; our @ISA = qw(Exporter); -our @EXPORT = qw( setup_notrack ); -our @EXPORT_OK = qw( ); +our @EXPORT = qw( setup_conntrack ); +our @EXPORT_OK = qw( handle_helper_rule ); our $VERSION = 'MODULEVERSION'; my %valid_ctevent = ( new => 1, related => 1, destroy => 1, reply => 1, assured => 1, protoinfo => 1, helper => 1, mark => 1, natseqinfo => 1, secmark => 1 ); @@ -41,21 +41,34 @@ my %valid_ctevent = ( new => 1, related => 1, destroy => 1, reply => 1, assured # # Notrack # -sub process_notrack_rule( $$$$$$$ ) { +sub process_conntrack_rule( $$$$$$$$$ ) { - my ($action, $source, $dest, $proto, $ports, $sports, $user ) = @_; + my ($chainref, $zoneref, $action, $source, $dest, $proto, $ports, $sports, $user ) = @_; + + require_capability 'RAW_TABLE', 'conntrack rules', ''; $proto = '' if $proto eq 'any'; $ports = '' if $ports eq 'any' || $ports eq 'all'; $sports = '' if $sports eq 'any' || $sports eq 'all'; - ( my $zone, $source) = split /:/, $source, 2; - my $zoneref = find_zone $zone; - my $chainref = ensure_raw_chain( notrack_chain $zone ); - my $restriction = $zoneref->{type} == FIREWALL || $zoneref->{type} == VSERVER ? OUTPUT_RESTRICT : PREROUTE_RESTRICT; + my $zone; + my $restriction = PREROUTE_RESTRICT; - fatal_error 'USER/GROUP is not allowed unless the SOURCE zone is $FW or a Vserver zone' if $user ne '-' && $restriction != OUTPUT_RESTRICT; - require_capability 'RAW_TABLE', 'conntrack rules', ''; + unless ( $chainref ) { + # + # Entry in the conntrack file + # + if ( $zoneref ) { + $zone = $zoneref->{name}; + } else { + ($zone, $source) = split /:/, $source, 2; + $zoneref = find_zone ( $zone ); + } + + $chainref = ensure_raw_chain( notrack_chain $zone ); + $restriction = OUTPUT_RESTRICT if $zoneref->{type} == FIREWALL || $zoneref->{type} == VSERVER; + fatal_error 'USER/GROUP is not allowed unless the SOURCE zone is $FW or a Vserver zone' if $user ne '-' && $restriction != OUTPUT_RESTRICT; + } my $target = $action; my $exception_rule = ''; @@ -122,9 +135,60 @@ sub process_notrack_rule( $$$$$$$ ) { $target , $exception_rule ); - progress_message " Notrack rule \"$currentline\" $done"; + progress_message " Conntrack rule \"$currentline\" $done"; +} - $globals{UNTRACKED} = 1; +sub handle_helper_rule( $$$$$$$$$$$ ) { + my ( $helper, $source, $dest, $proto, $ports, $sports, $sourceref, $action_target, $actionchain, $user, $rule ) = @_; + + if ( $helper ne '-' ) { + fatal_error "A HELPER is not allowed with this ACTION" if $action_target; + # + # This means that an ACCEPT or NAT rule with a helper is being processed + # + process_conntrack_rule( $actionchain ? ensure_raw_chain( $actionchain ) : undef , + $sourceref , + "CT:helper:$helper", + $source , + $dest , + $proto , + $ports , + $sports , + $user ); + } else { + assert( $action_target ); + # + # The target is an action + # + if ( $actionchain ) { + # + # And the source is another action chain + # + expand_rule( ensure_raw_chain( $actionchain ) , + PREROUTE_RESTRICT , + $rule , + $source , + $dest , + '' , + $action_target , + '', + 'CT' , + '' ); + } else { + expand_rule( ensure_raw_chain( notrack_chain( $sourceref->{name} ) ) , + ( $sourceref->{type} == FIREWALL || $sourceref->{type} == VSERVER ? + OUTPUT_RESTRICT : + PREROUTE_RESTRICT ) , + $rule , + $source , + $dest , + '' , + $action_target , + '' , + 'CT' , + '' ); + } + } } sub process_format( $ ) { @@ -135,7 +199,7 @@ sub process_format( $ ) { $format; } -sub setup_notrack() { +sub setup_conntrack() { my $format = 1; my $action = 'NOTRACK'; @@ -188,10 +252,10 @@ sub setup_notrack() { if ( $source eq 'all' ) { for my $zone (all_zones) { - process_notrack_rule( $action, $zone, $dest, $proto, $ports, $sports, $user ); + process_conntrack_rule( undef, undef, $action, $zone, $dest, $proto, $ports, $sports, $user ); } } else { - process_notrack_rule( $action, $source, $dest, $proto, $ports, $sports, $user ); + process_conntrack_rule( undef, undef, $action, $source, $dest, $proto, $ports, $sports, $user ); } } diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index b868ebd36..462e4c50a 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -34,6 +34,7 @@ use Shorewall::Zones; use Shorewall::Chains qw(:DEFAULT :internal); use Shorewall::IPAddrs; use Shorewall::Nat qw(:rules); +use Shorewall::Raw qw( handle_helper_rule ); use Scalar::Util 'reftype'; use strict; @@ -91,7 +92,9 @@ my %rulecolumns = ( action => 0, connlimit => 10, time => 11, headers => 12, - switch => 13 ); + switch => 13, + helper => 14, + ); use constant { MAX_MACRO_NEST_LEVEL => 5 }; @@ -915,7 +918,7 @@ sub new_action( $$ ) { fatal_error "Invalid action name($action)" if reserved_name( $action ); - $actions{$action} = { actchain => '' }; + $actions{$action} = { actchain => '' }; $targets{$action} = $type; } @@ -1424,7 +1427,7 @@ sub process_actions() { } -sub process_rule1 ( $$$$$$$$$$$$$$$$$ ); +sub process_rule1 ( $$$$$$$$$$$$$$$$$$ ); # # Populate an action invocation chain. As new action tuples are encountered, @@ -1457,14 +1460,14 @@ sub process_action( $) { while ( read_a_line( NORMAL_READ ) ) { - my ($target, $source, $dest, $proto, $ports, $sports, $origdest, $rate, $user, $mark, $connlimit, $time, $headers, $condition ); + my ($target, $source, $dest, $proto, $ports, $sports, $origdest, $rate, $user, $mark, $connlimit, $time, $headers, $condition, $helper ); if ( $format == 1 ) { ($target, $source, $dest, $proto, $ports, $sports, $rate, $user, $mark ) = split_line1 'action file', { target => 0, source => 1, dest => 2, proto => 3, dport => 4, sport => 5, rate => 6, user => 7, mark => 8 }, $rule_commands; $origdest = $connlimit = $time = $headers = $condition = '-'; } else { - ($target, $source, $dest, $proto, $ports, $sports, $origdest, $rate, $user, $mark, $connlimit, $time, $headers, $condition ) + ($target, $source, $dest, $proto, $ports, $sports, $origdest, $rate, $user, $mark, $connlimit, $time, $headers, $condition, $helper ) = split_line1 'action file', \%rulecolumns, $action_commands; } @@ -1502,6 +1505,7 @@ sub process_action( $) { $time, $headers, $condition, + $helper, 0 ); } @@ -1531,8 +1535,8 @@ sub use_policy_action( $ ) { # # Expand a macro rule from the rules file # -sub process_macro ( $$$$$$$$$$$$$$$$$$ ) { - my ($macro, $chainref, $target, $param, $source, $dest, $proto, $ports, $sports, $origdest, $rate, $user, $mark, $connlimit, $time, $headers, $condition, $wildcard ) = @_; +sub process_macro ( $$$$$$$$$$$$$$$$$$$) { + my ($macro, $chainref, $target, $param, $source, $dest, $proto, $ports, $sports, $origdest, $rate, $user, $mark, $connlimit, $time, $headers, $condition, $helper, $wildcard ) = @_; my $nocomment = no_comment; @@ -1550,13 +1554,13 @@ sub process_macro ( $$$$$$$$$$$$$$$$$$ ) { while ( read_a_line( NORMAL_READ ) ) { - my ( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $morigdest, $mrate, $muser, $mmark, $mconnlimit, $mtime, $mheaders, $mcondition ); + my ( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $morigdest, $mrate, $muser, $mmark, $mconnlimit, $mtime, $mheaders, $mcondition, $mhelper); if ( $format == 1 ) { ( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $mrate, $muser ) = split_line1 'macro file', \%rulecolumns, $rule_commands; - ( $morigdest, $mmark, $mconnlimit, $mtime, $mheaders, $mcondition ) = qw/- - - - - -/; + ( $morigdest, $mmark, $mconnlimit, $mtime, $mheaders, $mcondition, $mhelper ) = qw/- - - - - - -/; } else { - ( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $morigdest, $mrate, $muser, $mmark, $mconnlimit, $mtime, $mheaders, $mcondition ) = split_line1 'macro file', \%rulecolumns, $rule_commands; + ( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $morigdest, $mrate, $muser, $mmark, $mconnlimit, $mtime, $mheaders, $mcondition, $mhelper ) = split_line1 'macro file', \%rulecolumns, $rule_commands; } fatal_error 'TARGET must be specified' if $mtarget eq '-'; @@ -1635,6 +1639,7 @@ sub process_macro ( $$$$$$$$$$$$$$$$$$ ) { merge_macro_column( $mtime, $time ), merge_macro_column( $mheaders, $headers ), merge_macro_column( $mcondition, $condition ), + merge_macro_column( $mhelper, $helper ), $wildcard ); @@ -1667,7 +1672,7 @@ sub verify_audit($;$$) { # Similarly, if a new action tuple is encountered, this function is called recursively for each rule in the action # body. In this latter case, a reference to the tuple's chain is passed in the first ($chainref) argument. # -sub process_rule1 ( $$$$$$$$$$$$$$$$$ ) { +sub process_rule1 ( $$$$$$$$$$$$$$$$$$ ) { my ( $chainref, #reference to Action Chain if we are being called from process_action(); undef otherwise $target, $current_param, @@ -1684,6 +1689,7 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$ ) { $time, $headers, $condition, + $helper, $wildcard ) = @_; my ( $action, $loglevel) = split_action $target; @@ -1735,6 +1741,7 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$ ) { $time, $headers, $condition, + $helper, $wildcard ); $macro_nest_level--; @@ -1776,12 +1783,13 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$ ) { # process_action( $ref ); # - # Processing the action may determine that the action or one of it's dependents does NAT, so: + # Processing the action may determine that the action or one of it's dependents does NAT or HELPER, so: # # - Refresh $actiontype - # - Create the associate nat table chain if appropriate. + # - Create the associated nat and/or table chain if appropriate. # ensure_chain( 'nat', $ref->{name} ) if ( $actiontype = $targets{$basictarget} ) & NATRULE; + ensure_chain( 'raw', $ref->{name} ) if ( $actiontype & HELPER ); } $action = $basictarget; # Remove params, if any, from $action. @@ -1796,6 +1804,10 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$ ) { $targets{$inaction} |= NATRULE if $inaction; fatal_error "NAT rules are only allowed in the NEW section" unless $section eq 'NEW'; } + + if ( $actiontype & HELPER ) { + fatal_error "HELPER rules are only allowed in the NEW section" unless $section eq 'NEW'; + } # # Take care of irregular syntax and targets # @@ -1807,7 +1819,13 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$ ) { $bt =~ s/[-+!]$//; my %functions = - ( ACCEPT => sub() { $action = 'RETURN' if $blacklist; } , + ( ACCEPT => sub() { + if ( $blacklist ) { + $action = 'RETURN'; + } elsif ( $helper ne '-' ) { + $actiontype |= HELPER; + } + } , REDIRECT => sub () { my $z = $actiontype & NATONLY ? '' : firewall_zone; @@ -1838,6 +1856,8 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$ ) { if ( $function ) { $function->(); + } elsif ( $actiontype & NATRULE && $helper ne '-' ) { + $actiontype |= HELPER; } elsif ( $actiontype & SET ) { my %xlate = ( ADD => 'add-set' , DEL => 'del-set' ); @@ -2027,8 +2047,26 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$ ) { fatal_error "$basictarget rules are not allowed in the $section SECTION" if $actiontype & ( NATRULE | NONAT ); $rule .= "$globals{STATEMATCH} $section " unless $section eq 'ALL' || $blacklist; } - # + # Generate CT rules(s), if any + # + if ( $actiontype & HELPER ) { + handle_helper_rule( $helper, + $source, + $origdest ? $origdest : $dest, + $proto, + $ports, + $sports, + $sourceref, + ( $actiontype & ACTION ) ? $usedactions{$normalized_target}->{name} : '', + $inaction ? $chain : '' , + $user , + $rule , + ); + + $targets{$inaction} |= HELPER if $inaction; + } + # Generate NAT rule(s), if any # if ( $actiontype & NATRULE ) { @@ -2049,8 +2087,9 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$ ) { $rule, $source, ( $actiontype & ACTION ) ? '' : $loglevel, - $log_action - ); + $log_action, + ); + # # After NAT: # - the destination port will be the server port ($ports) -- we did that above @@ -2069,6 +2108,7 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$ ) { $loglevel = ''; $action = 'ACCEPT'; $origdest = ALLIP if $origdest =~ /[+]/; + $helper = '-'; } } elsif ( $actiontype & NONAT ) { # @@ -2224,7 +2264,7 @@ sub build_zone_list( $$$\$\$ ) { # Process a Record in the rules file # sub process_rule ( ) { - my ( $target, $source, $dest, $protos, $ports, $sports, $origdest, $ratelimit, $user, $mark, $connlimit, $time, $headers, $condition ) + my ( $target, $source, $dest, $protos, $ports, $sports, $origdest, $ratelimit, $user, $mark, $connlimit, $time, $headers, $condition, $helper ) = split_line1 'rules file', \%rulecolumns, $rule_commands; fatal_error 'ACTION must be specified' if $target eq '-'; @@ -2281,6 +2321,7 @@ sub process_rule ( ) { $time, $headers, $condition, + $helper, $wild ); } } @@ -2305,7 +2346,7 @@ sub classic_blacklist() { my $fw = firewall_zone; my @zones = off_firewall_zones; my @vservers = vserver_zones; - my @state = $config{BLACKLISTNEWONLY} ? $globals{UNTRACKED} ? state_imatch 'NEW,INVALID,UNTRACKED' : state_imatch 'NEW,INVALID' : (); + my @state = $config{BLACKLISTNEWONLY} ? have_capability( 'RAW_TABLE' ) ? state_imatch 'NEW,INVALID,UNTRACKED' : state_imatch 'NEW,INVALID' : (); my $result; for my $zone ( @zones ) { diff --git a/Shorewall/Perl/Shorewall/Tunnels.pm b/Shorewall/Perl/Shorewall/Tunnels.pm index 7fe7e3b72..7b27f8e59 100644 --- a/Shorewall/Perl/Shorewall/Tunnels.pm +++ b/Shorewall/Perl/Shorewall/Tunnels.pm @@ -61,7 +61,7 @@ sub setup_tunnels() { } } - my @options = $globals{UNTRACKED} ? state_imatch 'NEW,UNTRACKED' : state_imatch 'NEW'; + my @options = have_capability( 'RAW_TABLE' ) ? state_imatch 'NEW,UNTRACKED' : state_imatch 'NEW'; add_tunnel_rule $inchainref, p => 50, @$source; add_tunnel_rule $outchainref, p => 50, @$dest; diff --git a/Shorewall/Perl/Shorewall/Zones.pm b/Shorewall/Perl/Shorewall/Zones.pm index a3b0b243b..df9326c70 100644 --- a/Shorewall/Perl/Shorewall/Zones.pm +++ b/Shorewall/Perl/Shorewall/Zones.pm @@ -57,6 +57,7 @@ our @EXPORT = qw( NOTHING all_parent_zones complex_zones vserver_zones + on_firewall_zones off_firewall_zones non_firewall_zones single_interface @@ -117,7 +118,8 @@ use constant { IN_OUT => 1, # # @zones contains the ordered list of zones with sub-zones appearing before their parents. # -# %zones{ => {type => FIREWALL, IP, IPSEC, BPORT; +# %zones{ => {name => , +# type => FIREWALL, IP, IPSEC, BPORT; # complex => 0|1 # super => 0|1 # options => { in_out => < policy match string > @@ -838,6 +840,10 @@ sub all_zones() { @zones; } +sub on_firewall_zones() { + grep ( ( $zones{$_}{type} & ( FIREWALL | VSERVER ) ) , @zones ); +} + sub off_firewall_zones() { grep ( ! ( $zones{$_}{type} & ( FIREWALL | VSERVER ) ) , @zones ); } diff --git a/Shorewall/Samples/Universal/shorewall.conf b/Shorewall/Samples/Universal/shorewall.conf index d334682db..512802886 100644 --- a/Shorewall/Samples/Universal/shorewall.conf +++ b/Shorewall/Samples/Universal/shorewall.conf @@ -116,6 +116,8 @@ ADMINISABSENTMINDED=Yes AUTOCOMMENT=Yes +AUTOHELPERS=Yes + AUTOMAKE=No BLACKLISTNEWONLY=Yes diff --git a/Shorewall/Samples/one-interface/shorewall.conf b/Shorewall/Samples/one-interface/shorewall.conf index 38af1be72..6eabebf6d 100644 --- a/Shorewall/Samples/one-interface/shorewall.conf +++ b/Shorewall/Samples/one-interface/shorewall.conf @@ -127,6 +127,8 @@ ADMINISABSENTMINDED=Yes AUTOCOMMENT=Yes +AUTOHELPERS=Yes + AUTOMAKE=No BLACKLISTNEWONLY=Yes diff --git a/Shorewall/Samples/three-interfaces/shorewall.conf b/Shorewall/Samples/three-interfaces/shorewall.conf index e4f7b5142..9d6ba575f 100644 --- a/Shorewall/Samples/three-interfaces/shorewall.conf +++ b/Shorewall/Samples/three-interfaces/shorewall.conf @@ -125,6 +125,8 @@ ADMINISABSENTMINDED=Yes AUTOCOMMENT=Yes +AUTOHELPERS=Yes + AUTOMAKE=No BLACKLISTNEWONLY=Yes diff --git a/Shorewall/Samples/two-interfaces/shorewall.conf b/Shorewall/Samples/two-interfaces/shorewall.conf index 58ff0e882..2db35263c 100644 --- a/Shorewall/Samples/two-interfaces/shorewall.conf +++ b/Shorewall/Samples/two-interfaces/shorewall.conf @@ -128,6 +128,8 @@ ADMINISABSENTMINDED=Yes AUTOCOMMENT=Yes +AUTOHELPERS=Yes + AUTOMAKE=No BLACKLISTNEWONLY=Yes diff --git a/Shorewall/configfiles/shorewall.conf b/Shorewall/configfiles/shorewall.conf index 8d7f3a0df..68b6b97c7 100644 --- a/Shorewall/configfiles/shorewall.conf +++ b/Shorewall/configfiles/shorewall.conf @@ -116,6 +116,8 @@ ADMINISABSENTMINDED=Yes AUTOCOMMENT=Yes +AUTOHELPERS=Yes + AUTOMAKE=No BLACKLISTNEWONLY=Yes diff --git a/Shorewall/manpages/shorewall.conf.xml b/Shorewall/manpages/shorewall.conf.xml index 4cd86e8f6..ef09c1dd6 100644 --- a/Shorewall/manpages/shorewall.conf.xml +++ b/Shorewall/manpages/shorewall.conf.xml @@ -96,7 +96,7 @@ role="bold">none} - + @@ -106,7 +106,7 @@ role="bold">none} - + @@ -116,7 +116,7 @@ role="bold">none} - + @@ -126,7 +126,7 @@ role="bold">none} - + @@ -299,6 +299,49 @@ + + AUTOHELPERS=[Yes|No] + + + Added in Shorewall 4.5.8. When set to + (the default), the generated ruleset will automatically associate + helpers with applications that require them (FTP, IRC, etc.). When + configuring your firewall on systems running kernel 3.5 or later, it + is recommended that you: + + + + Set AUTOHELPERS=No. + + + + Either: + + + + Modify shorewall-conntrack + (5) to only apply helpers where they are required; or + + + + Specify the appropriate helper in the HELPER column in + shorewall-rules + (5). + + + The macros for those applications requiring a helper + automatically specify the appropriate HELPER where + required. + + + + + + + + AUTOMAKE=[Yes|No] @@ -482,7 +525,7 @@
- + If CONFIG_PATH is not given or if it is set to the empty value then the contents of /usr/share/shorewall/configpath are @@ -739,8 +782,8 @@ net all DROP infothen the chain name is 'net2all' When HELPERS is specified on a system running Kernel 3.5.0 or - later, automatic association of helpers to connections is disabled. - + later, automatic association of helpers to connections is + disabled. @@ -889,7 +932,7 @@ net all DROP infothen the chain name is 'net2all' - +
If this variable is not set or is given an empty value @@ -1099,7 +1142,7 @@ net all DROP infothen the chain name is 'net2all' - +
For example, using the default LOGFORMAT, the log prefix for @@ -1116,7 +1159,7 @@ net all DROP infothen the chain name is 'net2all' control your firewall after you enable this option. - + Do not use this option if the resulting log messages will @@ -1780,7 +1823,7 @@ net all DROP infothen the chain name is 'net2all' role="bold">" - + diff --git a/Shorewall6/Samples6/Universal/shorewall6.conf b/Shorewall6/Samples6/Universal/shorewall6.conf index af44a223e..826db4099 100644 --- a/Shorewall6/Samples6/Universal/shorewall6.conf +++ b/Shorewall6/Samples6/Universal/shorewall6.conf @@ -111,6 +111,8 @@ ADMINISABSENTMINDED=Yes AUTOCOMMENT=Yes +AUTOHELPERS=Yes + AUTOMAKE=No BLACKLISTNEWONLY=Yes diff --git a/Shorewall6/Samples6/one-interface/shorewall6.conf b/Shorewall6/Samples6/one-interface/shorewall6.conf index 5b2864e23..518ac9030 100644 --- a/Shorewall6/Samples6/one-interface/shorewall6.conf +++ b/Shorewall6/Samples6/one-interface/shorewall6.conf @@ -111,6 +111,8 @@ ADMINISABSENTMINDED=Yes AUTOCOMMENT=Yes +AUTOHELPERS=Yes + AUTOMAKE=No BLACKLISTNEWONLY=Yes diff --git a/Shorewall6/Samples6/three-interfaces/shorewall6.conf b/Shorewall6/Samples6/three-interfaces/shorewall6.conf index 3cf36656e..01b81f97f 100644 --- a/Shorewall6/Samples6/three-interfaces/shorewall6.conf +++ b/Shorewall6/Samples6/three-interfaces/shorewall6.conf @@ -111,6 +111,8 @@ ADMINISABSENTMINDED=Yes AUTOCOMMENT=Yes +AUTOHELPERS=Yes + AUTOMAKE=No BLACKLISTNEWONLY=Yes diff --git a/Shorewall6/Samples6/two-interfaces/shorewall6.conf b/Shorewall6/Samples6/two-interfaces/shorewall6.conf index 35beedfbd..0d9360a14 100644 --- a/Shorewall6/Samples6/two-interfaces/shorewall6.conf +++ b/Shorewall6/Samples6/two-interfaces/shorewall6.conf @@ -111,6 +111,8 @@ ADMINISABSENTMINDED=Yes AUTOCOMMENT=Yes +AUTOHELPERS=Yes + AUTOMAKE=No BLACKLISTNEWONLY=Yes diff --git a/Shorewall6/configfiles/shorewall6.conf b/Shorewall6/configfiles/shorewall6.conf index 096f64b58..946060722 100644 --- a/Shorewall6/configfiles/shorewall6.conf +++ b/Shorewall6/configfiles/shorewall6.conf @@ -111,6 +111,8 @@ ADMINISABSENTMINDED=Yes AUTOCOMMENT=Yes +AUTOHELPERS=Yes + AUTOMAKE=No BLACKLISTNEWONLY=Yes diff --git a/Shorewall6/manpages/shorewall6.conf.xml b/Shorewall6/manpages/shorewall6.conf.xml index 1eda02d4f..48d48d08b 100644 --- a/Shorewall6/manpages/shorewall6.conf.xml +++ b/Shorewall6/manpages/shorewall6.conf.xml @@ -82,7 +82,7 @@ role="bold">none} - + @@ -92,7 +92,7 @@ role="bold">none} - + @@ -102,7 +102,7 @@ role="bold">none} - + @@ -112,7 +112,7 @@ role="bold">none} - + @@ -228,6 +228,49 @@ + + AUTOHELPERS=[Yes|No] + + + Added in Shorewall 4.5.8. When set to + (the default), the generated ruleset will automatically associate + helpers with applications that require them (FTP, IRC, etc.). When + configuring your firewall on systems running kernel 3.5 or later, it + is recommended that you: + + + + Set AUTOHELPERS=No. + + + + Either: + + + + Modify shorewall6-conntrack + (5) to only apply helpers where they are required; or + + + + Specify the appropriate helper in the HELPER column in + shorewall6-rules + (5). + + + The macros for those applications requiring a helper + automatically specify the appropriate HELPER where + required. + + + + + + + + AUTOMAKE=[Yes|No] @@ -648,8 +691,8 @@ net all DROP infothen the chain name is 'net2all' When HELPERS is specified on a system running Kernel 3.5.0 or - later, automatic association of helpers to connections is disabled. - + later, automatic association of helpers to connections is + disabled. @@ -962,7 +1005,7 @@ net all DROP infothen the chain name is 'net2all' - +
For example, using the default LOGFORMAT, the log prefix for @@ -979,7 +1022,7 @@ net all DROP infothen the chain name is 'net2all' control your firewall after you enable this option. - + Do not use this option if the resulting log messages will @@ -1578,7 +1621,7 @@ net all DROP infothen the chain name is 'net2all' role="bold">" - + diff --git a/docs/upgrade_issues.xml b/docs/upgrade_issues.xml index 4216dc37d..654185c52 100644 --- a/docs/upgrade_issues.xml +++ b/docs/upgrade_issues.xml @@ -94,11 +94,11 @@ - This version of Shorewall requires the Digest::SHA1 Perl - module. + This version of Shorewall requires the Digest::SHA1 or the + Digest:SHA Perl module. - Debian: libdigest-sha1-perl + Debian: libdigest-sha-perl Fedora: perl-Digest-SHA1