diff --git a/.github/workflows/whoami.yml b/.github/workflows/whoami.yml new file mode 100644 index 0000000..0cdde6c --- /dev/null +++ b/.github/workflows/whoami.yml @@ -0,0 +1,31 @@ +name: Collect stats on DNS servers using whoami.akamai.net + +on: + push: + paths: + - 'nameservers.txt' + workflow_dispatch: + +jobs: + file-updated: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.x" + - name: Install ASN database + run: | + pip install pyasn + python3 pyasn_util_download.py --latestv46 + python3 pyasn_util_convert.py --single rib.*.bz2 asn.db + - name: Publish stats + run: | + python3 public_dns_servers/whoami.py | tee nameservers_by_asn.json + - name: git add nameservers_by_asn.json + uses: EndBug/add-and-commit@v9 + with: + add: "nameservers_by_asn.json" + default_author: github_actions + message: "refresh nameservers_by_asn.json" diff --git a/public_dns_servers/whoami.py b/public_dns_servers/whoami.py new file mode 100644 index 0000000..f41d078 --- /dev/null +++ b/public_dns_servers/whoami.py @@ -0,0 +1,51 @@ +import sys +import json +import dns.resolver +import pyasn +import ipaddress + +def query_dns(nameserver, domain): + resolver = dns.resolver.Resolver(configure=False) + resolver.timeout = 1 + resolver.lifetime = 1 + resolver.nameservers = [nameserver] + try: + answers = resolver.resolve(domain, 'A') + return str(answers[0]) + except Exception as e: + return f"Error querying {nameserver}: {str(e)}" + +def main(): + # List of DNS nameservers to query + nameservers = open('nameservers.txt').read().splitlines() + + # Domain to query + domain = 'whoami.akamai.net' + + asndb = pyasn.pyasn('asn.db') + + asns = {} + + try: + for nameserver in nameservers: + ip = query_dns(nameserver, domain) + if not ip.startswith('Error'): + try: + asn, subnet = asndb.lookup(ip) + except Exception as e: + print(f"Error getting subnet for {ip}: {str(e)}") + continue + print(f"Nameserver {nameserver} uses IP {ip} (subnet: {subnet}, ASN: {asn})") + try: + asns[asn].add(nameserver) + except KeyError: + asns[asn] = {nameserver} + else: + print(ip) + print(file=sys.stderr) + finally: + asns = {k:sorted(v) for k,v in asns.items()} + print(json.dumps(asns, sort_keys=True, indent=2)) + +if __name__ == "__main__": + main()