Skip to content

Instantly share code, notes, and snippets.

@JonathonReinhart
Created February 19, 2021 05:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JonathonReinhart/0a5d90c8875e6066769c012a797485d5 to your computer and use it in GitHub Desktop.
Save JonathonReinhart/0a5d90c8875e6066769c012a797485d5 to your computer and use it in GitHub Desktop.
Fetch all Google mail netblocks
#!/usr/bin/env python3
import dns.resolver
from ipaddress import IPv4Network, IPv6Network, ip_address
GOOGLE_NETBLOCKS = [
'_netblocks.google.com',
'_netblocks2.google.com',
'_netblocks3.google.com',
]
def query_netblocks_txt(name):
a = dns.resolver.query(name, 'TXT')
assert len(a) == 1
txt = a[0]
# This thing is reall an SPF record, but we'll grab just the IP networks
parts = str(txt).split()
for p in parts:
parts2 = p.split(':', maxsplit=1)
if len(parts2) != 2:
continue
atype, net = parts2
if atype == 'ip4':
yield IPv4Network(net)
elif atype == 'ip6':
yield IPv6Network(net)
else:
raise Exception("WTF:" + str(net))
def load_google_netblocks():
for name in GOOGLE_NETBLOCKS:
yield from query_netblocks_txt(name)
def cmd_list(args):
for net in load_google_netblocks():
print(net)
def cmd_check(args):
netblocks = list(load_google_netblocks())
def in_netblocks(ip):
for net in netblocks:
if ip in net:
return net
for ip in args.ip:
net = in_netblocks(ip)
if net:
print(f"{ip} in {net}")
else:
print(f"{ip} not in Google netblocks")
def parse_args():
import argparse
ap = argparse.ArgumentParser()
sub = ap.add_subparsers(dest='command_name', metavar='COMMAND')
sub.required = True # https://stackoverflow.com/a/18283730/119527
p = sub.add_parser('list',
help="List Google netblocks")
p.set_defaults(func=cmd_list)
p = sub.add_parser('check',
help="Check an IP address to see if it's Google's")
p.set_defaults(func=cmd_check)
p.add_argument("ip", nargs="+", type=ip_address,
help="IP address to check")
return ap.parse_args()
def main():
args = parse_args()
args.func(args)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment