-
Notifications
You must be signed in to change notification settings - Fork 1
/
asterisk-failed-regs.pl
136 lines (117 loc) · 3.29 KB
/
asterisk-failed-regs.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/perl -w
#
# Created 2008
# Fred Posner <fred@qxork.com>
# Last Updated August 2015.
#
# Find attempts and block them in iptables.
#
use strict;
use warnings;
#
# Definitions listed individually for I can't remember why.
#
# failhost will be an array of matching ip addresses from the log
# currblocked is a hash of currently blocked ip addresses
# addblocked checks failhost
# action runs system commands
# logfile is (shockingly) the log file to read
# date holds the date value, formatted as desired.
# rotate is a simple counter (0/1) for rotating log.
#
my (@failhost);
my %currblocked;
my %addblocked;
my $action;
my $logfile;
my $date = &get_date;
my $rotate = 0;
#
# Check if log file has been passed, if not
# use default messages file
#
if ($ARGV[0]) {
$logfile = $ARGV[0];
} else {
$logfile = "/var/log/asterisk/messages";
}
#
# open log file
# and grep each line for trouble
#
open (MYINPUTFILE, "$logfile") or die "\n", $!, "Does $logfile exist\?\n\n";
while (<MYINPUTFILE>) {
my ($line) = $_;
chomp($line);
# registrations for peers that don't exist
if ($line =~ m/\' failed for \'(.*?)\' - No matching peer found/) {
push(@failhost,$1);
}
# bad passwords / etc.
elsif ($line =~ m/\' failed for \'(.*?):/) {
push(@failhost,$1);
}
# bad calls to default context
elsif ($line =~ m/\((.*?):(.*?)\) to extension \'(.*?)\' rejected because extension not found in context \'default\'/) {
push(@failhost,$1);
}
elsif ($line =~ m/\((.*?):(.*?)\) to extension \'(.*?)\' rejected because extension not found in context \'public\'/) {
push(@failhost,$1);
}
}
#
# get current blocked ipaddresses in asterisk chain
#
my $blockedhosts = `/sbin/iptables -n -L asterisk`;
#
# grep through and get ip addresses, adding them to currblocked
#
while ($blockedhosts =~ /(.*)/g) {
my ($line2) = $1;
chomp($line2);
if ($line2 =~ m/(\d+\.\d+\.\d+\.\d+)(\s+)/) {
$currblocked{ $1 } = 'blocked';
}
}
while (my ($key, $value) = each(%currblocked)) {
print $key . "\n";
}
#
# match found addresses against current blocked
#
if (@failhost) {
# log results in /var/log/asterisk/logparse.log.
open (RESULTS, ">> /var/log/asterisk/logparse.log") or die "ERROR: Could not save log.\n";;
&count_unique(@failhost);
while (my ($ip, $count) = each(%addblocked)) {
if (exists $currblocked{ $ip }) {
print RESULTS "$date: $ip already blocked\n";
} elsif (index($ip, "10.1.101.") != "-1") {
# whitelist ip address / ranges
print RESULTS "$date: $ip is whitelisted\n";
} else {
# add ip address to asterisk chain with date time domment.
$action = `/sbin/iptables -I asterisk -s $ip -j DROP -m comment --comment "blocked $date $count attempts "`;
print RESULTS "$date: $ip blocked. $count attempts.\n";
$rotate = 1;
}
}
# we found a bad attempt, so let's rotate the log.
if ($rotate == 1) {
$action = `/usr/sbin/asterisk -rx "logger rotate"`;
}
close (RESULTS);
} else {
print "no failed registrations.\n";
}
sub count_unique {
my @array = @_;
my %count;
map { $count{$_}++ } @array;
map {($addblocked{ $_ } = ${count{$_}})} sort keys(%count);
}
sub get_date {
# return date and time from local time.
my ($sec,$min,$hour,$day,$mon,$yrnum,$wday,$yday,$isdst) = localtime(time);
return sprintf("%04d-%02d-%02d %02d:%02d", $yrnum+1900, $mon+1, $day, $hour, $min);
}