Complete first attempt at AUDIT support

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2011-05-19 12:06:43 -07:00
parent 814494e277
commit 5e68dbfa9a
10 changed files with 107 additions and 177 deletions

View File

@ -224,6 +224,7 @@ our $VERSION = '4.4_20';
# action => <action tuple that generated this chain>
# restricted => Logical OR of restrictions of rules in this chain.
# restriction => Restrictions on further rules in this chain.
# audit => Audit the result.
# } ,
# <chain2> => ...
# }
@ -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;

View File

@ -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
#

View File

@ -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 );
}
}
}

View File

@ -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')

View File

@ -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')

View File

@ -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')

View File

@ -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.

View File

@ -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"

View File

@ -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
----------------------------------------------------------------------------

View File

@ -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."