Skip to content

Instantly share code, notes, and snippets.

@itshaadi
Last active January 20, 2021 11:55
Show Gist options
  • Save itshaadi/f6d0ba418540ae1b6f79fbb2d0b80a44 to your computer and use it in GitHub Desktop.
Save itshaadi/f6d0ba418540ae1b6f79fbb2d0b80a44 to your computer and use it in GitHub Desktop.
GeoIP no-route

Usage

this script will generate routing files for ocserv and iproute2 based on MaxMind's GeoLite2

usage: generate.py [-h] [-i] [-g] [-cc]

optional arguments:
  -h, --help  show this help message and exit
  -i          CSV Dir
  -g          gateway
  -cc         ISO country code


eg: ./generate.py -i csv/ -cc us -g 192.168.1.1

iproute2

# add rules
ip -force -batch route.add.txt

# delete rules
ip -force -batch route.del.txt
#!/bin/sh
set -eou pipefail
pushd `dirname "$0"` > /dev/null
readonly pathscript=`pwd`
popd > /dev/null
CSV_URL="https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country-CSV&license_key=JvbzLLx7qBZT&suffix=zip"
if [ ! -x `command -v unzip` ]; then
echo "this script requires unzip"
fi
if ! [ -d "${pathscript}/csv" ]; then
mkdir -p "${pathscript}/csv"
else
rm -r "${pathscript}/csv"
fi
curl -L ${CSV_URL} -o GeoLite2-Country-CSV.zip
unzip GeoLite2-Country-CSV.zip
rm -f GeoLite2-Country-CSV.zip
mv GeoLite2* csv
#!/bin/env python3
import os
import sys
import csv
import argparse
from ipaddress import IPv4Network
def get_path(filename, input_dir):
if input_dir.endswith("/"):
input_dir = input_dir[:-1]
file_path = "{}/{}".format(input_dir, filename)
if not os.path.isfile(file_path):
raise FileNotFoundError(file_path)
return file_path
def gonameid(country_code, input_file):
country_code = country_code.upper()
with open(input_file) as csv_file:
content = csv.reader(csv_file, delimiter=",")
for row in content:
if row[4] == country_code:
return row[0]
def networks(areacode, input_file):
adresses = []
with open(input_file) as csv_file:
content = csv.reader(csv_file, delimiter=",")
for row in content:
if row[1] == areacode or row[2] == areacode:
adresses.append(row[0])
return set(adresses)
def main(country_code, gateway, input_dir):
try:
country_locations = get_path("GeoLite2-Country-Locations-en.csv", input_dir)
country_blocks = get_path("GeoLite2-Country-Blocks-IPv4.csv", input_dir)
except FileNotFoundError as e:
sys.exit("No such file or directory: '{}'".format(e))
areacode = gonameid(country_code, country_locations)
adresses = networks(areacode, country_blocks)
with open("route.add.txt", "w") as f:
for ip in adresses:
f.write("route add {} via {}\n".format(ip, gateway))
with open("route.del.txt", "w") as f:
for ip in adresses:
f.write("route del {} via {}\n".format(ip, gateway))
filename = "ocserv-{}-no-route.txt".format(country_code.lower())
with open(filename, "w") as f:
for ip in adresses:
ipnet = IPv4Network(ip)
f.write("no-route = {}/{}\n".format(ipnet.network_address, ipnet.netmask))
if __name__ == "__main__":
argparser = argparse.ArgumentParser()
argparser.add_argument(
"-i",
metavar="",
type=str,
required=False,
default="{}/csv".format(os.getcwd()),
help="CSV Dir"
)
argparser.add_argument(
"-g",
metavar="",
type=str,
required=False,
default="192.168.1.1",
help="gateway"
)
argparser.add_argument(
"-cc",
metavar="",
type=str,
required=False,
default="IR",
help="ISO country code"
)
args = argparser.parse_args()
if not os.path.isdir(args.i):
sys.exit("The path specified does not exist")
main(args.cc, args.g, args.i)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment