# README
ZAnnotate
ZAnnotate is a Go utility that facilitates annotating large datasets with network metadata. Right now this includes:
- Maxmind GeoIP2
- AS/Routing Data (based on an MRT routing table)
For example, you can add Maxmind geolocation data to a list of IPs:
cat ips.csv | zannotate --geoip2 --geoip2-database=geoip2.mmdb
Installation
ZAnnotate can be installed using make install
make install
or if you don't have make
installed, you can use the following command:
cd cmd/zannotate && go install
Either way, this will install the zannotate
binary in your $GOPATH/bin
directory.
Check that it was installed correctly with:
zannotate --help
Acquiring Datasets
[!NOTE] URLs and instructions may change over time. These are up-to-date as of September 2025.
Below are instructions for getting datasets from the below providers.
GeoLite2-ASN
- Sign-up form for MaxMind GeoLite Access
- Login to your account
- Go to the "GeoIP / GeoLite" > "Download files" section where you should see a list of available databases
- Download the
.mmdb
files for GeoLite ASN - Unzip the downloaded file and test with:
echo "1.1.1.1" | zannotate --geoasn --geoasn-database=/path-to-downloaded-file/GeoLite2-ASN_20250923/GeoLite2-ASN.mmdb
{"ip":"1.1.1.1","geoasn":{"asn":13335,"org":"CLOUDFLARENET"}}
BGP Routing Tables
- Go to https://archive.routeviews.org/route-views2/bgpdata/
- Select a month directory (e.g.
2025.09
) - Select the
RIBS/
directory - Download a BZiped MRT file (e.g.
rib.20250923.1200.bz2
) - Unzip the file with:
bzip2 -d ./path-to-downloaded-file/rib.20250923.1200.bz2
- Test with:
echo "1.1.1.1" | ./zannotate --routing --routing-mrt-file=/tmp/rib.20250923.1200
{"ip":"1.1.1.1","routing":{"prefix":"1.1.1.0/24","asn":13335,"path":[3561,209,3356,13335]}}
Input/Output
Output
By default, ZAnnotate reads new-line delimited IP addresses from standard input and outputs a JSON object per line to standard output like:
echo "1.1.1.1" | zannotate --rdns --geoasn --geoasn-database=/path-to-geo-asn.mmdb
{"ip":"1.1.1.1","geoasn":{"asn":13335,"org":"CLOUDFLARENET"},"rdns":{"domain_names":["one.one.one.one"]}}
If an IP address cannot be annotated, either because of an error or lack of data, there will be an empty field for that annotation. For example, if an IP address is private and therefore has no RDNS or ASN data, the output will look like:
echo "127.0.0.1" | zannotate --rdns --geoasn --geoasn-database=/path-to-geo-asn.mmdb
{"geoasn":{},"rdns":{},"ip":"127.0.0.1"}
Input
You may wish to annotate data that is already in JSON format. You'll then need to use the --input-file-type=json
flag.
This will insert a zannotate
field into the existing JSON object. For example:
echo '{"ip": "1.1.1.1"}' | ./zannotate --rdns --geoasn --geoasn-database=/path-to-geo-asn.mmdb --input-file-type=json
{"ip":"1.1.1.1","zannotate":{"geoasn":{"asn":13335,"org":"CLOUDFLARENET"},"rdns":{"domain_names":["one.one.one.one"]}}}