to the corresponding Snort 'msg' field. Added the FWSNORT_RULES_DIR
variable to have psad read Snort rules from any installed fwsnort
instance.
+
+Oscar Marley
+ - Suggested configurable auto-blocking timeout values depending on the
+ danger level that a scan or attack achieves. This resulted in the
+ implementation of the AUTO_BLOCK_DL*_TIMEOUT variables.
my %auto_dl = ();
my %auto_dl_ip_objs = ();
my %auto_assigned_msg = ();
+my $PERMANENT = 0;
### cache the source ips that we have automatically blocked
### (if ENABLE_AUTO_IDS == 'Y')
### Extract data and summarize scan packets, assign danger level,
### send email/syslog alerts.
&check_scan(\@fw_packets);
-
}
### log top scans data
### Timeout any auto-blocked IPs that are past due (need to
### check the timeouts against existing IPs in the scan hash
### even if new packets are not found).
- if ($config{'AUTO_BLOCK_TIMEOUT'} > 0) {
- &timeout_auto_blocked_ips();
- }
+ &timeout_auto_blocked_ips();
### see if we need to add any IP address from the domain
### socket
if $config{'ENABLE_AUTO_IDS'} eq 'Y'
and (not $analyze_mode or $analyze_mode_auto_block);
+ if ($config{'ENABLE_AUTO_IDS'} eq 'Y' and $analyze_mode_auto_block) {
+ sleep $config{'AUTO_BLOCK_TIMEOUT'} + 1;
+ &timeout_auto_blocked_ips();
+ }
+
if ($log_scan_ip_pair_max) {
&sys_log("scan IP pairs threshold reached");
}
exit $rv;
}
+ &dump_conf() if $test_mode;
+
### make sure all necessary configuration variables
### are defined
&required_vars();
}
sub renew_auto_blocked_ips() {
+
+ ### note that if we are renewing IP blocking rules, we just use
+ ### the AUTO_BLOCK_TIMEOUT value initially and then the AUTO_BLOCK_DLN...
+ ### values will take over as psad gets up and running
my $timeout_str = '.';
if ($config{'AUTO_BLOCK_TIMEOUT'} > 0) {
$timeout_str = "for $config{'AUTO_BLOCK_TIMEOUT'} seconds.";
} else {
$timeout_str = '(unlimited time).';
}
+
if ($config{'IPTABLES_BLOCK_METHOD'} eq 'Y'
and -e $config{'AUTO_BLOCK_IPT_FILE'}) {
open B, "< $config{'AUTO_BLOCK_IPT_FILE'}" or
my $block_success = 0;
my $already_blocked = 0;
- my $timeout_str = '';
- if ($config{'AUTO_BLOCK_TIMEOUT'} > 0) {
- $timeout_str = "for $config{'AUTO_BLOCK_TIMEOUT'} seconds";
- } else {
- $timeout_str = '(unlimited timeout)';
- }
+ my ($timeout, $timeout_str) = &get_block_timeout($scan_dl{$ip});
if ($config{'IPTABLES_PREREQ_CHECK'} > 1) {
$iptables_prereq_check++;
next SRC if defined $auto_blocked_ips{$src};
- my $timeout_str = '';
- if ($config{'AUTO_BLOCK_TIMEOUT'} > 0) {
- $timeout_str = "for $config{'AUTO_BLOCK_TIMEOUT'} seconds.";
- } else {
- $timeout_str = '(unlimited timeout).';
- }
+ my ($timeout, $timeout_str) = &get_block_timeout($dl);
+
### we have seen at least one packet logged by the firewall
### at this point
if ($config{'IPTABLES_BLOCK_METHOD'} eq 'Y') {
return 0;
}
+sub get_block_timeout() {
+ my $dl = shift;
+
+ my $timeout = $config{'AUTO_BLOCK_DL1_TIMEOUT'};
+ if ($dl == 2) {
+ $timeout = $config{'AUTO_BLOCK_DL2_TIMEOUT'};
+ } elsif ($dl == 3) {
+ $timeout = $config{'AUTO_BLOCK_DL3_TIMEOUT'};
+ } elsif ($dl == 4) {
+ $timeout = $config{'AUTO_BLOCK_DL4_TIMEOUT'};
+ } elsif ($dl == 5) {
+ $timeout = $config{'AUTO_BLOCK_DL5_TIMEOUT'};
+ }
+
+ my $timeout_str = "for $timeout seconds";
+ $timeout_str = '(unlimited timeout)' if $timeout == $PERMANENT;
+
+ return ($timeout, $timeout_str);
+}
+
sub timeout_auto_blocked_ips() {
- print STDERR "[+] timeout_auto_block_ips()\n" if $debug;
- return if $config{'AUTO_BLOCK_TIMEOUT'} == 0;
+
+ print STDERR "[+] timeout_auto_block_ips()\n" if $debug or $test_mode;
+
for my $ip (keys %auto_blocked_ips) {
- if ((time() - $auto_blocked_ips{$ip})
- > $config{'AUTO_BLOCK_TIMEOUT'}) {
+ my ($timeout, $timeout_str) = &get_block_timeout($scan_dl{$ip});
+ next if $timeout == $PERMANENT;
+
+ if ((time() - $auto_blocked_ips{$ip}) > $timeout) {
### remove all Netfiler blocking rules for $ip
if ($config{'IPTABLES_BLOCK_METHOD'} eq 'Y') {
### older versions do not have the timestamp
if ($line =~ /^\s*\S+\s+(\d+)/) {
$timestamp = $1;
- if ($config{'AUTO_BLOCK_TIMEOUT'} > 0) {
- $time_remain = $config{'AUTO_BLOCK_TIMEOUT'}
- - (time() - $timestamp);
+ my ($timeout, $timeout_str) = &get_block_timeout($scan_dl{$ip});
+ if ($timeout > 0) {
+ $time_remain = $timeout - (time() - $timestamp);
$time_remain = 0 if $time_remain < 0;
push @print_lines, " $ip ($time_remain ",
ENABLE_WHOIS_FORCE_SRC_IP ENABLE_IPV6_DETECTION
PERSISTENCE_CTR_THRESHOLD MAX_SCAN_IP_PAIRS INSTALL_ROOT
ICMP6_TYPES_FILE PROTOCOL_SCAN_THRESHOLD PROTOCOLS_FILE
+ AUTO_BLOCK_DL1_TIMEOUT AUTO_BLOCK_DL2_TIMEOUT
+ AUTO_BLOCK_DL3_TIMEOUT AUTO_BLOCK_DL4_TIMEOUT
+ AUTO_BLOCK_DL5_TIMEOUT
));
&defined_vars(\@required_vars);
return;
### is one hour).
AUTO_BLOCK_TIMEOUT 3600;
+### Set the auto-blocked timeout in seconds for each danger
+### level - zero means to block permanently. Each of these
+### can be set independently
+AUTO_BLOCK_DL1_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL2_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL3_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL4_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL5_TIMEOUT 0; ### permanent
+
### Enable regex checking on log prefixes for active response
ENABLE_AUTO_IDS_REGEX N;
### Block all traffic from offending IP if danger
### level >= to this value
-AUTO_IDS_DANGER_LEVEL 5;
+AUTO_IDS_DANGER_LEVEL 3;
### Set the auto-blocked timeout in seconds (the default
### is one hour).
AUTO_BLOCK_TIMEOUT 3;
+### Set the auto-blocked timeout in seconds for each danger
+### level - zero means to block permanently. Each of these
+### can be set independently
+AUTO_BLOCK_DL1_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL2_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL3_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL4_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL5_TIMEOUT 0; ### permanent
+
### Enable regex checking on log prefixes for active response
ENABLE_AUTO_IDS_REGEX N;
### is one hour).
AUTO_BLOCK_TIMEOUT 3600;
+### Set the auto-blocked timeout in seconds for each danger
+### level - zero means to block permanently. Each of these
+### can be set independently
+AUTO_BLOCK_DL1_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL2_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL3_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL4_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL5_TIMEOUT 0; ### permanent
+
### Enable regex checking on log prefixes for active response
ENABLE_AUTO_IDS_REGEX N;
### is one hour).
AUTO_BLOCK_TIMEOUT 3600;
+### Set the auto-blocked timeout in seconds for each danger
+### level - zero means to block permanently. Each of these
+### can be set independently
+AUTO_BLOCK_DL1_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL2_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL3_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL4_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL5_TIMEOUT 0; ### permanent
+
### Enable regex checking on log prefixes for active response
ENABLE_AUTO_IDS_REGEX N;
### is one hour).
AUTO_BLOCK_TIMEOUT 3600;
+### Set the auto-blocked timeout in seconds for each danger
+### level - zero means to block permanently. Each of these
+### can be set independently
+AUTO_BLOCK_DL1_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL2_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL3_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL4_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL5_TIMEOUT 0; ### permanent
+
### Enable regex checking on log prefixes for active response
ENABLE_AUTO_IDS_REGEX N;
### is one hour).
AUTO_BLOCK_TIMEOUT 3600;
+### Set the auto-blocked timeout in seconds for each danger
+### level - zero means to block permanently. Each of these
+### can be set independently
+AUTO_BLOCK_DL1_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL2_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL3_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL4_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL5_TIMEOUT 0; ### permanent
+
### Enable regex checking on log prefixes for active response
ENABLE_AUTO_IDS_REGEX N;
### is one hour).
AUTO_BLOCK_TIMEOUT 3600;
+### Set the auto-blocked timeout in seconds for each danger
+### level - zero means to block permanently. Each of these
+### can be set independently
+AUTO_BLOCK_DL1_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL2_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL3_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL4_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL5_TIMEOUT 0; ### permanent
+
### Enable regex checking on log prefixes for active response
ENABLE_AUTO_IDS_REGEX N;
### is one hour).
AUTO_BLOCK_TIMEOUT 3600;
+### Set the auto-blocked timeout in seconds for each danger
+### level - zero means to block permanently. Each of these
+### can be set independently
+AUTO_BLOCK_DL1_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL2_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL3_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL4_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL5_TIMEOUT 0; ### permanent
+
### Enable regex checking on log prefixes for active response
ENABLE_AUTO_IDS_REGEX N;
### is one hour).
AUTO_BLOCK_TIMEOUT 3600;
+### Set the auto-blocked timeout in seconds for each danger
+### level - zero means to block permanently. Each of these
+### can be set independently
+AUTO_BLOCK_DL1_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL2_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL3_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL4_TIMEOUT $AUTO_BLOCK_TIMEOUT;
+AUTO_BLOCK_DL5_TIMEOUT 0; ### permanent
+
### Enable regex checking on log prefixes for active response
ENABLE_AUTO_IDS_REGEX N;
my $ignore_udp_conf = "$conf_dir/ignore_udp.conf";
my $ignore_tcp_conf = "$conf_dir/ignore_tcp.conf";
my $auto_blocking_conf = "$conf_dir/auto_blocking.conf";
+my $auto_dl5_blocking_conf = "$conf_dir/auto_min_dl5_blocking.conf";
my $require_prefix_conf = "$conf_dir/require_DROP_syslog_prefix_str.conf";
my $require_missing_prefix_conf = "$conf_dir/require_missing_syslog_prefix_str.conf";
my $enable_ack_detection_conf = "$conf_dir/enable_ack_detection.conf";
{
'category' => 'operations',
'detail' => 'DL5 IPv4 <BLOCK> SYN scan',
- 'err_msg' => 'did not set SYN scan source to DL5',
+ 'err_msg' => 'did not block scan src',
'positive_output_matches' => [qr/Top\s\d+\sattackers/i,
qr/scanned\sports.*?1000\-1500/i,
qr/IP\sstatus/i,
qr/192\.168\.10\.55,\sDL\:\s5/,
qr/DROP\s.*192\.168\.10\.55/,
qr/Flushing\sand\sdeleting\spsad\schains/,
+ qr/unlimited\stime/,
],
'match_all' => $MATCH_ALL_RE,
'function' => \&generic_exec,
'cmdline' => "$psadCmd --test-mode -A --analysis-write-data --auto-dl $dl5_ipv4_auto_dl_file " .
+ "-m $scans_dir/" . &fw_type() . "/$syn_scan_file -c $auto_dl5_blocking_conf " .
+ "$normal_root_override_str --analysis-auto-block",
+ 'auto_block_test' => $YES,
+ 'exec_err' => $NO,
+ 'fatal' => $NO
+ },
+ {
+ 'category' => 'operations',
+ 'detail' => 'IPv4 <BLOCK> SYN scan',
+ 'err_msg' => 'did not block scan src',
+ 'positive_output_matches' => [qr/Top\s\d+\sattackers/i,
+ qr/scanned\sports.*?1000\-1500/i,
+ qr/IP\sstatus/i,
+ qr/192\.168\.10\.55,\sDL\:\s3/,
+ qr/DROP\s.*192\.168\.10\.55/,
+ qr/Flushing\sand\sdeleting\spsad\schains/,
+ qr/for\s3\sseconds/,
+ qr/removed\siptables\sblock/,
+ ],
+ 'match_all' => $MATCH_ALL_RE,
+ 'function' => \&generic_exec,
+ 'cmdline' => "$psadCmd --test-mode -A --analysis-write-data " .
"-m $scans_dir/" . &fw_type() . "/$syn_scan_file -c $auto_blocking_conf " .
"$normal_root_override_str --analysis-auto-block",
'auto_block_test' => $YES,