Skip to content

Instantly share code, notes, and snippets.

@SpareSimian
Created November 30, 2022 01:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SpareSimian/4205c9ebb65af14e264e9e3fe5e5c7c6 to your computer and use it in GitHub Desktop.
Save SpareSimian/4205c9ebb65af14e264e9e3fe5e5c7c6 to your computer and use it in GitHub Desktop.
Convert a list of records from iptoasn.com to a firewalld ipset XML file.
#!/usr/bin/env python3
""" Convert a list of records from iptoasn.com to a firewalld ipset XML file.
Download https://iptoasn.com/data/ip2asn-v4.tsv.gz, uncompress, filter
with grep, and feed to this script to generate a file to place in
/etc/firewalld/ipsets for use in firewall rules.
Example:
wget -q -O - https://iptoasn.com/data/ip2asn-v4.tsv.gz | \
gunzip | grep "DIGITALOCEAN" | ./asntoipset.py > /etc/firewalld/ipsets/DigitalOcean.xml
To match country codes, try 'grep -v -P "\tUS\t"' as your filter.
Requires the netaddr package to extract CIDR lists from a range of IP addresses.
Requires ElementTree from Python > 3.7 that includes the indent method.
"""
import sys
if (len(sys.argv) == 1):
fobj = sys.stdin
else:
fobj = open(sys.argv[-1], 'r') # command-line argument
import csv
reader = csv.DictReader(fobj, ["range_start", "range_end", "AS_number", "country_code", "AS_description"], delimiter="\t")
records = []
for row in reader:
records.append(dict(row))
from netaddr import IPRange
networks = []
for record in records:
range = IPRange(record["range_start"], record["range_end"])
networks.extend(range.cidrs());
import xml.etree.ElementTree as ET
ipset = ET.Element("ipset", type="hash:net")
ET.SubElement(ipset, "option", name="maxelem", value=str(len(networks)))
ET.SubElement(ipset, "option", name="family", value="inet")
for network in networks:
ET.SubElement(ipset, "entry").text = str(network)
tree = ET.ElementTree(ipset)
ET.indent(tree)
# standard streams are "text" and utf-8 is binary, so switch stdout
# to binary output mode with detach method
sys.stdout = sys.stdout.detach()
tree.write(sys.stdout, encoding="utf-8", xml_declaration=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment