diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index f05cb8e56..418c708b9 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -224,6 +224,7 @@ our $VERSION = '4.4_20'; # action => # restricted => Logical OR of restrictions of rules in this chain. # restriction => Restrictions on further rules in this chain. +# audit => Audit the result. # } , # => ... # } @@ -235,7 +236,7 @@ our $VERSION = '4.4_20'; # # Only 'referenced' chains get written to the iptables-restore input. # -# 'loglevel', 'synparams', 'synchain' and 'default' only apply to policy chains. +# 'loglevel', 'synparams', 'synchain', 'audit' and 'default' only apply to policy chains. # our %chain_table; our $raw_table; diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm index 01b2e9f8f..e6e153e9a 100644 --- a/Shorewall/Perl/Shorewall/Config.pm +++ b/Shorewall/Perl/Shorewall/Config.pm @@ -315,7 +315,7 @@ our %config_files = ( #accounting => 1, # # Options that involve the the AUDIT target # -my @auditoptions = qw( BLACKLIST_DISPOSITION MACLIST_DISPOSITION TCP_FLAGS_DISPOSITION ); +our @auditoptions = qw( BLACKLIST_DISPOSITION MACLIST_DISPOSITION TCP_FLAGS_DISPOSITION ); # # Directories to search for configuration files # diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index cd448fa53..7c4a544cb 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -95,12 +95,20 @@ my %actions; my %usedactions; # -# Enumerate the AUDIT policies and map them to their underlying polices +# Enumerate the AUDIT builtins # -my %auditpolicies = ( AACCEPT => 'ACCEPT', - ADROP => 'DROP', - AREJECT => 'REJECT' - ); +my %auditactions = ( AACCEPT => 1, + ADROP => 1, + AREJECT => 1 + ); + +# +# Policies for which AUDIT is allowed +# +my %auditpolicies = ( ACCEPT => 1, + DROP => 1, + REJECT => 1 + ); # # Rather than initializing globals in an INIT block or during declaration, @@ -168,9 +176,9 @@ sub initialize( $ ) { %usedactions = (); if ( $family == F_IPV4 ) { - @builtins = qw/dropBcast allowBcast dropNotSyn rejNotSyn dropInvalid allowInvalid allowinUPnP forwardUPnP Limit AUDIT AACCEPT ADROP AREJECT/; + @builtins = qw/dropBcast allowBcast dropNotSyn rejNotSyn dropInvalid allowInvalid allowinUPnP forwardUPnP Limit AACCEPT ADROP AREJECT/; } else { - @builtins = qw/dropBcast allowBcast dropNotSyn rejNotSyn dropInvalid allowInvalid AUDIT AACCEPT ADROP AREJECT/; + @builtins = qw/dropBcast allowBcast dropNotSyn rejNotSyn dropInvalid allowInvalid AACCEPT ADROP AREJECT/; } } @@ -193,13 +201,14 @@ sub get_target_param( $ ) { # # Convert a chain into a policy chain. # -sub convert_to_policy_chain($$$$$) +sub convert_to_policy_chain($$$$$$) { - my ($chainref, $source, $dest, $policy, $provisional ) = @_; + my ($chainref, $source, $dest, $policy, $provisional, $audit ) = @_; $chainref->{is_policy} = 1; $chainref->{policy} = $policy; $chainref->{provisional} = $provisional; + $chainref->{audit} = $audit; $chainref->{policychain} = $chainref->{name}; $chainref->{policypair} = [ $source, $dest ]; } @@ -207,13 +216,13 @@ sub convert_to_policy_chain($$$$$) # # Create a new policy chain and return a reference to it. # -sub new_policy_chain($$$$) +sub new_policy_chain($$$$$) { - my ($source, $dest, $policy, $provisional) = @_; + my ($source, $dest, $policy, $provisional, $audit) = @_; my $chainref = new_chain( 'filter', rules_chain( ${source}, ${dest} ) ); - convert_to_policy_chain( $chainref, $source, $dest, $policy, $provisional ); + convert_to_policy_chain( $chainref, $source, $dest, $policy, $provisional, $audit ); $chainref; } @@ -237,6 +246,7 @@ sub set_policy_chain($$$$$) # $chainref1->{policychain} = $chain1; $chainref1->{loglevel} = $chainref->{loglevel} if defined $chainref->{loglevel}; + $chainref1->{audit} = $chainref->{audit} if defined $chainref->{audit}; if ( defined $chainref->{synparams} ) { $chainref1->{synparams} = $chainref->{synparams}; @@ -260,18 +270,18 @@ sub set_policy_chain($$$$$) # use constant { PROVISIONAL => 1 }; -sub add_or_modify_policy_chain( $$ ) { - my ( $zone, $zone1 ) = @_; +sub add_or_modify_policy_chain( $$$ ) { + my ( $zone, $zone1, $audit ) = @_; my $chain = rules_chain( ${zone}, ${zone1} ); my $chainref = $filter_table->{$chain}; if ( $chainref ) { unless( $chainref->{is_policy} ) { - convert_to_policy_chain( $chainref, $zone, $zone1, 'CONTINUE', PROVISIONAL ); + convert_to_policy_chain( $chainref, $zone, $zone1, 'CONTINUE', PROVISIONAL, $audit ); push @policy_chains, $chainref; } } else { - push @policy_chains, ( new_policy_chain $zone, $zone1, 'CONTINUE', PROVISIONAL ); + push @policy_chains, ( new_policy_chain $zone, $zone1, 'CONTINUE', PROVISIONAL, $audit ); } } @@ -317,6 +327,10 @@ sub process_a_policy() { fatal_error "Undefined zone ($server)" unless $serverwild || defined_zone( $server ); + my $audit = ( $originalpolicy =~ s/:audit$// ); + + require_capability 'AUDIT_TARGET', ":audit", "s" if $audit; + my ( $policy, $default, $remainder ) = split( /:/, $originalpolicy, 3 ); fatal_error "Invalid or missing POLICY ($originalpolicy)" unless $policy; @@ -325,6 +339,10 @@ sub process_a_policy() { ( $policy , my $queue ) = get_target_param $policy; + fatal_error "Invalid policy ($policy)" unless exists $validpolicies{$policy}; + + fatal_error "A $policy policy may not be audited" unless $auditpolicies{$policy}; + if ( $default ) { if ( "\L$default" eq 'none' ) { $default = 'none'; @@ -334,12 +352,10 @@ sub process_a_policy() { fatal_error "Unknown Default Action ($default)"; } } else { - $default = $default_actions{$auditpolicies{$policy} || $policy} || ''; + $default = $default_actions{$policy} || ''; } - use_policy_action $policy if $auditpolicies{$policy}; - - fatal_error "Invalid policy ($policy)" unless exists $validpolicies{$policy}; + use_policy_action $policy if $auditactions{$policy}; if ( defined $queue ) { fatal_error "Invalid policy ($policy($queue))" unless $policy eq 'NFQUEUE'; @@ -377,11 +393,11 @@ sub process_a_policy() { } elsif ( $chainref->{policy} ) { fatal_error qq(Policy "$client $server $policy" duplicates earlier policy "@{$chainref->{policypair}} $chainref->{policy}"); } else { - convert_to_policy_chain( $chainref, $client, $server, $policy, 0 ); + convert_to_policy_chain( $chainref, $client, $server, $policy, 0 , $audit ); push @policy_chains, ( $chainref ) unless $config{EXPAND_POLICIES} && ( $clientwild || $serverwild ); } } else { - $chainref = new_policy_chain $client, $server, $policy, 0; + $chainref = new_policy_chain $client, $server, $policy, 0, $audit; push @policy_chains, ( $chainref ) unless $config{EXPAND_POLICIES} && ( $clientwild || $serverwild ); } @@ -486,16 +502,16 @@ sub process_policies() } for $zone ( all_zones ) { - push @policy_chains, ( new_policy_chain $zone, $zone, 'ACCEPT', PROVISIONAL ); - push @policy_chains, ( new_policy_chain firewall_zone, $zone, 'NONE', PROVISIONAL ) if zone_type( $zone ) == BPORT; + push @policy_chains, ( new_policy_chain $zone, $zone, 'ACCEPT', PROVISIONAL, 0 ); + push @policy_chains, ( new_policy_chain firewall_zone, $zone, 'NONE', PROVISIONAL, 0 ) if zone_type( $zone ) == BPORT; my $zoneref = find_zone( $zone ); if ( $config{IMPLICIT_CONTINUE} && ( @{$zoneref->{parents}} || $zoneref->{type} == VSERVER ) ) { for my $zone1 ( all_zones ) { unless( $zone eq $zone1 ) { - add_or_modify_policy_chain( $zone, $zone1 ); - add_or_modify_policy_chain( $zone1, $zone ); + add_or_modify_policy_chain( $zone, $zone1, 0 ); + add_or_modify_policy_chain( $zone1, $zone , 0 ); } } } @@ -526,7 +542,8 @@ sub policy_rules( $$$$$ ) { add_jump $chainref, $default, 0 if $default && $default ne 'none'; log_rule $loglevel , $chainref , $target , '' if $loglevel ne ''; fatal_error "Null target in policy_rules()" unless $target; - + + add_rule( $chainref , '-j AUDIT --type ' . lc $target ) if $chainref->{audit}; add_jump( $chainref , $target eq 'REJECT' ? 'reject' : $target, 1 ) unless $target eq 'CONTINUE'; } } @@ -1291,17 +1308,6 @@ sub Limit( $$$$ ) { add_rule $chainref, '-j ACCEPT'; } -sub AUDIT( $$$$) { - my ($chainref, $level, $tag, $type ) = @_; - - require_capability 'AUDIT_TARGET' , 'AUDIT rules', ''; - - fatal_error "Logging is not permitted in the AUDIT action" if $level; - fatal_error "AUDIT requires a 'type' parameter"; - fatal_error "Invalid AUDIT type ($type)" unless $type =~ /^(accept|drop|reject)$/; - add_rule $chainref , "-j AUDIT --type $type"; -} - sub AACCEPT ( $$$ ) { my ($chainref, $level, $tag) = @_; @@ -1341,7 +1347,6 @@ my %builtinops = ( 'dropBcast' => \&dropBcast, 'allowinUPnP' => \&allowinUPnP, 'forwardUPnP' => \&forwardUPnP, 'Limit' => \&Limit, - 'AUDIT' => \&AUDIT, 'AACCEPT' => \&AACCEPT, 'ADROP' => \&ADROP, 'AREJECT' => \&AREJECT @@ -1481,9 +1486,13 @@ sub process_actions2 () { my $ref; - for ( map normalized_action_name $_, grep $auditpolicies{$config{$_}}, @auditoptions ) { - if ( $ref = use_action( $_ ) ) { - process_action( $ref ); + for my $option ( @auditoptions ) { + my $action = $config{ $option }; + + if ( $auditactions{$action} ) { + if ( $ref = use_action( normalize_action_name $action ) ) { + process_action( $ref ); + } } } diff --git a/Shorewall/action.AAccept b/Shorewall/action.AAccept deleted file mode 100644 index 4852d5c1e..000000000 --- a/Shorewall/action.AAccept +++ /dev/null @@ -1,14 +0,0 @@ -# -# Shorewall version 4 - Audit Accept Action -# -# /usr/share/shorewall/action.AAccept -# -# Specify this as the ACCEPT_ACTION if you want ACCEPT policies to be -# Audited -# -############################################################################### -#TARGET SOURCE DEST PROTO DPORT SPORT -# -# Audit the result -# -AUDIT('accept') diff --git a/Shorewall/action.ADrop b/Shorewall/action.ADrop deleted file mode 100644 index b69f65b8c..000000000 --- a/Shorewall/action.ADrop +++ /dev/null @@ -1,60 +0,0 @@ -# -# Shorewall version 4 - Drop Action -# -# /usr/share/shorewall/action.ADrop -# -# Like action.Drop but also Audits -# -# This action is invoked before a DROP policy is enforced. The purpose -# of the action is: -# -# a) Avoid logging lots of useless cruft. -# b) Ensure that 'auth' requests are rejected, even if the policy is -# DROP. Otherwise, you may experience problems establishing -# connections with servers that use auth. -# c) Ensure that certain ICMP packets that are necessary for successful -# internet operation are always ACCEPTed. -# -# IF YOU ARE HAVING CONNECTION PROBLEMS, CHANGING THIS FILE WON'T HELP!!!!!!!!! -# -############################################################################### -#TARGET SOURCE DEST PROTO DPORT SPORT -# -# Count packets that come through here -# -COUNT -# -# Reject 'auth' -# -Auth(REJECT) -# -# Don't log broadcasts -# -dropBcast -# -# ACCEPT critical ICMP types -# -AllowICMPs - - icmp -# -# Drop packets that are in the INVALID state -- these are usually ICMP packets -# and just confuse people when they appear in the log. -# -dropInvalid -# -# Drop Microsoft noise so that it doesn't clutter up the log. -# -SMB(DROP) -DropUPnP -# -# Drop 'newnotsyn' traffic so that it doesn't get logged. -# -dropNotSyn - - tcp -# -# Drop late-arriving DNS replies. These are just a nuisance and clutter up -# the log. -# -DropDNSrep -# -# Audit the result -# -AUDIT('drop') diff --git a/Shorewall/action.AReject b/Shorewall/action.AReject deleted file mode 100644 index dd739ee17..000000000 --- a/Shorewall/action.AReject +++ /dev/null @@ -1,59 +0,0 @@ -# -# Shorewall version 4 - AReject Action -# -# /usr/share/shorewall/action.Reject -# -# This action is like Reject only it also audits -# -# This action is invoked before a REJECT policy is enforced. The purpose -# of the action is: -# -# a) Avoid logging lots of useless cruft. -# b) Ensure that certain ICMP packets that are necessary for successful -# internet operation are always ACCEPTed. -# -# IF YOU ARE HAVING CONNECTION PROBLEMS, CHANGING THIS FILE WON'T HELP!!!!!!!!! -############################################################################### -#TARGET SOURCE DEST PROTO -# -# Count packets that come through here -# -COUNT -# -# Don't log 'auth' -- REJECT -# -Auth(REJECT) -# -# Drop Broadcasts so they don't clutter up the log -# (broadcasts must *not* be rejected). -# -dropBcast -# -# ACCEPT critical ICMP types -# -AllowICMPs - - icmp -# -# Drop packets that are in the INVALID state -- these are usually ICMP packets -# and just confuse people when they appear in the log (these ICMPs cannot be -# rejected). -# -dropInvalid -# -# Reject Microsoft noise so that it doesn't clutter up the log. -# -SMB(REJECT) -DropUPnP -# -# Drop 'newnotsyn' traffic so that it doesn't get logged. -# -dropNotSyn - - tcp -# -# Drop late-arriving DNS replies. These are just a nuisance and clutter up -# the log. -# -DropDNSrep -# -# Audit the result -# -AUDIT('reject') - diff --git a/Shorewall/changelog.txt b/Shorewall/changelog.txt index 7d53e7790..8fad5838f 100644 --- a/Shorewall/changelog.txt +++ b/Shorewall/changelog.txt @@ -1,3 +1,7 @@ +Changes in Shorewall 4.4.20 Beta 3 + +1) Add auditing support. + Changes in Shorewall 4.4.20 Beta 2 1) Use 'my' for module globals unless variable is exported. diff --git a/Shorewall/lib.cli b/Shorewall/lib.cli index a4d983aa5..cb87829d6 100644 --- a/Shorewall/lib.cli +++ b/Shorewall/lib.cli @@ -739,6 +739,9 @@ show_command() { case $1 in actions) [ $# -gt 1 ] && usage 1 + echo "AACCEPT # Audit and accept the connection" + echo "ADROP # Audit and drop the connection" + echo "AREJECT # Audit and reject the connection " echo "allowBcast # Silently Allow Broadcast/multicast" echo "allowInvalid # Accept packets that are in the INVALID conntrack state." echo "allowinUPnP # Allow UPnP inbound (to firewall) traffic" diff --git a/Shorewall/releasenotes.txt b/Shorewall/releasenotes.txt index 816b29d1a..cee746311 100644 --- a/Shorewall/releasenotes.txt +++ b/Shorewall/releasenotes.txt @@ -58,6 +58,49 @@ All bug fixes from 4.4.19.1 - 4.4.19.4. are not matched against the entries which follow. No logging of whitelisted packets/connections is performed. +5) Support for the AUDIT target has been added. AUDIT is a feature of + the 2.6.39 kernel and iptables 1.4.10 that allows security auditing + of access decisions. + + Note: This support note is the only documentation of this support + currently available. + + The support involves the following: + + a) A new "Audit Target" capability is added and is required for + auditing support. To use AUDIT support with a capabilities + file, that file must be generated using this or a later + release. + + Use 'shorewall show capabilities' after installing this release + to see if your kernel/iptables support the AUDIT target. + + b) In /etc/shorewall/policy's POLICY column, the policy (and + default action, if any) may be followed by ':audit' to cause + application of the policy to be audited. + + It is allowed to also specify a log level on audited policies + resulting in both auditing and logging. + + c) Three new builtin actions that may be used in the rules file, + in macros and in other actions. + + AACCEPT - Audits and accepts the connection request + ADROP - Audits and drops the connection request + AREJECT - Audits and rejects + + It is allowed to specify a log level with these actions to + provide both auditing and logging. + + d) The BLACKLIST_DISPOSITION, MACLIST_DISPOSITION and + TCP_FLAGS_DISPOSITION options may be set as follows: + + BLACKLIST_DISPOSITION ADROP or AREJECT + MACLIST_DISPOSITION ADROP + AREJECT, unless + MACLIST_TABLE=mangle + TCP_FLAGS_DISPOSITION ADROP or AREJECT + ---------------------------------------------------------------------------- I V. R E L E A S E 4 . 4 H I G H L I G H T S ---------------------------------------------------------------------------- diff --git a/Shorewall6/lib.cli b/Shorewall6/lib.cli index cb8b309f1..26bac9009 100644 --- a/Shorewall6/lib.cli +++ b/Shorewall6/lib.cli @@ -630,6 +630,9 @@ show_command() { case $1 in actions) [ $# -gt 1 ] && usage 1 + echo "AACCEPT # Audit and accept the connection" + echo "ADROP # Audit and drop the connection" + echo "AREJECT # Audit and reject the connection " 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."