mirror of
https://github.com/PurpleI2P/i2pd-tools.git
synced 2025-01-22 13:27:17 +01:00
more
This commit is contained in:
parent
e7e0c6200f
commit
fe758eb1ae
29
baddie-detector/baddiefinder/__main__.py
Normal file
29
baddie-detector/baddiefinder/__main__.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
#
|
||||
#
|
||||
#
|
||||
|
||||
import netdb
|
||||
|
||||
|
||||
from argparse import ArgumentParser as AP
|
||||
|
||||
from . import settings
|
||||
from . import filter
|
||||
from . import processor
|
||||
|
||||
def main():
|
||||
ap = AP()
|
||||
ap.add_argument("--settings", default="baddies.ini")
|
||||
|
||||
args = ap.parse_args()
|
||||
s = settings.load(args.settings)
|
||||
fmax = s.get("thresholds", "max_floodfills_per_ip", fallback=5)
|
||||
f = filter.FloodfillFilter(fmax)
|
||||
p = processor.BaddieProcessor([f])
|
||||
netdb.inspect(p.hook)
|
||||
with open(s.get("output", "file", fallback="baddies.txt"), 'w') as f:
|
||||
p.write_blocklist(f)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
32
baddie-detector/baddiefinder/filter.py
Normal file
32
baddie-detector/baddiefinder/filter.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
|
||||
from . import util
|
||||
|
||||
class Filter:
|
||||
|
||||
name = "unnamed filter"
|
||||
|
||||
def process(self, info):
|
||||
"""
|
||||
process an info and return True if it should be added to blocklist
|
||||
any other return value will cause this info to NOT be added to blocklist
|
||||
"""
|
||||
|
||||
class FloodfillFilter(Filter):
|
||||
|
||||
name = "floodfill sybil detector"
|
||||
|
||||
def __init__(self, fmax):
|
||||
self._floodfills = dict()
|
||||
self.fmax = int(fmax)
|
||||
|
||||
def process(self, info):
|
||||
caps = util.getcaps(info)
|
||||
if not caps:
|
||||
return False
|
||||
if b'f' not in caps:
|
||||
return False
|
||||
h = util.getaddress(info)
|
||||
if h not in self._floodfills:
|
||||
self._floodfills[h] = 0
|
||||
self._floodfills[h] += 1
|
||||
return self._floodfills[h] > self.fmax
|
26
baddie-detector/baddiefinder/processor.py
Normal file
26
baddie-detector/baddiefinder/processor.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
from . import util
|
||||
|
||||
import datetime
|
||||
|
||||
class BaddieProcessor:
|
||||
|
||||
def __init__(self, filters):
|
||||
self._filters = filters
|
||||
self._baddies = dict()
|
||||
|
||||
|
||||
def hook(self, entry):
|
||||
for f in self._filters:
|
||||
if f.process(entry) is True:
|
||||
self.add_baddie(entry, 'detected by {}'.format(f.name))
|
||||
|
||||
def add_baddie(self, entry, reason):
|
||||
addr = util.getaddress(entry)
|
||||
if addr not in self._baddies:
|
||||
self._baddies[addr] = ''
|
||||
self._baddies[addr] += reason + ' '
|
||||
|
||||
def write_blocklist(self, f):
|
||||
f.write('# baddies blocklist generated on {}'.format(datetime.datetime.now()))
|
||||
for k in self._baddies:
|
||||
f.write('{}:{}\n'.format(self._baddies[k], k))
|
11
baddie-detector/baddiefinder/settings.py
Normal file
11
baddie-detector/baddiefinder/settings.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
#
|
||||
# baddiefinder settings wrapper
|
||||
#
|
||||
|
||||
from configparser import ConfigParser
|
||||
|
||||
def load(fname):
|
||||
c = ConfigParser()
|
||||
with open(fname) as f:
|
||||
c.read_file(f, fname)
|
||||
return c
|
15
baddie-detector/baddiefinder/util.py
Normal file
15
baddie-detector/baddiefinder/util.py
Normal file
|
@ -0,0 +1,15 @@
|
|||
def getaddress(info):
|
||||
"""
|
||||
get ip address from router info dict
|
||||
"""
|
||||
for addr in info.addrs:
|
||||
opts = addr.options
|
||||
if b'host' in opts:
|
||||
return opts[b'host']
|
||||
|
||||
def getcaps(info):
|
||||
"""
|
||||
extract router caps
|
||||
"""
|
||||
if b'caps' in info.options:
|
||||
return info.options[b'caps']
|
2
baddie-detector/baddies.ini
Normal file
2
baddie-detector/baddies.ini
Normal file
|
@ -0,0 +1,2 @@
|
|||
[thresholds]
|
||||
max_floodfills_per_ip = 2
|
|
@ -5,9 +5,11 @@
|
|||
## MIT Liecense 2014
|
||||
##
|
||||
import os,sys,struct,time,hashlib,fnmatch,io
|
||||
from geoip import geolite2
|
||||
import base64
|
||||
import logging
|
||||
import pygeoip
|
||||
|
||||
geo = pygeoip.GeoIP('/usr/share/GeoIP/GeoIPCity.dat')
|
||||
|
||||
b64encode = lambda x : base64.b64encode(x, b'~-').decode('ascii')
|
||||
|
||||
|
@ -152,6 +154,10 @@ class Entry:
|
|||
li = struct.unpack('!Q', d)[0]
|
||||
return li
|
||||
|
||||
@staticmethod
|
||||
def geolookup(entry):
|
||||
return geo.record_by_addr(entry)
|
||||
|
||||
@staticmethod
|
||||
def _read_addr(fd):
|
||||
"""
|
||||
|
@ -168,7 +174,7 @@ class Entry:
|
|||
# This is a try because sometimes hostnames show up.
|
||||
# TODO: Make it allow host names.
|
||||
try:
|
||||
addr.location = geolite2.lookup(addr.options.get('host', None))
|
||||
addr.location = geolookup(addr.options.get('host', None))
|
||||
except:
|
||||
addr.location = None
|
||||
|
||||
|
@ -179,7 +185,7 @@ class Entry:
|
|||
# If there are introducers then it's probably firewalled.
|
||||
addr.firewalled = True
|
||||
try:
|
||||
addr.location = geolite2.lookup(addr.options.get('ihost0', None))
|
||||
addr.location = geolookup(addr.options.get('ihost0', None))
|
||||
except:
|
||||
addr.location = None
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
from setuptools import setup
|
||||
|
||||
setup(name = 'baddiedetector',
|
||||
version = '0.0',
|
||||
description = 'i2p netdb blocklist ',
|
||||
version = '0.1',
|
||||
description = 'i2p netdb blocklist tool',
|
||||
author = 'Jeff Becker',
|
||||
author_email = 'ampernand@gmail.com',
|
||||
install_requires = ['python-geoip','python-geoip-geolite2'],
|
||||
|
|
Loading…
Reference in a new issue