diff --git a/Shorewall/Perl/Shorewall/Compiler.pm b/Shorewall/Perl/Shorewall/Compiler.pm index 9e6b01f98..7e221b48c 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; @@ -799,6 +794,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 232e716ab..d55a191c9 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 , ); diff --git a/Shorewall/Perl/Shorewall/Misc.pm b/Shorewall/Perl/Shorewall/Misc.pm index 16f2d796f..b31c8cdb5 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..cc3b78cba 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( process_conntrack_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,7 +41,7 @@ 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 ) = @_; @@ -122,9 +122,7 @@ sub process_notrack_rule( $$$$$$$ ) { $target , $exception_rule ); - progress_message " Notrack rule \"$currentline\" $done"; - - $globals{UNTRACKED} = 1; + progress_message " Conntrack rule \"$currentline\" $done"; } sub process_format( $ ) { @@ -135,7 +133,7 @@ sub process_format( $ ) { $format; } -sub setup_notrack() { +sub setup_conntrack() { my $format = 1; my $action = 'NOTRACK'; @@ -188,10 +186,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( $action, $zone, $dest, $proto, $ports, $sports, $user ); } } else { - process_notrack_rule( $action, $source, $dest, $proto, $ports, $sports, $user ); + process_conntrack_rule( $action, $source, $dest, $proto, $ports, $sports, $user ); } } diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index b868ebd36..bd8136678 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( process_conntrack_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 }; @@ -118,6 +121,10 @@ my %auditpolicies = ( ACCEPT => 1, REJECT => 1 ); # +# Source zone of the rule being processed +# +my $rulezone; +# # Rather than initializing globals in an INIT block or during declaration, # we initialize them in a function. This is done for two reasons: # @@ -1424,7 +1431,7 @@ sub process_actions() { } -sub process_rule1 ( $$$$$$$$$$$$$$$$$ ); +sub process_rule1 ( $$$$$$$$$$$$$$$$$$ ); # # Populate an action invocation chain. As new action tuples are encountered, @@ -1457,14 +1464,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 +1509,7 @@ sub process_action( $) { $time, $headers, $condition, + $helper, 0 ); } @@ -1531,8 +1539,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 +1558,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 +1643,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 +1676,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 +1693,7 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$ ) { $time, $headers, $condition, + $helper, $wildcard ) = @_; my ( $action, $loglevel) = split_action $target; @@ -1735,6 +1745,7 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$ ) { $time, $headers, $condition, + $helper, $wildcard ); $macro_nest_level--; @@ -1884,6 +1895,8 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$ ) { fatal_error "Missing source zone" if $sourcezone eq '-' || $sourcezone =~ /^:/; fatal_error "Unknown source zone ($sourcezone)" unless $sourceref = defined_zone( $sourcezone ); fatal_error 'USER/GROUP may only be specified when the SOURCE zone is $FW' unless $user eq '-' || $sourcezone eq firewall_zone; + + $rulezone = $sourcezone; } if ( $actiontype & NATONLY ) { @@ -2049,8 +2062,18 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$ ) { $rule, $source, ( $actiontype & ACTION ) ? '' : $loglevel, - $log_action - ); + $log_action, + ); + + unless ( $helper eq '-' ) { + process_conntrack_rule( "CT:helper:$helper" , + "$rulezone:$source", + $origdest, + $proto, + $ports, + $sports, + $user ); + } # # After NAT: # - the destination port will be the server port ($ports) -- we did that above @@ -2121,6 +2144,16 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$ ) { $loglevel , $log_action , '' ); + + if ( ! ( $helper eq '-' || ( $actiontype & NATRULE ) ) ) { + process_conntrack_rule( "CT:helper:$helper" , + "$rulezone:$source", + $origdest ? $origdest : $dest, + $proto, + $ports, + $sports, + $user ); + } } return 1; @@ -2224,7 +2257,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 +2314,7 @@ sub process_rule ( ) { $time, $headers, $condition, + $helper, $wild ); } } @@ -2305,7 +2339,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..87c667710 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 @@ -838,6 +839,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 ); }