Created
November 30, 2023 13:22
-
-
Save selimslab/3cce7f22fe886f1d83fcaf0aab6e265d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import csv | |
import yaml | |
import ipaddress | |
from intervaltree import IntervalTree, Interval | |
def read_csv_lines(file): | |
with open(file, 'r') as file: | |
csv_reader = csv.reader(file) | |
return [row[0] for row in csv_reader] | |
def read_yaml_lines(file): | |
with open(file, 'r') as file: | |
yaml_content = file.read() | |
data = yaml.safe_load(yaml_content) | |
return [line for line in data if not line.startswith("#")] | |
def create_interval_tree(blocked_networks): | |
# Create an IntervalTree for blocked IPs | |
blocked_intervals = IntervalTree() | |
for blocked_ip in blocked_networks: | |
# Convert IPNetwork objects to integers for querying IntervalTree | |
# network_address is the lowest and the broadcast_address is highest in the range | |
ip_start = int(blocked_ip.network_address) | |
ip_end = int(blocked_ip.broadcast_address) | |
if ip_start <= ip_end: | |
# +1 to have an inclusive range | |
blocked_intervals.add(Interval(ip_start, ip_end+1, blocked_ip)) | |
''' | |
blocked_intervals go like this: | |
Interval(878679552, 878679808, IPv4Network('52.95.150.0/24')) | |
Interval(56973056, 56973120, IPv4Network('3.101.87.0/26')) | |
Interval(42541956123655038472487924334797520896, 42541956123655038490934668408507072512, IPv6Network('2001:4860:4801:61::/64')) | |
''' | |
return blocked_intervals | |
def check_overlapping_intervals(blocked_networks, apple_networks): | |
blocked_intervals = create_interval_tree(blocked_networks) | |
# search in the tree of blocked IP intervals | |
blocked_apple_ips = set() | |
for apple_ip in apple_networks: | |
# Convert IPNetwork objects to integers for querying IntervalTree | |
ip_start = int(apple_ip.network_address) | |
ip_end = int(apple_ip.broadcast_address) | |
# Query the IntervalTree to check for overlaps with apple_ip | |
overlaps = blocked_intervals.overlap(ip_start, ip_end+1) | |
if any(apple_ip in interval for interval in overlaps): | |
print(f"IP {apple_ip} is blocked.") | |
blocked_apple_ips.add(apple_ip) | |
print(f"{len(blocked_apple_ips)} blocked Apple IPs:", blocked_apple_ips) | |
def search_blocked_apple_ips(): | |
apple_ip_ranges = read_csv_lines('apple.csv') | |
blocked_ip_ranges = read_yaml_lines('blocked.yaml') | |
# str to IP network objects | |
apple_networks = [ipaddress.ip_network(ip_range, strict=False) for ip_range in apple_ip_ranges] | |
blocked_networks = [ipaddress.ip_network(ip_range, strict=False) for ip_range in blocked_ip_ranges] | |
check_overlapping_intervals(blocked_networks, apple_networks) | |
if __name__ == '__main__': | |
''' | |
Find if any of the Apple IPs are in your blocklist | |
Iterative search is too slow so this script uses an interval tree | |
Prerequisites: | |
1. pip install intervaltree | |
2. curl https://mask-api.icloud.com/egress-ip-ranges.csv -o apple.csv | |
3. blocked.yaml is your blocklist | |
Assumes apple.csv and blocked.yaml are in the same folder as this script | |
''' | |
search_blocked_apple_ips() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment