eris- Elasticsearch Recon Ingestion Scripts (ERIS) 🔎 |
git clone git://git.acid.vegas/eris.git |
Log | Files | Refs | Archive | README | LICENSE |
ingest_rir_whois.py (5975B)
1 #/usr/bin/env python 2 # opengeoip - developed by acidvegas in python (https://git.acid.vegas/opengeoip) 3 # whois.py 4 5 ''' 6 Source: https://ftp.[afrinic|apnic|arin|lacnic|ripe].net/ + others 7 Notes : The databases are updated daily. 8 Check out the whois2json.py script for converting the whois data into JSON objects for elasticsearch. 9 Each database has a CURRENTSERIAL file that contains the serial number of the latest version of the database. 10 Need to find a smart way to unify the approach for each RIR to account for their differences. 11 Do we need ripe-nonauth.db.gz? | https://ftp.ripe.net/ripe/dbase/ 12 Do we need twnic, krnic, jpnic? | https://ftp.apnic.net/apnic/dbase/data/ 13 Do we need the IRR databases? | https://www.irr.net/docs/list.html 14 Do we need the LACNIC IRR database? | https://ftp.lacnic.net/lacnic/irr/ 15 ''' 16 17 import os 18 import sys 19 20 try: 21 import utils 22 except ImportError: 23 raise SystemError('utils.py module not found!') 24 25 REGISTRY_DATA = { 26 'AFRINIC' : 'ftp.afrinic.net/dbase/afrinic.db.gz', 27 'APNIC' : ['ftp.apnic.net/apnic/whois/apnic.db.as-block.gz', # APNIC really has to be "special" snowflake... 28 'ftp.apnic.net/apnic/whois/apnic.db.as-set.gz', 29 'ftp.apnic.net/apnic/whois/apnic.db.aut-num.gz', 30 'ftp.apnic.net/apnic/whois/apnic.db.domain.gz', 31 'ftp.apnic.net/apnic/whois/apnic.db.filter-set.gz', 32 'ftp.apnic.net/apnic/whois/apnic.db.inet-rtr.gz', 33 'ftp.apnic.net/apnic/whois/apnic.db.inet6num.gz', 34 'ftp.apnic.net/apnic/whois/apnic.db.inetnum.gz', 35 'ftp.apnic.net/apnic/whois/apnic.db.irt.gz', 36 'ftp.apnic.net/apnic/whois/apnic.db.key-cert.gz', 37 'ftp.apnic.net/apnic/whois/apnic.db.limerick.gz', # Little easteregg, not updated since 2017... 38 'ftp.apnic.net/apnic/whois/apnic.db.mntner.gz', 39 'ftp.apnic.net/apnic/whois/apnic.db.organisation.gz', 40 'ftp.apnic.net/apnic/whois/apnic.db.peering-set.gz', 41 'ftp.apnic.net/apnic/whois/apnic.db.role.gz', 42 'ftp.apnic.net/apnic/whois/apnic.db.route-set.gz', 43 'ftp.apnic.net/apnic/whois/apnic.db.route.gz', 44 'ftp.apnic.net/apnic/whois/apnic.db.route6.gz', 45 'ftp.apnic.net/apnic/whois/apnic.db.rtr-set.gz'], 46 'JPNIC' : 'ftp.apnic.net/apnic/dbase/data/jpnic.db.gz', # JPNIC is APNIC but is a NIR 47 'KRNIC' : 'ftp.apnic.net/apnic/dbase/data/krnic.db.gz', # KRNIC is APNIC but is a NIR 48 'TWINIC' : 'ftp.apnic.net/apnic/dbase/data/twnic.db.gz', # TWINIC is APNIC but is a NIR 49 'ARIN' : 'ftp.arin.net/pub/rr/arin.db.gz', 50 'LACNIC' : ['ftp.lacnic.net/lacnic/dbase/lacnic.db.gz', # LACNIC has a dbase and an IRR 51 'ftp.lacnic.net/lacnic/irr/lacnic.db.gz'], 52 'RIPE' : ['ftp.ripe.net/ripe/dbase/ripe.db.gz', # RIPE has a dbase and a non-auth dbase 53 'ftp.ripe.net/ripe/dbase/ripe-nonauth.db.gz'] 54 } 55 56 IRR_DATA = { 57 'ALTDB' : 'ftp.altdb.net/pub/altdb/altdb.db.gz', 58 'BELL' : 'whois.in.bell.ca/bell.db.gz', 59 'CANARIE' : 'ftp.radb.net/radb/dbase/canarie.db.gz', 60 'HOST' : 'ftp.radb.net/radb/dbase/host.db.gz', 61 'IDNIC' : 'irr-mirror.idnic.net/idnic.db.gz', 62 'JPIRR' : 'ftp.nic.ad.jp/jpirr/jpirr.db.gz', 63 'LACNIC' : 'ftp.lacnic.net/lacnic/irr/lacnic.db.gz', # Name conflict... 64 'LEVEL3' : 'rr.Level3.net/level3.db.gz', 65 'NESTEGG' : 'ftp.nestegg.net/irr/nestegg.db.gz', 66 'NTTCOM' : 'rr1.ntt.net/nttcomRR/nttcom.db.gz', 67 'OPENFACE' : 'ftp.radb.net/radb/dbase/openface.db.gz', 68 'PANIX' : 'ftp.panix.com/pub/rrdb/panix.db.gz', 69 'RADB' : 'ftp.radb.net/radb/dbase/radb.db.gz', 70 'REACH' : 'ftp.radb.net/radb/dbase/reach.db.gz', 71 'RGNET' : 'ftp.radb.net/radb/dbase/rgnet.db.gz', 72 'TC' : 'ftp.bgp.net.br/tc.db.gz' 73 } 74 75 76 def check_serial(local_serial_path: str, ftp_serial_url: str) -> bool: 77 ''' 78 Check the CURRENTSERIAL file for an update. 79 80 :param local_path: The path to the local CURRENTSERIAL file 81 :param ftp_path: The path to the remote CURRENTSERIAL file 82 ''' 83 84 if not os.path.exists(local_serial_path): 85 return True 86 87 else: 88 with open(local_serial_path) as serial_file: 89 old_serial = serial_file.read().strip() 90 new_serial = utils.read_ftp(ftp_serial_url) 91 if old_serial != new_serial: 92 return True 93 else: 94 return False 95 96 97 def download_db(output_path: str, url: str): 98 ''' 99 Dowload a WHOIS database. 100 101 :param output_path: The path to the output directory 102 :param url: The FTP URL of the database to download 103 ''' 104 105 DB_PATH = os.path.join(output_path, url.split('/')[-1]) 106 utils.safe_remove(DB_PATH) 107 utils.safe_remove(DB_PATH[:-3]) 108 utils.download_ftp(url, DB_PATH) 109 utils.gunzip_extract(DB_PATH, DB_PATH[:-3]) 110 utils.safe_remove(DB_PATH) 111 112 113 def update_db(output_path: str): 114 ''' 115 Update the whois IRR databases. 116 117 :param output_path: The path to the output directory 118 ''' 119 120 os.makedirs(output_path, exist_ok=True) 121 122 for RIR, DB_URL in REGISTRY_DATA.items(): 123 if RIR == 'APNIC': 124 for url in DB_URL: 125 download_db(output_path, url) 126 else: 127 download_db(output_path, DB_URL) 128 for IRR, DB_URL in REGISTRY_DATA.items(): 129 download_db(output_path+'/irr', DB_URL) 130 131 # For now, we'll just download the files and not check the serials for updates APNIC will need to be handled differently...seperate function? 132 ''' 133 SERIAL_PATH = os.path.join(output_path, REGISTRY+'.CURRENTSERIAL') 134 FTP_SERIAL = os.path.join('/'.join(DB_URL.split('/')[:-1]), REGISTRY + '.CURRENTSERIAL') 135 136 if check_serial(SERIAL_PATH, FTP_SERIAL): 137 logging.debug(f'A new version of the {REGISTRY} whois database is available! Downloading...') 138 for item in (DB_PATH, DB_PATH[:-3], SERIAL_PATH): 139 utils.safe_remove(item) # Remove old files 140 utils.download_ftp(DB_URL, DB_PATH) 141 utils.download_ftp(FTP_SERIAL, SERIAL_PATH) 142 utils.gunzip_extract(DB_PATH, DB_PATH[:-3]) 143 logging.debug(f'The {REGISTRY} whois database has been updated!') 144 else: 145 logging.info(f'The {REGISTRY} whois database is up-to-date') 146 ''' 147 148 149 if __name__ == '__main__': 150 utils.print_header('WHOIS Module') 151 utils.setup_logger('whois') 152 utils.setup_user_agent() 153 update_db('database/whois')