Yax
2017-09-06 b8b614309acd67eafa4aa4197426100aaff5af80
commit | author | age
9f3540 1 #!/usr/bin/env python3
Y 2 # -*- coding:Utf-8 -*-
3
4 import re
5 import sys
6
7 pattern = '(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+).*Blacklisting (\d+\.\d+\.\d+\.\d+), reason (.*), return'
8 regex = re.compile(pattern)
9
10
11 class CounterDict:
12
13     def __init__(self):
14         self._counters = dict()
15
16     def inc(self, k):
17         v = self._counters.get(k, 0) + 1
18         self._counters[k] = v
19
20     def get(self, k):
21         return self._counters.get(k, 0)
22
23     def keys(self):
24         return self._counters.keys()
25
26     def reset(self):
27         self._counters = dict()
28
29     def topitems(self):
30         return sorted(self._counters.items(), key=lambda x: x[1], reverse=True)
31
32
33 class Value:
34
35     def __init__(self):
36         self._value = ""
37
38     def __str__(self):
39         return self._value
40
41     def __eq__(self, other):
42         return str(self._value) == str(other)
43
44     def set(self, value):
45         self._value = value
46
47
48 last_day = Value()
49
50 # daily counters: key is reason
51 dcounters = CounterDict()
52
53 # global counters: key is reason
54 gcounters = CounterDict()
55
56 # hourly counters: key is hour
57 hcounters = CounterDict()
58
59 # top counters: key is IP
60 tcounters = CounterDict()
61
62
63 def plural(noun, count):
64     if count > 1:
65         return noun + "s"
66     else:
67         return noun
68
69
70 def process(m):
71     current_day = m.group(1) + "-" + m.group(2) + "-" + m.group(3)
72     current_hour = m.group(4)
73     full_time = m.group(4) + ":" + m.group(5) + ":" + m.group(6)
74     ip = m.group(7)
75     reason = m.group(8)
76
77     # new day
78     #print("({})-({}) => {}".format(last_day, current_day, last_day == current_day))
79     if last_day != current_day:
80         # display day counters
81         sys.stdout.write("\n")
82         for reason in dcounters.keys():
83             count = dcounters.get(reason)
84             sys.stdout.write("Probe '{}': {} {}\n".format(reason, count, plural("attack", count)))
85         last_day.set(current_day)
86         dcounters.reset()
87         sys.stdout.write("\n### Date {}\n".format(current_day))
88
89     # output current line
90     sys.stdout.write("{} blacklist IP {} ({})\n".format(full_time, ip, reason))
91
92     # increment counters
93     dcounters.inc(reason)
94     gcounters.inc(reason)
95     hcounters.inc(current_hour)
96     tcounters.inc(ip)
97
98
99 # parse stdin
100 for line in sys.stdin:
101     match = regex.match(line)
102     if match:
103         process(match)
104
105 # output counters
106 sys.stdout.write("\n")
107 for reason in dcounters.keys():
108     sys.stdout.write("Probe '{}' : {} attacks\n".format(reason, dcounters.get(reason)))
109
110 sys.stdout.write("\n### Attacks per probe\n")
111 for k in gcounters.keys():
112     count = gcounters.get(k)
113     sys.stdout.write("Probe '{}': {} {} \n".format(k, count, plural("attack", count)))
114
115 sys.stdout.write("\n### Hourly repartition\n")
116 for k in sorted(hcounters.keys()):
117     sys.stdout.write("Hour {} - {:02d}: {}\n".format(k, int(k) + 1, hcounters.get(k)))
118
119 sys.stdout.write("\n### Top attackers\n")
120 for k, v in tcounters.topitems():
121     if v < 2:
122         break
123     sys.stdout.write("IP {:16}: {}\n".format(k, v))