ascension

Migrate DNS zones to the GNU Name System
Log | Files | Refs | README | LICENSE

commit 523342ba45f078b64a4d10badb7df4e51f5145c1
parent 428ca05b1384014a91fa66c3779c788afa9a3310
Author: rexxnor <rexxnor+gnunet@brief.li>
Date:   Thu,  9 May 2019 00:36:20 +0200

fixed bugs, updated create and get pkey

Diffstat:
Mascension/ascension.py | 93++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Mascension/test/basic_named.conf | 1+
2 files changed, 58 insertions(+), 36 deletions(-)

diff --git a/ascension/ascension.py b/ascension/ascension.py @@ -267,10 +267,10 @@ class Ascender(): taskqueue.task_done() # End of worker - + # Check if a delegated zone is available in GNS as per NS record - nsrecords = self.zone.iterate_rdatas(dns.rdatatype.NS) + nsrecords = self.zone.iterate_rdatasets(dns.rdatatype.NS) # This is broken if your NS is for ns.foo.YOURZONE as you add # the PKEY to YOURZONE instead of to the foo.YOURZONE subzone. @@ -283,26 +283,35 @@ class Ascender(): # foo.bar A IN 1.2.3.4 # => bar PKEY GNS $NEWKEY + mapping: bar => $NEWKEY # => foo[.bar] A GNS 1.2.3.4 - gnspkey = list(filter(lambda record: for rec in record[2]: if str(rec).startswith('gns--pkey--'): return true; return false, nsrecords)) + #gnspkey = list(filter(lambda record: for rec in record[2]: if str(rec).startswith('gns--pkey--'): return true; return false, nsrecords)) for nsrecord in nsrecords: name = str(nsrecord[0]) - ttl = nsrecord[1] - values = nsrecord[2] + values = nsrecord[1] + ttl = values.ttl + #if values.startswith('gns--pkey--'): + # gnspkeys.add() gnspkeys = list(filter(lambda record: str(record).startswith('gns--pkey--'), values)) - if len(gnspkeys) > 1: - logging.critical("Detected ambiguous PKEY records for label %s (not generating PKEY record)", name) + + num_gnspkeys = len(gnspkeys) + if not num_gnspkeys: + # skip empty values + continue + if num_gnspkeys > 1: + logging.critical("Detected ambiguous PKEY records for label \ + %s (not generating PKEY record)", name) continue - gnspkey = gnspkeys[0] + + gnspkey = str(gnspkeys[0]) # FIXME: check that this is actucally a well-formed PKEY string! (Crockford base32, sufficient length) - self.add_pkey_record_to_zone(pkey[11:], self.domain, name, ttl) + self.add_pkey_record_to_zone(gnspkey[11:], self.domain, name, ttl) # FIXME: drop all NS records under this name later! => new map, if entry present during NS processing, skip! - + # Unify all records under same label into a record set customrdataset = dict() for name, rdset in self.zone.iterate_rdatasets(): # build lookup table for later GNS2DNS records name = str(name) # Name could be str or DNS.name.Name - if customrdataset.get(name)) is None: + if customrdataset.get(name) is None: work = list() work.append(rdset) customrdataset[name] = work @@ -386,13 +395,23 @@ class Ascender(): def resolve_glue(self, authorityname: str) -> list: - rdsets = self.zone[dnsresolver].rdatasets + """ + Resolves IP Adresses within zone + :param authorityname: + """ + try: + rdsets = self.zone[authorityname].rdatasets + except KeyError: + return [] value = [] for rdataset in rdsets: if rdataset.rdtype in [dns.rdatatype.A, dns.rdatatype.AAAA]: - value.append("%s@%s" % (zonename, str(rdataset))) + for rdata in rdataset: + value.append("%s.%s@%s" % (authorityname, + self.domain, + str(rdata))) return value - + def transform_to_gns_format(self, record: dns.rdata.Rdata, rdtype: dns.rdata.Rdata, @@ -430,18 +449,28 @@ class Ascender(): else: value = "%s.%s" % (value, zonename) elif rdtype == 'NS': - nameserver = str(record) + nameserver = str(record.target) + if nameserver[-1] == ".": + nameserver = nameserver[:-1] if value[-1] == ".": # FQDN provided - if value.endswith("." + zonename): - # in bailiwick - value = resolve_glue (self, nameserver) + if value.endswith(".%s." % zonename): + # in bailiwick + value = self.resolve_glue(record.target) else: # out of bailiwick - value = '%s.%s@%s' % (str(label), zonename, dnsresolver) + if label.startswith("@"): + value = '%s@%s' % (zonename, nameserver) + else: + value = '%s.%s@%s' % (str(label), zonename, nameserver) else: # Name is relative to zone, must be in bailiwick - value = resolve_glue (self, nameserver) + value = self.resolve_glue(record.target) + if not value: + if label.startswith("@"): + value = '%s@%s.%s' % (self.domain, record.target, self.domain) + else: + value = '%s.%s@%s.%s' % (str(label), self.domain, record.target, self.domain) logging.info("transformed %s record to GNS2DNS format", rdtype) rdtype = 'GNS2DNS' @@ -559,26 +588,14 @@ class Ascender(): """ try: ret = sp.run([GNUNET_ZONE_CREATION_COMMAND, - '-C', zonestring], - stdout=sp.DEVNULL, + '-C', zonestring, + '-V'], + stdout=sp.PIPE, stderr=sp.DEVNULL) logging.info("executed command: %s", " ".join(ret.args)) + pkey_zone = ret.stdout.decode().strip() except sp.CalledProcessError: logging.info("Zone %s already exists!", zonestring) - - # This is the most inefficient part of the zone hierarchy building - pkey_lookup = sp.Popen([GNUNET_ZONE_CREATION_COMMAND, - '-d'], - stdout=sp.PIPE) - pkey_line = sp.Popen(['grep', '^' + zonestring], - stdin=pkey_lookup.stdout, - stdout=sp.PIPE) - pkey_zone = sp.check_output(['cut', '-d', - ' ', '-f3'], - stdin=pkey_line.stdout) - pkey_zone = pkey_zone.decode().strip() - pkey_lookup.stdout.close() - pkey_line.stdout.close() return pkey_zone @staticmethod @@ -675,6 +692,7 @@ def main(): # Set to defaults to use before we get a SOA for the first time retry = 300 refresh = 300 + # Main loop for actual daemon while True: gns_zone_serial = ascender.get_gns_zone_serial() @@ -698,9 +716,11 @@ def main(): continue if not gns_zone_serial: logging.info("GNS zone does not exist yet, performing full transfer.") + print("GNS zone does not exist yet, performing full transfer.") ascender.bootstrap_zone() elif gns_zone_serial == dns_zone_serial: logging.info("GNS zone is up to date.") + print("GNS zone is up to date.") if standalone: return 0 time.sleep(refresh) @@ -714,6 +734,7 @@ def main(): continue else: logging.info("GNS zone is out of date, performing incremental transfer.") + print("GNS zone is out of date, performing incremental transfer.") try: ascender.zone = dns.zone.from_xfr(ascender.zonegenerator, diff --git a/ascension/test/basic_named.conf b/ascension/test/basic_named.conf @@ -1,4 +1,5 @@ options { + port 5000; directory "."; pid-file "/run/named/named.pid";