I want to add a method for my bot protection project that allows certain rules, one of these rules will be that the current IP belongs to Tor, not because connections from Tor are bad but rather to provide customization options (like disabling JS).
I can't find a free solution without an API key that is fast enough to fulfill the requirements. The Tor Exit List also does not seem to contain all ips, such as certain Ipv6 ips.
I found Tor Exonera: https://metrics.torproject.org/exonerator.html but there doesn't seem to be an API for it.
I found the solution with the help of Possible to add proxy after TOR exit node?, which links to this blog article: https://lists.torproject.org/pipermail/tor-project/2020-March/002759.html.
The following is the implementation for Python:
import dns.resolver
import ipaddress
def reverse_ip(ip):
try:
ip_obj = ipaddress.ip_address(ip)
if isinstance(ip_obj, ipaddress.IPv4Address):
return '.'.join(reversed(ip.split('.'))) + '.dnsel.torproject.org'
elif isinstance(ip_obj, ipaddress.IPv6Address):
return '.'.join(reversed(ip_obj.exploded.replace(':', ''))) + '.dnsel.torproject.org'
except ValueError:
raise ValueError("Invalid IP address format")
def is_tor_ip(ip):
query = reverse_ip(ip)
try:
answers = dns.resolver.resolve(query, 'A')
for rdata in answers:
if rdata.to_text() == '127.0.0.2':
return True
except dns.resolver.NXDOMAIN:
return False
except dns.resolver.NoAnswer:
return False
except dns.exception.DNSException as e:
print(f"DNS query failed: {e}")
return False
return False
print(is_tor_ip("185.220.101.25"))
print(is_tor_ip("2a0b:f4c2:1::1"))