1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- #!/usr/bin/env python
- # Maintained at https://code.ffdn.org/zorun/dn42-scripts
- """This script generates DNS TXT records containing ASN information.
- The idea comes from asn.cymru.com. Example:
- dig +short AS1.asn.cymru.com TXT
- The output looks like this:
- "1 | US | arin | 2001-09-20 | LVLT-1 - Level 3 Communications, Inc."
- In dn42, we try to respect this format. Fields 2 and 3 are set to "DN42"
- and "dn42", respectively. The date field is left empty, as we currently
- do not record this information in the registry. For the last field, we use
- "[as-name] [descr]" from the registry.
- """
- import sys
- import time
- import argparse
- from registry import AutNum
- def gen_zone(args):
- out = args.output
- # SOA and stuff
- out.write("$ORIGIN {}\n".format(args.zone))
- out.write("$TTL {}\n".format(args.ttl))
- serial = int(time.time())
- out.write("@ IN SOA {0.ns[0]} {0.rname} "
- "({1} {0.refresh} {0.retry} {0.expire} {0.negative})\n".format(args,
- serial))
- # NS
- for ns in args.ns:
- out.write("@ NS {}\n".format(ns))
- # TXT data
- autnum = AutNum(args.registry)
- for (asn, data) in autnum.data.items():
- comment = ""
- if "as-name" in data:
- comment = data["as-name"][0]
- if "descr" in data:
- comment += " " + data["descr"][0]
- comment.replace('"', '')
- # Bind and NSD are quite happy with UTF-8 in TXT records, but
- # KnotDNS isn't (at least Knot 1.4.7). This is a hack to work around this.
- comment = comment.encode('ascii', errors='xmlcharrefreplace').decode()
- out.write('{} TXT "{} | DN42 | dn42 | | {}"\n'.format(asn, asn[2:], comment))
- def cleanup(args):
- def final_dot(s):
- if not s.endswith('.'):
- return s + "."
- else:
- return s
- args.zone = final_dot(args.zone)
- args.rname = args.rname.replace("@", ".")
- args.rname = final_dot(args.rname)
- for (i, ns) in enumerate(args.ns):
- args.ns[i] = final_dot(ns)
- if __name__ == "__main__":
- parser = argparse.ArgumentParser(description=__doc__)
- parser.add_argument("-n", "--ns", action="append", required=True,
- help="name server, can be passed multiple times (the first one will be listed as master in the SOA)")
- parser.add_argument("-r", "--rname", required=True,
- help="contact email of the administrator of the zone")
- parser.add_argument("-o", "--output", default=sys.stdout, type=argparse.FileType('w'),
- help="output file (default: stdout)")
- parser.add_argument("registry", help="path to the monotone registry")
- opt = parser.add_argument_group("Zone options")
- opt.add_argument("-z", "--zone", default="asn.dn42.",
- help="zone to generate data for (default: %(default)s)")
- opt.add_argument("-t", "--ttl", default="1h",
- help="TTL for all records (default: %(default)s)")
- opt.add_argument("--refresh", default="1d",
- help="refresh timer for slaves (default: %(default)s)")
- opt.add_argument("--retry", default="1h",
- help="retry timer for slaves (default: %(default)s)")
- opt.add_argument("--expire", default="4w",
- help="expire time for slaves (default: %(default)s)")
- opt.add_argument("--negative", default="5m",
- help="negative TTL (default: %(default)s)")
- args = parser.parse_args()
- # Sanity checks
- cleanup(args)
- gen_zone(args)
|