forked from extern/shorewall_code
Complete first attempt at AUDIT support
Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
parent
814494e277
commit
5e68dbfa9a
@ -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;
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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')
|
@ -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')
|
@ -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')
|
||||
|
@ -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.
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
----------------------------------------------------------------------------
|
||||
|
@ -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."
|
||||
|
Loading…
Reference in New Issue
Block a user