Created
August 12, 2025 10:57
-
-
Save gourytch/159f4b71e3dfaa23b50f55b79de36420 to your computer and use it in GitHub Desktop.
Parse GeoLite2-Country.mmdb and create shell scripts with ipset rules
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
| #! /usr/bin/python3 | |
| # | |
| # this script reads the GeoLite2-Country base and | |
| # for each country | |
| # creates shell scripts with ipset rules | |
| # | |
| # before use this do: | |
| # install pip install maxminddb | |
| # read this: https://www.maxmind.com/en/geolite-free-ip-geolocation-data | |
| # download GeoLite2-Country_YYYYmmdd.tar.gz from MaxMind | |
| # extract GeoLite2-Country.mmdb | |
| # | |
| # published under WTFPL License | |
| import maxminddb | |
| import os | |
| import ipaddress | |
| M = {} | |
| with maxminddb.open_database('GeoLite2-Country.mmdb') as reader: | |
| print("parse base ...") | |
| total = 0 | |
| for network, info in reader: | |
| if not isinstance(network, ipaddress.IPv4Network): | |
| continue | |
| if 'registered_country' in info: | |
| code = info['registered_country']['iso_code'].upper() | |
| if code not in M: | |
| M[code] = [] | |
| M[code].append(network) | |
| total += 1 | |
| elif 'country' in info: | |
| code = info['country']['iso_code'].upper() | |
| if code not in M: | |
| M[code] = [] | |
| M[code].append(network) | |
| total += 1 | |
| else: | |
| print(f"{str(network)} IDK: {info}") | |
| print(f"{total} records collected. create {len(M)} separate scripts ...") | |
| os.makedirs('ipset') | |
| for code in M: | |
| with open(f'ipset/ipset_country_{code}.sh', 'wt') as F: | |
| print("#! /bin/bash", file=F) | |
| C = list(ipaddress.collapse_addresses(M[code])) | |
| print(f"# {len(C)} collapsed regions from {len(M[code])} networks for country {code}", file=F) | |
| print(f"ipset create {code} hash:net || ipset flush {code}", file=F) | |
| for net in C: | |
| print(f"ipset add {code} {str(net)}", file=F) | |
| print(f"ipset save {code} > country_{code}.ipset", file=F) | |
| print("done.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment