mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-08-21 05:43:22 -07:00
Update ipwhois to 1.1.0
This commit is contained in:
parent
4d6279a626
commit
84ce4758d1
13 changed files with 5041 additions and 649 deletions
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2013, 2014, 2015, 2016 Philip Hane
|
||||
# Copyright (c) 2013-2019 Philip Hane
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
|
@ -23,6 +23,8 @@
|
|||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from . import Net
|
||||
from .asn import IPASN
|
||||
from .nir import NIRWhois
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -34,22 +36,25 @@ class IPWhois:
|
|||
IPv4 and IPv6 addresses.
|
||||
|
||||
Args:
|
||||
address: An IPv4 or IPv6 address as a string, integer, IPv4Address, or
|
||||
IPv6Address.
|
||||
timeout: The default timeout for socket connections in seconds.
|
||||
proxy_opener: The urllib.request.OpenerDirector request for proxy
|
||||
support or None.
|
||||
allow_permutations: allow net.Net() to use additional methods if DNS
|
||||
lookups to Cymru fail.
|
||||
address (:obj:`str`/:obj:`int`/:obj:`IPv4Address`/:obj:`IPv6Address`):
|
||||
An IPv4 or IPv6 address
|
||||
timeout (:obj:`int`): The default timeout for socket connections in
|
||||
seconds. Defaults to 5.
|
||||
proxy_opener (:obj:`urllib.request.OpenerDirector`): The request for
|
||||
proxy support. Defaults to None.
|
||||
allow_permutations (:obj:`bool`): Allow net.Net() to use additional
|
||||
methods if DNS lookups to Cymru fail. *WARNING* deprecated in
|
||||
favor of new argument asn_methods. Defaults to False.
|
||||
"""
|
||||
|
||||
def __init__(self, address, timeout=5, proxy_opener=None,
|
||||
allow_permutations=True):
|
||||
allow_permutations=False):
|
||||
|
||||
self.net = Net(
|
||||
address=address, timeout=timeout, proxy_opener=proxy_opener,
|
||||
allow_permutations=allow_permutations
|
||||
)
|
||||
self.ipasn = IPASN(self.net)
|
||||
|
||||
self.address = self.net.address
|
||||
self.timeout = self.net.timeout
|
||||
|
@ -64,80 +69,101 @@ class IPWhois:
|
|||
self.address_str, str(self.timeout), repr(self.net.opener)
|
||||
)
|
||||
|
||||
def lookup(self, *args, **kwargs):
|
||||
"""
|
||||
Temporary wrapper for legacy whois lookups (moved to
|
||||
IPWhois.lookup_whois()). This will be removed in a future
|
||||
release (TBD).
|
||||
"""
|
||||
|
||||
from warnings import warn
|
||||
warn("IPWhois.lookup() has been deprecated and will be removed. "
|
||||
"You should now use IPWhois.lookup_whois() for legacy whois "
|
||||
"lookups.")
|
||||
return self.lookup_whois(*args, **kwargs)
|
||||
|
||||
def lookup_whois(self, inc_raw=False, retry_count=3, get_referral=False,
|
||||
extra_blacklist=None, ignore_referral_errors=False,
|
||||
field_list=None, asn_alts=None, extra_org_map=None):
|
||||
field_list=None, asn_alts=None, extra_org_map=None,
|
||||
inc_nir=True, nir_field_list=None, asn_methods=None,
|
||||
get_asn_description=True):
|
||||
"""
|
||||
The function for retrieving and parsing whois information for an IP
|
||||
address via port 43 (WHOIS).
|
||||
|
||||
Args:
|
||||
inc_raw: Boolean for whether to include the raw whois results in
|
||||
the returned dictionary.
|
||||
retry_count: The number of times to retry in case socket errors,
|
||||
timeouts, connection resets, etc. are encountered.
|
||||
get_referral: Boolean for whether to retrieve referral whois
|
||||
information, if available.
|
||||
extra_blacklist: A list of blacklisted whois servers in addition to
|
||||
the global BLACKLIST.
|
||||
ignore_referral_errors: Boolean for whether to ignore and continue
|
||||
when an exception is encountered on referral whois lookups.
|
||||
field_list: If provided, a list of fields to parse:
|
||||
inc_raw (:obj:`bool`): Whether to include the raw whois results in
|
||||
the returned dictionary. Defaults to False.
|
||||
retry_count (:obj:`int`): The number of times to retry in case
|
||||
socket errors, timeouts, connection resets, etc. are
|
||||
encountered. Defaults to 3.
|
||||
get_referral (:obj:`bool`): Whether to retrieve referral whois
|
||||
information, if available. Defaults to False.
|
||||
extra_blacklist (:obj:`list`): Blacklisted whois servers in
|
||||
addition to the global BLACKLIST. Defaults to None.
|
||||
ignore_referral_errors (:obj:`bool`): Whether to ignore and
|
||||
continue when an exception is encountered on referral whois
|
||||
lookups. Defaults to False.
|
||||
field_list (:obj:`list`): If provided, a list of fields to parse:
|
||||
['name', 'handle', 'description', 'country', 'state', 'city',
|
||||
'address', 'postal_code', 'emails', 'created', 'updated']
|
||||
asn_alts: Array of additional lookup types to attempt if the
|
||||
If None, defaults to all.
|
||||
asn_alts (:obj:`list`): Additional lookup types to attempt if the
|
||||
ASN dns lookup fails. Allow permutations must be enabled.
|
||||
Defaults to all ['whois', 'http'].
|
||||
extra_org_map: Dictionary mapping org handles to RIRs. This is for
|
||||
limited cases where ARIN REST (ASN fallback HTTP lookup) does
|
||||
not show an RIR as the org handle e.g., DNIC (which is now the
|
||||
built in ORG_MAP) e.g., {'DNIC': 'arin'}. Valid RIR values are
|
||||
(note the case-sensitive - this is meant to match the REST
|
||||
result): 'ARIN', 'RIPE', 'apnic', 'lacnic', 'afrinic'
|
||||
If None, defaults to all ['whois', 'http']. *WARNING*
|
||||
deprecated in favor of new argument asn_methods.
|
||||
extra_org_map (:obj:`dict`): Dictionary mapping org handles to
|
||||
RIRs. This is for limited cases where ARIN REST (ASN fallback
|
||||
HTTP lookup) does not show an RIR as the org handle e.g., DNIC
|
||||
(which is now the built in ORG_MAP) e.g., {'DNIC': 'arin'}.
|
||||
Valid RIR values are (note the case-sensitive - this is meant
|
||||
to match the REST result):
|
||||
'ARIN', 'RIPE', 'apnic', 'lacnic', 'afrinic'
|
||||
Defaults to None.
|
||||
inc_nir (:obj:`bool`): Whether to retrieve NIR (National Internet
|
||||
Registry) information, if registry is JPNIC (Japan) or KRNIC
|
||||
(Korea). If True, extra network requests will be required.
|
||||
If False, the information returned for JP or KR IPs is
|
||||
severely restricted. Defaults to True.
|
||||
nir_field_list (:obj:`list`): If provided and inc_nir, a list of
|
||||
fields to parse:
|
||||
['name', 'handle', 'country', 'address', 'postal_code',
|
||||
'nameservers', 'created', 'updated', 'contacts']
|
||||
If None, defaults to all.
|
||||
asn_methods (:obj:`list`): ASN lookup types to attempt, in order.
|
||||
If None, defaults to all ['dns', 'whois', 'http'].
|
||||
get_asn_description (:obj:`bool`): Whether to run an additional
|
||||
query when pulling ASN information via dns, in order to get
|
||||
the ASN description. Defaults to True.
|
||||
|
||||
Returns:
|
||||
Dictionary:
|
||||
dict: The IP whois lookup results
|
||||
|
||||
:query: The IP address (String)
|
||||
:asn: The Autonomous System Number (String)
|
||||
:asn_date: The ASN Allocation date (String)
|
||||
:asn_registry: The assigned ASN registry (String)
|
||||
:asn_cidr: The assigned ASN CIDR (String)
|
||||
:asn_country_code: The assigned ASN country code (String)
|
||||
:nets: Dictionaries containing network information which consists
|
||||
of the fields listed in the ipwhois.whois.RIR_WHOIS dictionary.
|
||||
(List)
|
||||
:raw: Raw whois results if the inc_raw parameter is True. (String)
|
||||
:referral: Dictionary of referral whois information if get_referral
|
||||
is True and the server isn't blacklisted. Consists of fields
|
||||
listed in the ipwhois.whois.RWHOIS dictionary.
|
||||
:raw_referral: Raw referral whois results if the inc_raw parameter
|
||||
is True. (String)
|
||||
::
|
||||
|
||||
{
|
||||
'query' (str) - The IP address
|
||||
'asn' (str) - The Autonomous System Number
|
||||
'asn_date' (str) - The ASN Allocation date
|
||||
'asn_registry' (str) - The assigned ASN registry
|
||||
'asn_cidr' (str) - The assigned ASN CIDR
|
||||
'asn_country_code' (str) - The assigned ASN country code
|
||||
'asn_description' (str) - The ASN description
|
||||
'nets' (list) - Dictionaries containing network
|
||||
information which consists of the fields listed in the
|
||||
ipwhois.whois.RIR_WHOIS dictionary.
|
||||
'raw' (str) - Raw whois results if the inc_raw parameter
|
||||
is True.
|
||||
'referral' (dict) - Referral whois information if
|
||||
get_referral is True and the server is not blacklisted.
|
||||
Consists of fields listed in the ipwhois.whois.RWHOIS
|
||||
dictionary.
|
||||
'raw_referral' (str) - Raw referral whois results if the
|
||||
inc_raw parameter is True.
|
||||
'nir' (dict) - ipwhois.nir.NIRWhois() results if inc_nir
|
||||
is True.
|
||||
}
|
||||
"""
|
||||
|
||||
from .whois import Whois
|
||||
|
||||
# Create the return dictionary.
|
||||
results = {}
|
||||
results = {'nir': None}
|
||||
|
||||
# Retrieve the ASN information.
|
||||
log.debug('ASN lookup for {0}'.format(self.address_str))
|
||||
asn_data, response = self.net.lookup_asn(
|
||||
retry_count=retry_count, asn_alts=asn_alts,
|
||||
extra_org_map=extra_org_map
|
||||
|
||||
asn_data = self.ipasn.lookup(
|
||||
inc_raw=inc_raw, retry_count=retry_count, asn_alts=asn_alts,
|
||||
extra_org_map=extra_org_map, asn_methods=asn_methods,
|
||||
get_asn_description=get_asn_description
|
||||
)
|
||||
|
||||
# Add the ASN information to the return dictionary.
|
||||
|
@ -147,20 +173,42 @@ class IPWhois:
|
|||
whois = Whois(self.net)
|
||||
log.debug('WHOIS lookup for {0}'.format(self.address_str))
|
||||
whois_data = whois.lookup(
|
||||
inc_raw=inc_raw, retry_count=retry_count, response=response,
|
||||
inc_raw=inc_raw, retry_count=retry_count, response=None,
|
||||
get_referral=get_referral, extra_blacklist=extra_blacklist,
|
||||
ignore_referral_errors=ignore_referral_errors, asn_data=asn_data,
|
||||
field_list=field_list
|
||||
)
|
||||
|
||||
# Add the RDAP information to the return dictionary.
|
||||
# Add the WHOIS information to the return dictionary.
|
||||
results.update(whois_data)
|
||||
|
||||
if inc_nir:
|
||||
|
||||
nir = None
|
||||
if 'JP' == asn_data['asn_country_code']:
|
||||
nir = 'jpnic'
|
||||
elif 'KR' == asn_data['asn_country_code']:
|
||||
nir = 'krnic'
|
||||
|
||||
if nir:
|
||||
|
||||
nir_whois = NIRWhois(self.net)
|
||||
nir_data = nir_whois.lookup(
|
||||
nir=nir, inc_raw=inc_raw, retry_count=retry_count,
|
||||
response=None,
|
||||
field_list=nir_field_list, is_offline=False
|
||||
)
|
||||
|
||||
# Add the NIR information to the return dictionary.
|
||||
results['nir'] = nir_data
|
||||
|
||||
return results
|
||||
|
||||
def lookup_rdap(self, inc_raw=False, retry_count=3, depth=0,
|
||||
excluded_entities=None, bootstrap=False,
|
||||
rate_limit_timeout=120, asn_alts=None, extra_org_map=None):
|
||||
rate_limit_timeout=120, asn_alts=None, extra_org_map=None,
|
||||
inc_nir=True, nir_field_list=None, asn_methods=None,
|
||||
get_asn_description=True):
|
||||
"""
|
||||
The function for retrieving and parsing whois information for an IP
|
||||
address via HTTP (RDAP).
|
||||
|
@ -169,50 +217,84 @@ class IPWhois:
|
|||
information to parse.**
|
||||
|
||||
Args:
|
||||
inc_raw: Boolean for whether to include the raw whois results in
|
||||
the returned dictionary.
|
||||
retry_count: The number of times to retry in case socket errors,
|
||||
timeouts, connection resets, etc. are encountered.
|
||||
depth: How many levels deep to run queries when additional
|
||||
referenced objects are found.
|
||||
excluded_entities: A list of entity handles to not perform lookups.
|
||||
bootstrap: If True, performs lookups via ARIN bootstrap rather
|
||||
than lookups based on ASN data. ASN lookups are not performed
|
||||
and no output for any of the asn* fields is provided.
|
||||
rate_limit_timeout: The number of seconds to wait before retrying
|
||||
when a rate limit notice is returned via rdap+json.
|
||||
asn_alts: Array of additional lookup types to attempt if the
|
||||
inc_raw (:obj:`bool`): Whether to include the raw whois results in
|
||||
the returned dictionary. Defaults to False.
|
||||
retry_count (:obj:`int`): The number of times to retry in case
|
||||
socket errors, timeouts, connection resets, etc. are
|
||||
encountered. Defaults to 3.
|
||||
depth (:obj:`int`): How many levels deep to run queries when
|
||||
additional referenced objects are found. Defaults to 0.
|
||||
excluded_entities (:obj:`list`): Entity handles to not perform
|
||||
lookups. Defaults to None.
|
||||
bootstrap (:obj:`bool`): If True, performs lookups via ARIN
|
||||
bootstrap rather than lookups based on ASN data. ASN lookups
|
||||
are not performed and no output for any of the asn* fields is
|
||||
provided. Defaults to False.
|
||||
rate_limit_timeout (:obj:`int`): The number of seconds to wait
|
||||
before retrying when a rate limit notice is returned via
|
||||
rdap+json. Defaults to 120.
|
||||
asn_alts (:obj:`list`): Additional lookup types to attempt if the
|
||||
ASN dns lookup fails. Allow permutations must be enabled.
|
||||
Defaults to all ['whois', 'http'].
|
||||
extra_org_map: Dictionary mapping org handles to RIRs. This is for
|
||||
limited cases where ARIN REST (ASN fallback HTTP lookup) does
|
||||
not show an RIR as the org handle e.g., DNIC (which is now the
|
||||
built in ORG_MAP) e.g., {'DNIC': 'arin'}. Valid RIR values are
|
||||
(note the case-sensitive - this is meant to match the REST
|
||||
result): 'ARIN', 'RIPE', 'apnic', 'lacnic', 'afrinic'
|
||||
If None, defaults to all ['whois', 'http']. *WARNING*
|
||||
deprecated in favor of new argument asn_methods.
|
||||
extra_org_map (:obj:`dict`): Dictionary mapping org handles to
|
||||
RIRs. This is for limited cases where ARIN REST (ASN fallback
|
||||
HTTP lookup) does not show an RIR as the org handle e.g., DNIC
|
||||
(which is now the built in ORG_MAP) e.g., {'DNIC': 'arin'}.
|
||||
Valid RIR values are (note the case-sensitive - this is meant
|
||||
to match the REST result):
|
||||
'ARIN', 'RIPE', 'apnic', 'lacnic', 'afrinic'
|
||||
Defaults to None.
|
||||
inc_nir (:obj:`bool`): Whether to retrieve NIR (National Internet
|
||||
Registry) information, if registry is JPNIC (Japan) or KRNIC
|
||||
(Korea). If True, extra network requests will be required.
|
||||
If False, the information returned for JP or KR IPs is
|
||||
severely restricted. Defaults to True.
|
||||
nir_field_list (:obj:`list`): If provided and inc_nir, a list of
|
||||
fields to parse:
|
||||
['name', 'handle', 'country', 'address', 'postal_code',
|
||||
'nameservers', 'created', 'updated', 'contacts']
|
||||
If None, defaults to all.
|
||||
asn_methods (:obj:`list`): ASN lookup types to attempt, in order.
|
||||
If None, defaults to all ['dns', 'whois', 'http'].
|
||||
get_asn_description (:obj:`bool`): Whether to run an additional
|
||||
query when pulling ASN information via dns, in order to get
|
||||
the ASN description. Defaults to True.
|
||||
|
||||
Returns:
|
||||
Dictionary:
|
||||
dict: The IP RDAP lookup results
|
||||
|
||||
:query: The IP address (String)
|
||||
:asn: The Autonomous System Number (String)
|
||||
:asn_date: The ASN Allocation date (String)
|
||||
:asn_registry: The assigned ASN registry (String)
|
||||
:asn_cidr: The assigned ASN CIDR (String)
|
||||
:asn_country_code: The assigned ASN country code (String)
|
||||
:entities: List of entity handles referred by the top level query.
|
||||
:network: Dictionary containing network information which consists
|
||||
of the fields listed in the ipwhois.rdap._RDAPNetwork dict.
|
||||
:objects: Dictionary of (entity handle: entity dict) which consists
|
||||
of the fields listed in the ipwhois.rdap._RDAPEntity dict.
|
||||
:raw: (Dictionary) - Whois results in json format if the inc_raw
|
||||
parameter is True.
|
||||
::
|
||||
|
||||
{
|
||||
'query' (str) - The IP address
|
||||
'asn' (str) - The Autonomous System Number
|
||||
'asn_date' (str) - The ASN Allocation date
|
||||
'asn_registry' (str) - The assigned ASN registry
|
||||
'asn_cidr' (str) - The assigned ASN CIDR
|
||||
'asn_country_code' (str) - The assigned ASN country code
|
||||
'asn_description' (str) - The ASN description
|
||||
'entities' (list) - Entity handles referred by the top
|
||||
level query.
|
||||
'network' (dict) - Network information which consists of
|
||||
the fields listed in the ipwhois.rdap._RDAPNetwork
|
||||
dict.
|
||||
'objects' (dict) - Mapping of entity handle->entity dict
|
||||
which consists of the fields listed in the
|
||||
ipwhois.rdap._RDAPEntity dict. The raw result is
|
||||
included for each object if the inc_raw parameter
|
||||
is True.
|
||||
'raw' (dict) - Whois results in json format if the inc_raw
|
||||
parameter is True.
|
||||
'nir' (dict) - ipwhois.nir.NIRWhois results if inc_nir is
|
||||
True.
|
||||
}
|
||||
"""
|
||||
|
||||
from .rdap import RDAP
|
||||
|
||||
# Create the return dictionary.
|
||||
results = {}
|
||||
results = {'nir': None}
|
||||
|
||||
asn_data = None
|
||||
response = None
|
||||
|
@ -220,9 +302,10 @@ class IPWhois:
|
|||
|
||||
# Retrieve the ASN information.
|
||||
log.debug('ASN lookup for {0}'.format(self.address_str))
|
||||
asn_data, asn_response = self.net.lookup_asn(
|
||||
retry_count=retry_count, asn_alts=asn_alts,
|
||||
extra_org_map=extra_org_map
|
||||
asn_data = self.ipasn.lookup(
|
||||
inc_raw=inc_raw, retry_count=retry_count, asn_alts=asn_alts,
|
||||
extra_org_map=extra_org_map, asn_methods=asn_methods,
|
||||
get_asn_description=get_asn_description
|
||||
)
|
||||
|
||||
# Add the ASN information to the return dictionary.
|
||||
|
@ -241,4 +324,23 @@ class IPWhois:
|
|||
# Add the RDAP information to the return dictionary.
|
||||
results.update(rdap_data)
|
||||
|
||||
if inc_nir:
|
||||
|
||||
nir = None
|
||||
if 'JP' == asn_data['asn_country_code']:
|
||||
nir = 'jpnic'
|
||||
elif 'KR' == asn_data['asn_country_code']:
|
||||
nir = 'krnic'
|
||||
|
||||
if nir:
|
||||
nir_whois = NIRWhois(self.net)
|
||||
nir_data = nir_whois.lookup(
|
||||
nir=nir, inc_raw=inc_raw, retry_count=retry_count,
|
||||
response=None,
|
||||
field_list=nir_field_list, is_offline=False
|
||||
)
|
||||
|
||||
# Add the NIR information to the return dictionary.
|
||||
results['nir'] = nir_data
|
||||
|
||||
return results
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue