lookyloo/lookyloo/modules/cloudflare.py

51 lines
1.6 KiB
Python

#!/usr/bin/env python3
from __future__ import annotations
import ipaddress
import requests
from ..default import ConfigError
from .abstractmodule import AbstractModule
class Cloudflare(AbstractModule):
'''This module checks if an IP is announced by Cloudflare.'''
def module_init(self) -> bool:
# Get IPv4
try:
r = requests.get('https://www.cloudflare.com/ips-v4')
r.raise_for_status()
ipv4_list = r.text
except Exception as e:
self.logger.warning(f'Unable to get Cloudflare IPv4 list: {e}')
return False
# Get IPv6
try:
r = requests.get('https://www.cloudflare.com/ips-v6')
r.raise_for_status()
ipv6_list = r.text
except Exception as e:
self.logger.warning(f'Unable to get Cloudflare IPv6 list: {e}')
return False
self.v4_list = [ipaddress.ip_network(net) for net in ipv4_list.split('\n')]
self.v6_list = [ipaddress.ip_network(net) for net in ipv6_list.split('\n')]
return True
def ips_lookup(self, ips: set[str]) -> dict[str, bool]:
'''Lookup a list of IPs. True means it is a known Cloudflare IP'''
if not self.available:
raise ConfigError('Hashlookup not available, probably not enabled.')
to_return: dict[str, bool] = {}
for ip_s, ip_p in [(ip, ipaddress.ip_address(ip)) for ip in ips]:
if ip_p.version == 4:
to_return[ip_s] = any(ip_p in net for net in self.v4_list)
else:
to_return[ip_s] = any(ip_p in net for net in self.v6_list)
return to_return