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