]> git.openstreetmap.org Git - nominatim.git/commitdiff
log unreasonable IPs
authorSarah Hoffmann <lonvia@denofr.de>
Wed, 7 Feb 2018 20:03:21 +0000 (21:03 +0100)
committerSarah Hoffmann <lonvia@denofr.de>
Wed, 7 Feb 2018 20:03:21 +0000 (21:03 +0100)
Log IPs that continue sending request despite having been
told to go away with a 403 or 429.

utils/cron_ipanalyse.py

index be5e6956915b502e19df315056f6a869d94110db..4625de707ee24b99ffb2eb4d2b3d2ecd41fd7699 100755 (executable)
@@ -34,6 +34,8 @@ UA_BLOCKLIST = ()
 BLOCKCOOLOFF_DELTA=timedelta(hours=1)
 # quiet time before an IP is released from the bulk pool
 BULKCOOLOFF_DELTA=timedelta(minutes=15)
+# time to check if new accesses appear despite being blocked
+BLOCKCHECK_DELTA=timedelta(minutes=1)
 
 BULKLONG_LIMIT=8000
 BULKSHORT_LIMIT=2000
@@ -225,6 +227,7 @@ class IPstats:
         self.short_api = 0
         self.long_total = 0
         self.long_api = 0
+        self.block_total = 0
         self.bad_ua = False
 
     def add_long(self, logentry):
@@ -241,6 +244,12 @@ class IPstats:
             self.short_api += 1
         self.add_long(logentry)
 
+    def add_block(self, logentry):
+        self.block_total += 1
+
+    def ignores_warnings(self):
+        return self.block_total > 5
+
     def new_state(self, was_blocked, was_bulked):
         if was_blocked:
             # deblock only if the IP has been really quiet
@@ -287,6 +296,7 @@ if __name__ == '__main__':
     bl = BlockList()
 
     shortstart = dt + BLOCKCOOLOFF_DELTA - BULKCOOLOFF_DELTA
+    blockstart = dt + BLOCKCOOLOFF_DELTA - BLOCKCHECK_DELTA
     notlogged = bl.whitelist | bl.blacklist
 
     stats = defaultdict(IPstats)
@@ -303,6 +313,8 @@ if __name__ == '__main__':
             stats[l.ip].add_short(l)
         if l.request is not None and l.retcode == 200:
             total200 += 1
+        if l.date > blockstart and l.retcode in (403, 429):
+            stats[l.ip].add_block(l)
 
     # adapt limits according to CPU and DB load
     fd = open("/proc/loadavg")
@@ -376,4 +388,7 @@ if __name__ == '__main__':
         fd.write(logstr % (' ua block:', ', '.join(uablocked)))
     if blocked:
         fd.write(logstr % ('new block:', ', '.join(blocked)))
+    for k,v in stats.items():
+        if v.ignores_warnings() and k not in notlogged:
+            fd.write(logstr % ('Warning ignored:', k))
     fd.close()