mirror of
https://github.com/PurpleI2P/i2pd-tools.git
synced 2025-01-22 21:37:18 +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
|
## MIT Liecense 2014
|
||||||
##
|
##
|
||||||
import os,sys,struct,time,hashlib,fnmatch,io
|
import os,sys,struct,time,hashlib,fnmatch,io
|
||||||
from geoip import geolite2
|
|
||||||
import base64
|
import base64
|
||||||
import logging
|
import logging
|
||||||
|
import pygeoip
|
||||||
|
|
||||||
|
geo = pygeoip.GeoIP('/usr/share/GeoIP/GeoIPCity.dat')
|
||||||
|
|
||||||
b64encode = lambda x : base64.b64encode(x, b'~-').decode('ascii')
|
b64encode = lambda x : base64.b64encode(x, b'~-').decode('ascii')
|
||||||
|
|
||||||
|
@ -152,6 +154,10 @@ class Entry:
|
||||||
li = struct.unpack('!Q', d)[0]
|
li = struct.unpack('!Q', d)[0]
|
||||||
return li
|
return li
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def geolookup(entry):
|
||||||
|
return geo.record_by_addr(entry)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _read_addr(fd):
|
def _read_addr(fd):
|
||||||
"""
|
"""
|
||||||
|
@ -168,7 +174,7 @@ class Entry:
|
||||||
# This is a try because sometimes hostnames show up.
|
# This is a try because sometimes hostnames show up.
|
||||||
# TODO: Make it allow host names.
|
# TODO: Make it allow host names.
|
||||||
try:
|
try:
|
||||||
addr.location = geolite2.lookup(addr.options.get('host', None))
|
addr.location = geolookup(addr.options.get('host', None))
|
||||||
except:
|
except:
|
||||||
addr.location = None
|
addr.location = None
|
||||||
|
|
||||||
|
@ -179,7 +185,7 @@ class Entry:
|
||||||
# If there are introducers then it's probably firewalled.
|
# If there are introducers then it's probably firewalled.
|
||||||
addr.firewalled = True
|
addr.firewalled = True
|
||||||
try:
|
try:
|
||||||
addr.location = geolite2.lookup(addr.options.get('ihost0', None))
|
addr.location = geolookup(addr.options.get('ihost0', None))
|
||||||
except:
|
except:
|
||||||
addr.location = None
|
addr.location = None
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
|
|
||||||
setup(name = 'baddiedetector',
|
setup(name = 'baddiedetector',
|
||||||
version = '0.0',
|
version = '0.1',
|
||||||
description = 'i2p netdb blocklist ',
|
description = 'i2p netdb blocklist tool',
|
||||||
author = 'Jeff Becker',
|
author = 'Jeff Becker',
|
||||||
author_email = 'ampernand@gmail.com',
|
author_email = 'ampernand@gmail.com',
|
||||||
install_requires = ['python-geoip','python-geoip-geolite2'],
|
install_requires = ['python-geoip','python-geoip-geolite2'],
|
||||||
|
|
Loading…
Reference in a new issue