mirror of
https://gitlab.com/shorewall/code.git
synced 2024-11-27 10:03:41 +01:00
67589cab69
Signed-off-by: Tom Eastep <teastep@shorewall.net>
140 lines
5.0 KiB
Plaintext
140 lines
5.0 KiB
Plaintext
#
|
|
# Shorewall version 5 - Perform an Action based on a Event
|
|
#
|
|
# /etc/shorewall/action.IfEvent
|
|
#
|
|
# Parameters:
|
|
# Event: Must start with a letter and be composed of letters, digits, '-', and '_'.
|
|
# Action: Anything that can appear in the ACTION column of a rule.
|
|
# Duration: Duration in seconds over which the event is to be tested.
|
|
# Hit Count: Number of packets seen within the duration -- default is 1
|
|
# Src or Dest: 'src' (default) or 'dst'. Determines if the event is associated with the source
|
|
# address (src) or destination address (dst)
|
|
# Command: 'check' (default) 'reset', or 'update'. If 'reset', the event will be reset before
|
|
# the Action is taken. If 'update', the timestamp associated with the event will
|
|
# be updated and the action taken if the time limit/hitcount are matched.
|
|
# If '-', the action will be taken if the limit/hitcount are matched but the
|
|
# event's timestamp will not be updated.
|
|
#
|
|
# If a duration is specified, then 'checkreap' and 'updatereap' may also
|
|
# be used. These are like 'check' and 'update' respectively, but they also
|
|
# remove any event entries for the IP address that are older than <duration>
|
|
# seconds.
|
|
# Disposition: Disposition for any event generated.
|
|
#
|
|
# For additional information, see http://www.shorewall.net/Events.html
|
|
#
|
|
#######################################################################################################
|
|
# DO NOT REMOVE THE FOLLOWING LINE
|
|
?format 2
|
|
#################################################################################################################################################################################################
|
|
#ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE USER/ MARK CONNLIMIT TIME HEADERS SWITCH HELPER
|
|
# PORT PORT(S) DEST LIMIT GROUP
|
|
|
|
DEFAULTS -,ACCEPT,-,1,src,check,-
|
|
|
|
?begin perl
|
|
|
|
use Shorewall::Config qw(:DEFAULT :internal);
|
|
use Shorewall::Chains;
|
|
use Shorewall::Rules;
|
|
use strict;
|
|
|
|
my ( $event, $action, $duration, $hitcount, $destination, $command, $disposition ) = get_action_params( 7 );
|
|
|
|
fatal_error "An event name is required" unless supplied $event;
|
|
fatal_error "Invalid event name ($event)" unless $event =~ /^[a-zA-z][-\w]*$/;
|
|
|
|
if ( supplied $duration ) {
|
|
fatal_error "Invalid time limit ($duration)" unless $duration =~ /^\d+$/;
|
|
$duration = "--seconds $duration ";
|
|
} else {
|
|
$duration = '';
|
|
}
|
|
|
|
fatal_error "Invalid hit count ($hitcount)" unless $hitcount =~ /^\d+$/;
|
|
fatal_error "Invalid Src or Dest ($destination)" unless $destination =~ /^(?:src|dst)$/;
|
|
|
|
my $srcdst = $destination eq 'src'? '--rsource' : '--rdest';
|
|
|
|
our $commands_defined;
|
|
|
|
#
|
|
# Can't 'use constant' here
|
|
#
|
|
my ( $UPDATE_CMD, $CHECK_CMD, $RESET_CMD, $REAP_OPT, $TTL_OPT ) = ( 1, 2, 4, 8, 16 );
|
|
|
|
my %command = ( check => $CHECK_CMD,
|
|
update => $UPDATE_CMD,
|
|
reset => $RESET_CMD
|
|
);
|
|
|
|
my %commandopts = (
|
|
reap => $REAP_OPT,
|
|
ttl => $TTL_OPT
|
|
);
|
|
|
|
my @command = split(':', $command);
|
|
|
|
$command = $command{shift @command} || 0;
|
|
|
|
fatal_error "Command must be 'check', 'update' or 'reset" unless $command & ( $CHECK_CMD | $UPDATE_CMD | $RESET_CMD);
|
|
|
|
for ( @command ) {
|
|
fatal_error "Invalid command option ($_)" unless $commandopts{$_};
|
|
if ( $command & $commandopts{$_} ) {
|
|
warning_message "Duplicate command ($_)";
|
|
} else {
|
|
$command |= $commandopts{$_};
|
|
}
|
|
}
|
|
|
|
my $duplicate;
|
|
|
|
set_action_disposition( $disposition) if supplied $disposition;
|
|
set_action_name_to_caller;
|
|
|
|
require_capability 'RECENT_MATCH', 'Use of events', 's';
|
|
|
|
if ( $command & $REAP_OPT ) {
|
|
require_capability( 'REAP_OPTION', q(The 'reap' option), 's' );
|
|
fatal_error "${command}reap requires a time limit" unless $duration;
|
|
$duration .= '--reap ';
|
|
}
|
|
|
|
$duration .= '--rttl ' if $command & $TTL_OPT;
|
|
|
|
if ( $command & $RESET_CMD ) {
|
|
require_capability 'MARK_ANYWHERE', '"reset"', 's';
|
|
|
|
print "Resetting....\n";
|
|
|
|
my $mark = $globals{EVENT_MARK};
|
|
#
|
|
# The event mark bit must be within 32 bits
|
|
#
|
|
fatal_error "The mark layout does not permit resetting of events" unless $mark & 0xffffffff;
|
|
#
|
|
# Reset the event mark bit
|
|
#
|
|
perl_action_helper( 'INLINE', '-j MARK --and-mark '. in_hex( (~ $mark ) & 0xffffffff ) );
|
|
|
|
$mark = in_hex $mark;
|
|
#
|
|
# Mark the packet if event is armed
|
|
#
|
|
perl_action_helper( 'INLINE', "-m recent --rcheck ${duration}--hitcount $hitcount --name $event $srcdst -j MARK --or-mark $mark" );
|
|
#
|
|
# if the event is armed, remove it and perform the action
|
|
#
|
|
perl_action_helper( $action , "-m mark --mark $mark/$mark -m recent --remove --name $event" );
|
|
} elsif ( $command & $UPDATE_CMD ) {
|
|
perl_action_helper( $action, "-m recent --update ${duration}--hitcount $hitcount --name $event $srcdst" );
|
|
} else {
|
|
perl_action_helper( $action, "-m recent --rcheck ${duration}--hitcount $hitcount --name $event $srcdst" );
|
|
}
|
|
|
|
1;
|
|
|
|
?end perl
|