Created
February 19, 2021 05:29
-
-
Save JonathonReinhart/0a5d90c8875e6066769c012a797485d5 to your computer and use it in GitHub Desktop.
Fetch all Google mail netblocks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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