ascension

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

commit b15fbf76712439230882deb1d739e6fe6d1d23dd
parent 3d9b0cb2a4cb7f0a86d128c6a8afc8e006e0e1cb
Author: rexxnor <rexxnor+gnunet@brief.li>
Date:   Fri, 10 May 2019 10:12:01 +0200

ascension dry-run fixes, packaging, ascension-bind

Diffstat:
Mascension/ascension.py | 21++++++++++++---------
Adeb_dist/ascension-0.5.0/.pc/.quilt_patches | 1+
Adeb_dist/ascension-0.5.0/.pc/.quilt_series | 1+
Adeb_dist/ascension-0.5.0/.pc/.version | 1+
Adeb_dist/ascension-0.5.0/.pc/applied-patches | 0
Adeb_dist/ascension-0.5.0/.pybuild/pythonX.Y_3.5/.pydistutils.cfg | 11+++++++++++
Adeb_dist/ascension-0.5.0/PKG-INFO | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.5.0/README | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.5.0/ascension.1 | 108+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.5.0/ascension/__init__.py | 0
Adeb_dist/ascension-0.5.0/ascension/ascension.py | 750+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.5.0/debian/ascension.1 | 45+++++++++++++++++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.5.0/debian/changelog | 5+++++
Adeb_dist/ascension-0.5.0/debian/compat | 1+
Adeb_dist/ascension-0.5.0/debian/control | 33+++++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.5.0/debian/copyright | 21+++++++++++++++++++++
Adeb_dist/ascension-0.5.0/debian/debhelper-build-stamp | 1+
Adeb_dist/ascension-0.5.0/debian/files | 2++
Adeb_dist/ascension-0.5.0/debian/python3-ascension.manpages | 1+
Adeb_dist/ascension-0.5.0/debian/python3-ascension.postinst | 41+++++++++++++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.5.0/debian/python3-ascension.postinst.debhelper | 7+++++++
Adeb_dist/ascension-0.5.0/debian/python3-ascension.prerm.debhelper | 10++++++++++
Adeb_dist/ascension-0.5.0/debian/python3-ascension.substvars | 3+++
Adeb_dist/ascension-0.5.0/debian/python3-ascension/DEBIAN/control | 31+++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.5.0/debian/python3-ascension/DEBIAN/md5sums | 12++++++++++++
Adeb_dist/ascension-0.5.0/debian/python3-ascension/DEBIAN/postinst | 3+++
Adeb_dist/ascension-0.5.0/debian/python3-ascension/DEBIAN/prerm | 12++++++++++++
Adeb_dist/ascension-0.5.0/debian/python3-ascension/usr/bin/ascension | 12++++++++++++
Adeb_dist/ascension-0.5.0/debian/python3-ascension/usr/man/man1/ascension.1 | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.5.0/debian/python3-ascension/usr/share/doc/python3-ascension/changelog.Debian.gz | 0
Adeb_dist/ascension-0.5.0/debian/python3-ascension/usr/share/doc/python3-ascension/copyright | 21+++++++++++++++++++++
Adeb_dist/ascension-0.5.0/debian/python3-ascension/usr/share/man/man1/ascension.1.gz | 0
Adeb_dist/ascension-0.5.0/debian/rules | 8++++++++
Adeb_dist/ascension-0.5.0/debian/source/format | 1+
Adeb_dist/ascension-0.5.0/debian/watch | 5+++++
Adeb_dist/ascension-0.5.0/setup.cfg | 4++++
Adeb_dist/ascension-0.5.0/setup.py | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.6.1/.pc/.quilt_patches | 1+
Adeb_dist/ascension-0.6.1/.pc/.quilt_series | 1+
Adeb_dist/ascension-0.6.1/.pc/.version | 1+
Adeb_dist/ascension-0.6.1/.pc/applied-patches | 0
Adeb_dist/ascension-0.6.1/PKG-INFO | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.6.1/README | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.6.1/ascension.1 | 108+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.6.1/ascension/__init__.py | 0
Adeb_dist/ascension-0.6.1/ascension/ascension.py | 789+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.6.1/debian/.debhelper/generated/python3-ascension/installed-by-dh_installdocs | 0
Adeb_dist/ascension-0.6.1/debian/changelog | 5+++++
Adeb_dist/ascension-0.6.1/debian/compat | 1+
Adeb_dist/ascension-0.6.1/debian/control | 36++++++++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.6.1/debian/files | 2++
Adeb_dist/ascension-0.6.1/debian/python3-ascension.postinst.debhelper | 7+++++++
Adeb_dist/ascension-0.6.1/debian/python3-ascension.prerm.debhelper | 10++++++++++
Adeb_dist/ascension-0.6.1/debian/python3-ascension.substvars | 3+++
Adeb_dist/ascension-0.6.1/debian/python3-ascension/DEBIAN/control | 30++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.6.1/debian/python3-ascension/DEBIAN/md5sums | 10++++++++++
Adeb_dist/ascension-0.6.1/debian/python3-ascension/DEBIAN/postinst | 9+++++++++
Adeb_dist/ascension-0.6.1/debian/python3-ascension/DEBIAN/prerm | 12++++++++++++
Adeb_dist/ascension-0.6.1/debian/python3-ascension/usr/bin/ascension | 12++++++++++++
Adeb_dist/ascension-0.6.1/debian/python3-ascension/usr/man/man1/ascension.1 | 108+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.6.1/debian/python3-ascension/usr/share/doc/python3-ascension/changelog.Debian.gz | 0
Adeb_dist/ascension-0.6.1/debian/rules | 31+++++++++++++++++++++++++++++++
Adeb_dist/ascension-0.6.1/debian/source/format | 1+
Adeb_dist/ascension-0.6.1/debian/source/options | 2++
Adeb_dist/ascension-0.6.1/setup.cfg | 4++++
Adeb_dist/ascension-0.6.1/setup.py | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adeb_dist/python3-ascension_0.5.0-1_all.deb | 0
Adeb_dist/python3-ascension_0.6.1-1_all.deb | 0
Mdebian/ascension-bind-0.0.1/debian/ascension-bind.config | 32+++++++++++++++++---------------
Mdebian/ascension-bind-0.0.1/debian/ascension-bind/DEBIAN/config | 32+++++++++++++++++---------------
Mdebian/ascension-bind-0.0.1/debian/ascension-bind/DEBIAN/control | 2+-
Ahelpers/python3-ascension.postinst | 46++++++++++++++++++++++++++++++++++++++++++++++
Ahelpers/python3-ascension.prerm | 22++++++++++++++++++++++
73 files changed, 2954 insertions(+), 40 deletions(-)

diff --git a/ascension/ascension.py b/ascension/ascension.py @@ -702,6 +702,18 @@ def main(): if debug: logging.basicConfig(level=logging.DEBUG) + # Initialize class instance + ascender = Ascender(domain, transferns, port, flags, minimum) + + # Do dey run before GNUnet check + if dryrun: + dns_zone_serial = ascender.get_dns_zone_serial(ascender.domain, + ascender.transferns) + if not dns_zone_serial: + return 1 + else: + return 0 + # Checks if GNUnet services are running try: sp.check_output([GNUNET_ARM_COMMAND, '-I'], timeout=1) @@ -709,9 +721,6 @@ def main(): logging.critical('GNUnet services are not running!') sys.exit(1) - # Initialize class instance - ascender = Ascender(domain, transferns, port, flags, minimum) - # Set to defaults to use before we get a SOA for the first time retry = 300 refresh = 300 @@ -732,12 +741,6 @@ def main(): dns_zone_serial = ascender.get_dns_zone_serial(ascender.domain, ascender.transferns) - if dryrun: - if not dns_zone_serial: - return 1 - else: - return 0 - if not dns_zone_serial: logging.error("Could not get DNS zone serial") if standalone: diff --git a/deb_dist/ascension-0.5.0/.pc/.quilt_patches b/deb_dist/ascension-0.5.0/.pc/.quilt_patches @@ -0,0 +1 @@ +debian/patches diff --git a/deb_dist/ascension-0.5.0/.pc/.quilt_series b/deb_dist/ascension-0.5.0/.pc/.quilt_series @@ -0,0 +1 @@ +series diff --git a/deb_dist/ascension-0.5.0/.pc/.version b/deb_dist/ascension-0.5.0/.pc/.version @@ -0,0 +1 @@ +2 diff --git a/deb_dist/ascension-0.5.0/.pc/applied-patches b/deb_dist/ascension-0.5.0/.pc/applied-patches diff --git a/deb_dist/ascension-0.5.0/.pybuild/pythonX.Y_3.5/.pydistutils.cfg b/deb_dist/ascension-0.5.0/.pybuild/pythonX.Y_3.5/.pydistutils.cfg @@ -0,0 +1,11 @@ +[clean] +all=1 +[build] +build-lib=/mnt/ascension/deb_dist/ascension-0.5.0/.pybuild/pythonX.Y_3.5/build +[install] +force=1 +install-layout=deb +install-scripts=/usr/bin +install-lib=/usr/lib/python3.5/dist-packages +[easy_install] +allow_hosts=None diff --git a/deb_dist/ascension-0.5.0/PKG-INFO b/deb_dist/ascension-0.5.0/PKG-INFO @@ -0,0 +1,76 @@ +Metadata-Version: 1.1 +Name: ascension +Version: 0.5.0 +Summary: Tool to migrate DNS Zones to the GNU Name System +Home-page: https://gnunet.org/git/ascension.git/ +Author: rexxnor +Author-email: rexxnor+gnunet@brief.li +License: UNKNOWN +Description: # Ascension + + Tool to easily migrate existing DNS Zones into the GNU Name System using + incremental zone transfers (AXFR/IXFR). + + ## How to install + To install the ascension simply execute one of the following commands in the + freshly cloned directory: + + ```bash + # System wide installation + sudo python3 setup.py install + + # Local installation through virtualenv + python3 -m venv .venv + source .venv/bin/activate + python3 setup.py install + ``` + + ## How to install (Developer) + A developer installation is very handy when you are making changes to the source + code as this way you don't need to re-run the installation procedure every time + you make a change. + + ```bash + # installation through virtualenv + python3 -m venv .venv + source .venv/bin/activate + python3 setup.py develop + ``` + + ## How to use + If you have installed it, simply execute ascension with one of several options. + You can also just run the file ascension.py itself directly. + + Taken from the docstring of the ascension.py file: + ``` + Ascension + + Usage: + ascension <domain> [-d] [-p] + ascension <domain> <port> [-d] [-p] + ascension <domain> -n <transferns> [-d] [-p] + ascension <domain> -n <transferns> <port> [-d] [-p] + ascension -p | --public + ascension -h | --help + ascension -v | --version + + Options: + <domain> Domain to migrate + <port> Port for zone transfer + <transferns> DNS Server that does the zone transfer + -p --public Make records public on the DHT + -d --debug Enable debugging + -h --help Show this screen. + -v --version Show version. + ``` + + Example use: + ``` + # Transfers the sy TLD from ns1.tld.sy. + ascension sy -n ns1.tld.sy. + # Transfers the nu TLD from zonedata.iis.se with debug options enabled + ascension nu -n zonedata.iis.se. -d + ``` + +Platform: UNKNOWN +Classifier: Programming Language :: Python :: 3 diff --git a/deb_dist/ascension-0.5.0/README b/deb_dist/ascension-0.5.0/README @@ -0,0 +1,65 @@ +# Ascension + +Tool to easily migrate existing DNS Zones into the GNU Name System using +incremental zone transfers (AXFR/IXFR). + +## How to install +To install the ascension simply execute one of the following commands in the +freshly cloned directory: + +```bash +# System wide installation +sudo python3 setup.py install + +# Local installation through virtualenv +python3 -m venv .venv +source .venv/bin/activate +python3 setup.py install +``` + +## How to install (Developer) +A developer installation is very handy when you are making changes to the source +code as this way you don't need to re-run the installation procedure every time +you make a change. + +```bash +# installation through virtualenv +python3 -m venv .venv +source .venv/bin/activate +python3 setup.py develop +``` + +## How to use +If you have installed it, simply execute ascension with one of several options. +You can also just run the file ascension.py itself directly. + +Taken from the docstring of the ascension.py file: +``` +Ascension + +Usage: + ascension <domain> [-d] [-p] + ascension <domain> <port> [-d] [-p] + ascension <domain> -n <transferns> [-d] [-p] + ascension <domain> -n <transferns> <port> [-d] [-p] + ascension -p | --public + ascension -h | --help + ascension -v | --version + +Options: + <domain> Domain to migrate + <port> Port for zone transfer + <transferns> DNS Server that does the zone transfer + -p --public Make records public on the DHT + -d --debug Enable debugging + -h --help Show this screen. + -v --version Show version. +``` + +Example use: +``` +# Transfers the sy TLD from ns1.tld.sy. +ascension sy -n ns1.tld.sy. +# Transfers the nu TLD from zonedata.iis.se with debug options enabled +ascension nu -n zonedata.iis.se. -d +``` diff --git a/deb_dist/ascension-0.5.0/ascension.1 b/deb_dist/ascension-0.5.0/ascension.1 @@ -0,0 +1,108 @@ +.\" This file is part of Ascension. +.\" Copyright (C) 2018,2019 GNUnet e.V. +.\" +.\" Permission is granted to copy, distribute and/or modify this document +.\" under the terms of the GNU Free Documentation License, Version 1.3 or +.\" any later version published by the Free Software Foundation; with no +.\" Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A +.\" copy of the license is included in the file +.\" ``FDL-1.3''. +.\" +.\" A copy of the license is also available from the Free Software +.\" Foundation Web site at http://www.gnu.org/licenses/fdl.html. +.\" +.\" Alternately, this document is also available under the General +.\" Public License, version 3 or later, as published by the Free Software +.\" Foundation. A copy of the license is included in the file +.\" ``GPL3''. +.\" +.\" A copy of the license is also available from the Free Software +.\" Foundation Web site at http://www.gnu.org/licenses/gpl.html. +.\" +.\" SPDX-License-Identifier: GPL3.0-or-later OR FDL1.3-or-later +.\" +.Dd May 1, 2019 +.Dt ASCENSION 1 +.Os +.Sh NAME +.Nm ascension +.Nd migrate existing DNS zones into the GNU Name System +.Sh SYNOPSIS +.Nm +.Op Ar domain Fl d Fl p Fl s \- minimum-ttl=<ttl> \- dry-run +.Op Ar domain port Fl d Fl p Fl s \- minimum-ttl=<ttl> \- dry-run +.Op Ar domain Fl n Ar transferns Fl d Fl p Fl s Fl \- minimum-ttl=<ttl> \- dry-run +.Op Ar domain Fl n Ar transferns Ar port Fl d Fl p Fl s \- minimum-ttl=<ttl> \- dry-run +.Op Fl d | \-debug +.Op Fl h | \-help +.Op Fl p | \-public +.Op Fl v | \-version +.Op Fl s | \-standalone +.Sh DESCRIPTION +.Nm +is a tool to migrate existing DNS Zones into the GNU Name System (GNS) using incremental zone transfers (AXFR/IXFR). +To achieve this it uses +.Xr gnunet-identity 1 , +.Xr gnunet-namestore 1 , +.Xr gnunet-gns 1 . +As +.Nm +relies on these 3 GNUnet services, +.Xr gnunet-arm 1 +must be installed and running. +.Bl -tag -width Ds +.It Ar domain Fl d Fl p Fl s Fl minimum-ttl=<ttl> +Migrate the DOMAIN passed as domain. +The debug, public and standalone options are optional. +.It Ar domain port Fl d Fl p Fl s Fl minimum-ttl=<ttl> +Migrate the DOMAIN domain, using port for zone transfer. +The debug, public and standalone options are optional. +.It Ar domain Fl n Ar transferns Fl d Fl p Fl s Fl minimum-ttl=<ttl> +Migrate the DOMAIN domain from the DNS server transferns. +The debug, public and standalone options are optional. +.It Ar domain Fl n Ar transferns Ar port Fl d Fl p Fl s Fl minimum-ttl=<ttl> +Migrate the DOMAIN domain from the DNS server transferns using port for the zone transfer. +The debug, public and standalone options are optional. +.It Fl s | \-standalone +Run Ascension once +.It Fl d | \-debug +Enable debugging +.It Fl h | \-help +Print short help on options +.It Fl p | \-public +Make records public on the DHT +.It Fl v | \-version +Print ascension version number +.El +.\" .Sh FILES +.Sh EXAMPLES +To transfer the sy TLD from ns1.tld.sy: +.Pp +.Dl $ ascension sy -n ns1.tld.sy. +.Pp +To transfer the nu TLD from zonedata.iis.se with debug options enabled: +.Pp +.Dl $ ascension nu -n zonedata.iis.se. -d +.Sh SEE ALSO +.Xr gnunet-arm 1 , +.Xr gnunet-gns 1 , +.Xr gnunet-identity 1 , +.Xr gnunet-namestore 1 +.Sh HISTORY +The +.Nm +tool was designed and written in 2018 by +.An rexxnor Aq Mt rexxnor+gnunet@brief.li . +.Sh AUTHORS +This man page was written by +.An ng0 Aq Mt ng0@gnunet.org +and updated by +.An rexxnor Aq Mt rexxnor+gnunet@brief.li +it first appeared in +.Nm +0.5.1. +.Sh BUGS +Report bugs by using +.Lk https://bugs.gnunet.org +or by sending electronic mail to +.Aq Mt bug-gnunet@gnu.org . diff --git a/deb_dist/ascension-0.5.0/ascension/__init__.py b/deb_dist/ascension-0.5.0/ascension/__init__.py diff --git a/deb_dist/ascension-0.5.0/ascension/ascension.py b/deb_dist/ascension-0.5.0/ascension/ascension.py @@ -0,0 +1,750 @@ +#!/usr/bin/env python3 +# This file is part of Ascension. +# Copyright (C) 2019 GNUnet e.V. +# +# Ascension is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Ascension is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# SPDX-License-Identifier: AGPL3.0-or-later +# +# Author rexxnor +""" +Usage: + ascension <domain> [-d] [-p] [-s] [--minimum-ttl=<ttl>] + ascension <domain> <port> [-d] [-p] [-s] [--minimum-ttl=<ttl>] + ascension <domain> -n <transferns> [-d] [-p] [-s] [--minimum-ttl=<ttl>] + ascension <domain> -n <transferns> <port> [-d] [-p] [-s] [--minimum-ttl=<ttl>] + ascension -p | --public + ascension -s | --standalone + ascension -h | --help + ascension -v | --version + +Options: + <domain> Domain to migrate + <port> Port for zone transfer + <transferns> DNS Server that does the zone transfer + --minimum-ttl=<ttl> Minimum TTL for records to migrate [default: 3600] + -p --public Make records public on the DHT + -s --standalone Run ascension once + -d --debug Enable debugging + -h --help Show this screen. + -v --version Show version. +""" + +# imports +import logging +import queue +import re +import socket +import sys +import time +import subprocess as sp +import threading +import dns.query +import dns.resolver +import dns.zone +import docopt + +# GLOBALS +GNUNET_ZONE_CREATION_COMMAND = 'gnunet-identity' +GNUNET_NAMESTORE_COMMAND = 'gnunet-namestore' +GNUNET_GNS_COMMAND = 'gnunet-gns' +GNUNET_ARM_COMMAND = 'gnunet-arm' +# TODO find better solution for ignoring DNSSEC record types +SUPPORTED_RECORD_TYPES = [ + "A", "AAAA", "NS", "MX", "SRV", "TXT", "CNAME" +] + +class Ascender(): + """ + Class that provides migration for any given domain + """ + @classmethod + def __init__(cls, domain, transferns, port, flags, minimum): + cls.domain = domain + if domain[-1] == '.': + cls.domain = cls.domain[:-1] + cls.port = int(port) + cls.transferns = transferns + cls.soa = None + cls.tld = cls.domain.split(".")[::-1][0] + cls.zone = None + cls.zonegenerator = None + cls.nscache = dict() + cls.flags = flags + cls.minimum = int(minimum) + cls.subzonedict = dict() + + @classmethod + def initial_zone_transfer(cls, serial=None): + """ + Initialize the zone transfer generator + :param serial: The serial to base the transfer on + """ + if serial: + cls.zonegenerator = dns.query.xfr(cls.transferns, + cls.domain, + rdtype=dns.rdatatype.IXFR, + serial=serial, + port=cls.port) + else: + cls.zonegenerator = dns.query.xfr(cls.transferns, + cls.domain, + port=cls.port) + + @classmethod + def bootstrap_zone(cls): + """ + Creates the zone in gnunet + """ + try: + ret = sp.run([GNUNET_ZONE_CREATION_COMMAND, + '-C', cls.domain]) + logging.info("executed command: %s", " ".join(ret.args)) + except sp.CalledProcessError: + logging.info("Zone %s already exists!", cls.domain) + + @classmethod + def get_current_serial(cls, domain, resolver=None): + """ + Gets the current serial for a given zone + :param domain: Domain to query for in DNS + :param resolver: Nameserver to query in DNS, defaults to None + :returns: Serial of the zones SOA record + """ + # Makes domains better resolvable + domain = domain + "." + # SOA is different if taken directly from SOA record + # compared to AXFR/IXFR - changed to respect this + try: + soa_answer = dns.resolver.query(domain, 'SOA') + except dns.resolver.NoAnswer: + logging.critical("the domain '%s' does not exist", domain) + sys.exit(1) + except dns.resolver.NXDOMAIN: + logging.critical("the domain '%s' is invalid", domain) + sys.exit(1) + master_answer = dns.resolver.query(soa_answer[0].mname, 'A') + try: + if resolver: + zone = dns.zone.from_xfr(dns.query.xfr( + resolver, domain, port=cls.port)) + else: + zone = dns.zone.from_xfr(dns.query.xfr( + master_answer[0].address, domain, + port=cls.port)) + except dns.resolver.NoAnswer: + logging.error("nameserver for '%s' did not answer", domain) + except dns.exception.FormError: + logging.critical("domain '%s' does not allow xfr requests", domain) + sys.exit(1) + except dns.query.TransferError: + logging.critical("domain '%s' does not allow xfr requests", domain) + sys.exit(1) + for soa_record in zone.iterate_rdatas(rdtype=dns.rdatatype.SOA): + if not cls.transferns: + mname = soa_record[2].mname + if cls.domain not in mname: + cls.transferns = str(soa_record[2].mname) + "." + domain + else: + cls.transferns = str(soa_record[2].mname) + return soa_record[2].serial + + @classmethod + def mirror_zone(cls): + """ + Extract necessary information from Generator + """ + currentserial = int(cls.get_current_serial(cls.domain, cls.transferns)) + zoneserial = int(cls.get_zone_serial()) + if zoneserial == 0: + logging.info("zone does not exist yet") + cls.initial_zone_transfer() + try: + cls.zone = dns.zone.from_xfr(cls.zonegenerator, + check_origin=False) + except dns.zone.BadZone: + logging.critical("Malformed DNS Zone '%s'", cls.domain) + cls.soa = cls.get_zone_soa(cls.zone) + elif zoneserial < currentserial: + logging.info("zone is out of date") + cls.initial_zone_transfer(serial=zoneserial) + try: + cls.zone = dns.zone.from_xfr(cls.zonegenerator) + except dns.zone.BadZone: + logging.critical("Malformed DNS Zone '%s'", cls.domain) + cls.soa = cls.get_zone_soa(cls.zone) + elif zoneserial == currentserial: + logging.info("zone is up to date") + # should be unnecessary but AXFR SOA might not be equal to direct SOA + else: + # because it runs as a daemon, ignore this case but log it + logging.warning("SOA serial is bigger than zone serial?") + logging.warning("zone: %s, current: %s", zoneserial, currentserial) + + @classmethod + def add_records_to_gns(cls): + """ + Extracts records from zone and adds them to GNS + :raises AttributeError: When getting incomplete data + """ + logging.info("Starting to add records into GNS...") + + # Defining FIFO Queue + taskqueue = queue.Queue(maxsize=5) + + # Defining worker + def worker(): + while True: + # define recordline + recordline = list() + label = "" + domain = None + + labelrecords = taskqueue.get() + # break if taskqueue is empty + if labelrecords is None: + break + + # execute thing to run on item + label, listofrdatasets = labelrecords + subzones = label.split('.') + domain = cls.domain + + if len(subzones) > 1: + ttl = cls.get_zone_refresh_time() + label = subzones[0] + subdomains = ".".join(subzones[1:]) + subzone = "%s.%s" % (subdomains, domain) + fqdn = "%s.%s.%s" % (label, subdomains, domain) + if fqdn in cls.subzonedict.keys(): + label = "@" + domain = fqdn + elif subzone in cls.subzonedict.keys(): + domain = subzone + + for rdataset in listofrdatasets: + for record in rdataset: + rdtype = dns.rdatatype.to_text(record.rdtype) + if rdtype not in SUPPORTED_RECORD_TYPES: + continue + + try: + if rdataset.ttl <= cls.minimum: + ttl = cls.minimum + else: + ttl = rdataset.ttl + except AttributeError: + ttl = cls.minimum + + value = str(record) + + # ignore NS for itself here + if label == '@' and rdtype == 'NS': + logging.info("ignoring NS record for itself") + + # modify value to fit gns syntax + rdtype, value, label = \ + cls.transform_to_gns_format(record, + rdtype, + domain, + label) + # skip record if value is none + if value is None: + continue + + if isinstance(value, list): + for element in value: + # build recordline + recordline.append("-R") + recordline.append('%d %s %s %s' % + (int(ttl), + rdtype, + cls.flags, + element)) + else: + # build recordline + recordline.append("-R") + + # TODO possible regression here; maybe use a separate + # list to pass those arguments to prevent quoting + # issues in the future. + recordline.append('%d %s %s %s' % + (int(ttl), + rdtype, + cls.flags, + value)) + + # add recordline to gns and filter out empty lines + if len(recordline) > 1: + cls.add_recordline_to_gns(recordline, + domain, + label) + + taskqueue.task_done() + + # Check if there is zone has already been migrated + nsrecords = cls.zone.iterate_rdatas(dns.rdatatype.NS) + + gnspkey = list(filter(lambda record: str(record[2]).startswith('gns--pkey--'), nsrecords)) + if gnspkey: + label = str(gnspkey[0][0]) + ttl = gnspkey[0][1] + pkey = str(gnspkey[0][2]) + # TODO Check this check + if not cls.transferns in ['127.0.0.1', '::1', 'localhost']: + logging.warning("zone exists in GNS, adding it to local store") + cls.add_pkey_record_to_zone(pkey[11:], cls.domain, + label, ttl) + return + + # Unify all records under same label into datastructure + customrdataset = dict() + for remaining in cls.zone.iterate_rdatasets(): + # build lookup table for later GNS2DNS records + domain = "%s.%s" % (str(remaining[0]), cls.domain) + elementlist = [] + for element in remaining[1]: + if dns.rdatatype.to_text(element.rdtype) in ['A', 'AAAA']: + elementlist.append(str(element)) + cls.nscache[str(domain)] = elementlist + rdataset = remaining[1] + if customrdataset.get(str(remaining[0])) is None: + work = list() + work.append(rdataset) + customrdataset[str(remaining[0])] = work + else: + customrdataset[str(remaining[0])].append(rdataset) + + for label, value in customrdataset.items(): + if value is None: + continue + + subzones = label.split('.') + label = subzones[0] + subdomain = ".".join(subzones[1:]) + zonename = "%s.%s" % (subdomain, cls.domain) + + refresh = cls.get_zone_refresh_time() + if refresh <= cls.minimum: + ttl = cls.minimum + else: + ttl = refresh + + if len(subzones) > 1: + if cls.subzonedict.get(zonename): + continue + else: + cls.subzonedict[zonename] = (False, ttl) + + cls.create_zone_hierarchy() + + # Create one thread + thread = threading.Thread(target=worker) + thread.start() + + # add records + for label, value in customrdataset.items(): + if value is None: + continue + taskqueue.put((label, value)) + + # Block until all tasks are done + taskqueue.join() + + # Stop workers and threads + taskqueue.put(None) + thread.join(timeout=10) + if thread.is_alive(): + logging.critical("thread join timed out, still running") + + # Add soa record to GNS once completed (updates the previous one) + soa = cls.get_zone_soa(cls.zone) + cls.add_soa_record_to_gns(soa) + logging.info("All records have been added!") + + @staticmethod + def add_recordline_to_gns(recordline, zonename, label): + """ + Replaces records in zone or adds them if not + :param recordline: records to replace as list in form + ['-R', 'TTL TYPE FLAGS VALUE'] + :param zonename: zonename of zone to add records to + :param label: label under which to add the records + """ + logging.info("trying to add %d records with name %s", + len(recordline)/2, label) + + ret = sp.run([GNUNET_NAMESTORE_COMMAND, + '-z', zonename, + '-n', str(label), + ] + recordline) + + if ret.returncode != 0: + logging.warning("failed adding record with name %s", + ' '.join(ret.args)) + else: + logging.info("successfully added record with command %s", + ' '.join(ret.args)) + + @classmethod + def transform_to_gns_format(cls, record, rdtype, zonename, label): + """ + Transforms value of record to GNS compatible format + :param record: record to transform + :param rdtype: record value to transform + :param zonename: name of the zone to add to + :param label: label under which the record is stored + :returns: a tuple consisting of the new rdtype, the label and value + """ + value = str(record) + if label is None: + label = '@' + if rdtype == 'SOA': + zonetuple = str(value).split(' ') + authns, owner, serial, refresh, retry, expiry, irefresh = zonetuple + if authns[-1] == '.': + authns = authns[:-1] + if owner[-1] == '.': + owner = owner[:-1] + # hacky and might cause bugs + authns += cls.tld + owner += cls.tld + value = "rname=%s.%s mname=%s.%s %d,%d,%d,%d,%d" % ( + authns, zonename, owner, zonename, + int(serial), int(refresh), int(retry), + int(expiry), int(irefresh) + ) + elif rdtype in ['CNAME']: + if value[-1] == ".": + value = value[:-1] + else: + value = "%s.%s" % (value, zonename) + elif rdtype == 'NS': + nameserver = str(record) + if value[-1] == ".": + value = value[:-1] + else: + value = "%s.%s" % (value, zonename) + if zonename[-1] == ".": + zonename = zonename[:-1] + if nameserver[-1] == ".": + dnsresolver = nameserver[:-1] + dnsresolver = cls.nscache.get(dnsresolver, dnsresolver) + else: + dnsresolver = "%s.%s" % (nameserver, zonename) + dnsresolver = cls.nscache.get(dnsresolver, dnsresolver) + if isinstance(dnsresolver, list): + value = [] + for nsip in dnsresolver: + value.append("%s@%s" % (zonename, nsip)) + else: + value = '%s.%s@%s' % (str(label), zonename, dnsresolver) + + logging.info("transformed %s record to GNS2DNS format", rdtype) + rdtype = 'GNS2DNS' + elif rdtype == 'MX': + priority, mailserver = str(value).split(' ') + if mailserver[-1] == ".": + mailserver = mailserver[:-1] + mailserver = '%s.%s' % (mailserver, zonename) + value = '%s,%s' % (priority, mailserver) + logging.info("transformed %s record to GNS format", rdtype) + elif rdtype == 'SRV': + # this is the number for a SRV record + rdtype = 'BOX' + srv = 33 + + # tearing the record apart + try: + srvrecord = str(label).split('.') + proto = srvrecord[1] + except IndexError: + logging.warning("could not parse SRV label %s", label) + return (rdtype, None, None) + priority, weight, destport, target = value.split(' ') + + try: + protostring = proto.strip('_') + protonum = socket.getprotobyname(protostring) + except OSError: + logging.warning("invalid protocol: %s", protostring) + return (rdtype, None, None) + + if target[:-1] == ".": + value = '%s %s %s %s %s %s %s' % ( + destport, protonum, srv, priority, weight, destport, + "%s" % target + ) + else: + value = '%s %s %s %s %s %s %s' % ( + destport, protonum, srv, priority, weight, destport, + "%s.%s" % (target, zonename) + ) + + label = target + else: + logging.info("Did not transform record of type: %s", rdtype) + return (rdtype, value, label) + + @classmethod + def get_zone_serial(cls): + """ + Fetches the zones serial from GNS + :returns: serial of the SOA record in GNS + """ + try: + serial = sp.check_output([GNUNET_GNS_COMMAND, + '-t', 'SOA', + '-u', '@.%s' % cls.domain,]) + serial = serial.decode() + except sp.CalledProcessError: + serial = "" + soa_serial = 0 + soapattern = re.compile(r'.+\s(\d+),\d+,\d+,\d+,\d+', re.M) + if re.findall(soapattern, serial): + soa_serial = re.findall(soapattern, serial)[0] + else: + soa_serial = 0 + return soa_serial + + @classmethod + def get_zone_soa_expiry(cls): + """ + Extracts the current serial from the class SOA + :returns: refresh time of the current SOA record + """ + ttlpattern = re.compile(r'.+\s\d+\s(\d+)\s\d+\s\d+\s\d+', re.M) + return re.findall(ttlpattern, str(cls.soa[2])) + + @classmethod + def get_zone_refresh_time(cls): + """ + Extracts the current refresh time of the zone from GNS + :returns: refresh time of the current SOA record + """ + try: + serial = sp.check_output([GNUNET_GNS_COMMAND, + '-t', 'SOA', + '-u', '@.%s' % cls.domain]) + serial = serial.decode() + except sp.CalledProcessError: + serial = "" + refresh = 0 + soapattern = re.compile(r'.+\s\d+,(\d+),\d+,\d+,\d+', re.M) + if re.findall(soapattern, serial): + refresh = re.findall(soapattern, serial)[0] + else: + refresh = 0 + return refresh + + @classmethod + def get_zone_retry_time(cls): + """ + Extracts the current retry time of the zone from GNS + :returns: retry time of the current SOA record + """ + try: + serial = sp.check_output([GNUNET_GNS_COMMAND, + '-t', 'SOA', + '-u', '@.%s' % cls.domain]) + serial = serial.decode() + except sp.CalledProcessError: + serial = "" + retry = 300 + soapattern = re.compile(r'.+\s\d+,\d+,(\d+),\d+,\d+', re.M) + if re.findall(soapattern, serial): + retry = re.findall(soapattern, serial)[0] + else: + retry = 300 + return retry + + @staticmethod + def get_zone_soa(zone): + """ + Fetches soa record from zone a given zone + :param zone: A dnspython zone + :returns: SOA record of given zone + """ + soa = None + for soarecord in zone.iterate_rdatas(rdtype=dns.rdatatype.SOA): + if str(soarecord[0]) == '@': + soa = soarecord + return soa + + @classmethod + def add_soa_record_to_gns(cls, record): + """ + Adds a SOA record to GNS + :param record: The record to add + """ + label, ttl, rdata = record + zonetuple = str(rdata).split(' ') + authns, owner, serial, refresh, retry, expiry, irefresh = zonetuple + if authns[-1] == '.': + authns = authns[:-1] + else: + authns = "%s.%s" % (authns, cls.domain) + if owner[-1] == '.': + owner = owner[:-1] + else: + owner = "%s.%s" % (owner, cls.domain) + + value = "rname=%s mname=%s %s,%s,%s,%s,%s" % (authns, + owner, + serial, + refresh, + retry, + expiry, + irefresh) + recordval = '%s %s %s %s' % (ttl, "SOA", cls.flags, str(value)) + recordline = ['-R', recordval] + cls.add_recordline_to_gns(recordline, cls.domain, str(label)) + + @staticmethod + def create_zone_and_get_pkey(zonestring): + """ + Creates the zone in zonestring and returns pkey + :param zonestring: The label name of the zone + :returns: gnunet pkey of the zone + """ + try: + ret = sp.run([GNUNET_ZONE_CREATION_COMMAND, + '-C', zonestring], + stdout=sp.DEVNULL, + stderr=sp.DEVNULL) + logging.info("executed command: %s", " ".join(ret.args)) + except sp.CalledProcessError: + logging.info("Zone %s already exists!", zonestring) + + 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 + def add_pkey_record_to_zone(pkey, domain, label, ttl): + """ + Adds the pkey of the subzone to the parent zone + :param pkey: the public key of the child zone + :param domain: the name of the parent zone + :param label: the label under which to add the pkey + :param ttl: the time to live the record should have + """ + #lookup = sp.run(GNUNET_NAMESTORE_COMMAND, + # '-z', domain, + # '-n', label, + # '-t', 'PKEY') + #if not 'Got result:' in lookup.stdout: + debug = " ".join([GNUNET_NAMESTORE_COMMAND, + '-z', domain, + '-a', '-n', label, + '-t', 'PKEY', + '-V', pkey, + '-e', "%ss" % ttl]) + ret = sp.run([GNUNET_NAMESTORE_COMMAND, + '-z', domain, + '-a', '-n', label, + '-t', 'PKEY', + '-V', pkey, + '-e', "%ss" % ttl]) + logging.info("executed command: %s", debug) + if ret.returncode != 0: + logging.warning("failed to add PKEY record %s to %s", + label, domain) + #logging.warning("PKEY record %s already exists in %s", label, domain) + + @classmethod + def create_zone_hierarchy(cls): + """ + Creates the zone hierarchy in GNS for label + :param label: the split record to create zones for + """ + domain = cls.domain + + zonelist = cls.subzonedict.items() + sortedlist = sorted(zonelist, key=lambda s: len(str(s).split('.'))) + for zone, pkeyttltuple in sortedlist: + pkey, ttl = pkeyttltuple + if not pkey: + domain = ".".join(zone.split('.')[1::]) + label = zone.split('.')[0] + pkey = cls.create_zone_and_get_pkey(zone) + logging.info("adding zone %s with %s pkey into %s", zone, pkey, domain) + cls.add_pkey_record_to_zone(pkey, domain, label, pkeyttltuple[1]) + cls.subzonedict[zone] = (pkey, ttl) + +def main(): + """ + Initializes object and handles arguments + """ + # argument parsing from docstring definition + args = docopt.docopt(__doc__, version='Ascension 0.5.0') + + # argument parsing + debug = args['--debug'] + domain = args.get('<domain>', None) + transferns = args['<transferns>'] if args['<transferns>'] else None + port = args['<port>'] if args['<port>'] else 53 + flags = "p" if args.get('--public') else "n" + standalone = bool(args.get('--standalone')) + minimum = args['--minimum-ttl'] + + # Change logging severity to debug + if debug: + logging.basicConfig(level=logging.DEBUG) + + # Checks if GNUnet services are running + try: + sp.check_output([GNUNET_ARM_COMMAND, '-I'], timeout=1) + except sp.TimeoutExpired: + logging.critical('GNUnet Services are not running!') + sys.exit(1) + + # Initialize class instance + ascender = Ascender(domain, transferns, port, flags, minimum) + + # Event loop for actual daemon + while 1: + serial = ascender.get_zone_serial() + ascender.initial_zone_transfer(serial) + ascender.mirror_zone() + ascender.bootstrap_zone() + if ascender.zone is not None: + ascender.add_records_to_gns() + logging.info("Finished migration of the zone %s", ascender.domain) + else: + logging.info("Zone %s already up to date", ascender.domain) + refresh = int(ascender.get_zone_refresh_time()) + retry = int(ascender.get_zone_retry_time()) + if standalone: + return 0 + if refresh == 0: + logging.info("unable to refresh zone, retrying in %ds", retry) + time.sleep(retry) + else: + logging.info("refreshing zone in %ds", refresh) + print("refreshing zone in %ds" % refresh) + time.sleep(refresh) + +if __name__ == '__main__': + main() diff --git a/deb_dist/ascension-0.5.0/debian/ascension.1 b/deb_dist/ascension-0.5.0/debian/ascension.1 @@ -0,0 +1,45 @@ +.TH ASCENSION "1" "February 2019" "Ascension 0.5.0" "User Commands" +.SH NAME +Ascension \- continuous migration of DNS zones to GNS +.SH USAGE +.IP +ascension <domain> [\-d] [\-p] [\-s] +.IP +ascension <domain> <port> [\-d] [\-p] [\-s] +.IP +ascension <domain> \fB\-n\fR <transferns> [\-d] [\-p] [\-s] +.IP +ascension <domain> \fB\-n\fR <transferns> <port> [\-d] [\-p] [\-s] +.IP +ascension \fB\-p\fR | \fB\-\-public\fR +.IP +ascension \fB\-s\fR | \fB\-\-standalone\fR +.IP +ascension \fB\-h\fR | \fB\-\-help\fR +.IP +ascension \fB\-v\fR | \fB\-\-version\fR +.SH OPTIONS +.TP +<domain> +Domain to migrate +.TP +<port> +Port for zone transfer +.TP +<transferns> +DNS Server that does the zone transfer +.TP +\fB\-p\fR \fB\-\-public\fR +Make records public on the DHT +.TP +\fB\-s\fR \fB\-\-standalone\fR +Run ascension once +.TP +\fB\-d\fR \fB\-\-debug\fR +Enable debugging +.TP +\fB\-h\fR \fB\-\-help\fR +Show this screen. +.TP +\fB\-v\fR \fB\-\-version\fR +Show version. diff --git a/deb_dist/ascension-0.5.0/debian/changelog b/deb_dist/ascension-0.5.0/debian/changelog @@ -0,0 +1,5 @@ +ascension (0.5.0-1) unstable; urgency=low + + * source package automatically created by stdeb 0.8.5 + + -- rexxnor <rexxnor+gnunet@brief.li> Tue, 30 Apr 2019 19:01:03 +0000 diff --git a/deb_dist/ascension-0.5.0/debian/compat b/deb_dist/ascension-0.5.0/debian/compat @@ -0,0 +1 @@ +9 diff --git a/deb_dist/ascension-0.5.0/debian/control b/deb_dist/ascension-0.5.0/debian/control @@ -0,0 +1,33 @@ +Source: ascension +Maintainer: rexxnor <rexxnor+gnunet@brief.li> +Section: python +Priority: optional +Build-Depends: dh-python, python3-setuptools, python3-all, debhelper (>= 9) +Standards-Version: 3.9.6 +Homepage: https://gnunet.org/git/ascension.git/ + +Package: python3-ascension +Architecture: all +Depends: ${misc:Depends}, ${python3:Depends} +Description: Tool to migrate DNS Zones to the GNU Name System + # Ascension + . + Tool to easily migrate existing DNS Zones into the GNU Name System using + incremental zone transfers (AXFR/IXFR). + . + ## How to install + To install the ascension simply execute one of the following commands in the + freshly cloned directory: + . + ```bash + # System wide installation + sudo python3 setup.py install + . + # Local installation through virtualenv + python3 -m venv .venv + source .venv/bin/activate + python3 setup.py install + ``` + . + ## How to install (Developer) + diff --git a/deb_dist/ascension-0.5.0/debian/copyright b/deb_dist/ascension-0.5.0/debian/copyright @@ -0,0 +1,21 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: python3-ascension +Source: <https://git.gnunet.org/ascension.git/> + +Files: * +Copyright: 2019 GNUnet e.V. +License: AGPL-3.0 + Source: python3-ascension + Section: contrib + Priority: optional + Maintainer: rexxnor <rexxnor+gnunet@brief.li> + Build-Depends: debhelper (>= 9), python3-ascension, bind9 + Standards-Version: 3.9.8 + Homepage: https://git.gnunet.org/ascension.git/ + + Package: ascension-bind + Architecture: any + Depends: ${shlibs:Depends}, ${misc:Depends} + Description: Tool to migrate DNS Zones to the GNU Name System + Tool to easily migrate existing DNS Zones into the GNU Name System using + incremental zone transfers (AXFR/IXFR). diff --git a/deb_dist/ascension-0.5.0/debian/debhelper-build-stamp b/deb_dist/ascension-0.5.0/debian/debhelper-build-stamp @@ -0,0 +1 @@ +python3-ascension diff --git a/deb_dist/ascension-0.5.0/debian/files b/deb_dist/ascension-0.5.0/debian/files @@ -0,0 +1,2 @@ +ascension_0.5.0-1_amd64.buildinfo python optional +python3-ascension_0.5.0-1_all.deb python optional diff --git a/deb_dist/ascension-0.5.0/debian/python3-ascension.manpages b/deb_dist/ascension-0.5.0/debian/python3-ascension.manpages @@ -0,0 +1 @@ +debian/ascension.1 diff --git a/deb_dist/ascension-0.5.0/debian/python3-ascension.postinst b/deb_dist/ascension-0.5.0/debian/python3-ascension.postinst @@ -0,0 +1,41 @@ +#!/bin/sh +# postinst script for ascension-bind +# +# see: dh_installdeb(1) +# load debconf library +set -e + +adduser --system ascension +# ok if this fails as gnunet is not yet a dependency +addgroup --system gnunet +adduser ascension gnunet || true + +mkdir -p /etc/ascension.d/ + +# add systemd unit file + cat > "/etc/ascension.d/gnunet-ascension.service" << EOF +[Unit] +Description=Starting GNUnet peer for ascension +After=network.target + +[Service] +Type=oneshot +RemainAfterExit=yes +User=ascension +ExecStart=/usr/bin/gnunet-arm -s +ExecStop=/usr/bin/gnunet-arm -e +ExecReload=/usr/bin/gnunet-arm -r + +[Install] +WantedBy=multi-user.target +EOF + +# link the systemd unit file +ln -sf "/etc/ascension.d/gnunet-ascension.service" "/lib/systemd/system/gnunet-ascension.service" + +# start and enable service +systemctl start gnunet-ascension +systemctl enable gnunet-ascension + +exit 0 +#DEBHELPER# diff --git a/deb_dist/ascension-0.5.0/debian/python3-ascension.postinst.debhelper b/deb_dist/ascension-0.5.0/debian/python3-ascension.postinst.debhelper @@ -0,0 +1,7 @@ + +# Automatically added by dh_python3: +if which py3compile >/dev/null 2>&1; then + py3compile -p python3-ascension +fi + +# End automatically added section diff --git a/deb_dist/ascension-0.5.0/debian/python3-ascension.prerm.debhelper b/deb_dist/ascension-0.5.0/debian/python3-ascension.prerm.debhelper @@ -0,0 +1,10 @@ + +# Automatically added by dh_python3: +if which py3clean >/dev/null 2>&1; then + py3clean -p python3-ascension +else + dpkg -L python3-ascension | perl -ne 's,/([^/]*)\.py$,/__pycache__/\1.*, or next; unlink $_ or die $! foreach glob($_)' + find /usr/lib/python3/dist-packages/ -type d -name __pycache__ -empty -print0 | xargs --null --no-run-if-empty rmdir +fi + +# End automatically added section diff --git a/deb_dist/ascension-0.5.0/debian/python3-ascension.substvars b/deb_dist/ascension-0.5.0/debian/python3-ascension.substvars @@ -0,0 +1,3 @@ +python3:Depends=python3-coverage, python3-dnspython, python3-docopt, python3-mock, python3-pbr, python3-six, python3:any, python3:any (>= 3.3.2-2~) +misc:Depends= +misc:Pre-Depends= diff --git a/deb_dist/ascension-0.5.0/debian/python3-ascension/DEBIAN/control b/deb_dist/ascension-0.5.0/debian/python3-ascension/DEBIAN/control @@ -0,0 +1,31 @@ +Package: python3-ascension +Source: ascension +Version: 0.5.0-1 +Architecture: all +Maintainer: rexxnor <rexxnor+gnunet@brief.li> +Installed-Size: 61 +Depends: python3-coverage, python3-dnspython, python3-docopt, python3-mock, python3-pbr, python3-six, python3:any (>= 3.3.2-2~) +Section: python +Priority: optional +Homepage: https://gnunet.org/git/ascension.git/ +Description: Tool to migrate DNS Zones to the GNU Name System + # Ascension + . + Tool to easily migrate existing DNS Zones into the GNU Name System using + incremental zone transfers (AXFR/IXFR). + . + ## How to install + To install the ascension simply execute one of the following commands in the + freshly cloned directory: + . + ```bash + # System wide installation + sudo python3 setup.py install + . + # Local installation through virtualenv + python3 -m venv .venv + source .venv/bin/activate + python3 setup.py install + ``` + . + ## How to install (Developer) diff --git a/deb_dist/ascension-0.5.0/debian/python3-ascension/DEBIAN/md5sums b/deb_dist/ascension-0.5.0/debian/python3-ascension/DEBIAN/md5sums @@ -0,0 +1,12 @@ +a0f759101bdbf91192e01e4aa7fc735a usr/bin/ascension +bc657ea500b7eb1aaaed030b6825fa0f usr/lib/python3/dist-packages/ascension-0.5.0.egg-info/PKG-INFO +68b329da9893e34099c7d8ad5cb9c940 usr/lib/python3/dist-packages/ascension-0.5.0.egg-info/dependency_links.txt +9cda1022e5fc72a3762b4bc09ee0ddb5 usr/lib/python3/dist-packages/ascension-0.5.0.egg-info/entry_points.txt +d41d8cd98f00b204e9800998ecf8427e usr/lib/python3/dist-packages/ascension-0.5.0.egg-info/requires.txt +e616e4373e7b199db038fd8e938a3188 usr/lib/python3/dist-packages/ascension-0.5.0.egg-info/top_level.txt +d41d8cd98f00b204e9800998ecf8427e usr/lib/python3/dist-packages/ascension/__init__.py +b8e868d3010eb44c1dd5d13fb4a17013 usr/lib/python3/dist-packages/ascension/ascension.py +46ed4cd14add4c87e480fd2f30f72fbd usr/man/man1/ascension.1 +7190029e7e99c1b73c2018382db26093 usr/share/doc/python3-ascension/changelog.Debian.gz +42cbfd228642e598041a4f8583b17259 usr/share/doc/python3-ascension/copyright +5139d8621867d59e7b2ce8dcb06d974d usr/share/man/man1/ascension.1.gz diff --git a/deb_dist/ascension-0.5.0/debian/python3-ascension/DEBIAN/postinst b/deb_dist/ascension-0.5.0/debian/python3-ascension/DEBIAN/postinst @@ -0,0 +1,3 @@ +adduser --system ascension +# ok if this fails as gnunet is not yet a dependency +adduser ascension gnunet || true diff --git a/deb_dist/ascension-0.5.0/debian/python3-ascension/DEBIAN/prerm b/deb_dist/ascension-0.5.0/debian/python3-ascension/DEBIAN/prerm @@ -0,0 +1,12 @@ +#!/bin/sh +set -e + +# Automatically added by dh_python3: +if which py3clean >/dev/null 2>&1; then + py3clean -p python3-ascension +else + dpkg -L python3-ascension | perl -ne 's,/([^/]*)\.py$,/__pycache__/\1.*, or next; unlink $_ or die $! foreach glob($_)' + find /usr/lib/python3/dist-packages/ -type d -name __pycache__ -empty -print0 | xargs --null --no-run-if-empty rmdir +fi + +# End automatically added section diff --git a/deb_dist/ascension-0.5.0/debian/python3-ascension/usr/bin/ascension b/deb_dist/ascension-0.5.0/debian/python3-ascension/usr/bin/ascension @@ -0,0 +1,12 @@ +#!/usr/bin/python3 +# EASY-INSTALL-ENTRY-SCRIPT: 'ascension==0.5.0','console_scripts','ascension' +__requires__ = 'ascension==0.5.0' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('ascension==0.5.0', 'console_scripts', 'ascension')() + ) diff --git a/deb_dist/ascension-0.5.0/debian/python3-ascension/usr/man/man1/ascension.1 b/deb_dist/ascension-0.5.0/debian/python3-ascension/usr/man/man1/ascension.1 @@ -0,0 +1,103 @@ +.\" This file is part of Ascension. +.\" Copyright (C) 2018,2019 GNUnet e.V. +.\" +.\" Permission is granted to copy, distribute and/or modify this document +.\" under the terms of the GNU Free Documentation License, Version 1.3 or +.\" any later version published by the Free Software Foundation; with no +.\" Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A +.\" copy of the license is included in the file +.\" ``FDL-1.3''. +.\" +.\" A copy of the license is also available from the Free Software +.\" Foundation Web site at http://www.gnu.org/licenses/fdl.html. +.\" +.\" Alternately, this document is also available under the General +.\" Public License, version 3 or later, as published by the Free Software +.\" Foundation. A copy of the license is included in the file +.\" ``GPL3''. +.\" +.\" A copy of the license is also available from the Free Software +.\" Foundation Web site at http://www.gnu.org/licenses/gpl.html. +.\" +.\" SPDX-License-Identifier: GPL3.0-or-later OR FDL1.3-or-later +.\" +.Dd March 7, 2019 +.Dt ASCENSION 1 +.Os +.Sh NAME +.Nm ascension +.Nd migrate existing DNS zones into the GNU Name System +.Sh SYNOPSIS +.Nm +.Op Ar domain Fl d Fl p +.Op Ar domain port Fl d Fl p +.Op Ar domain Fl n Ar transferns Fl d Fl p +.Op Ar domain Fl n Ar transferns Ar port Fl d Fl p +.Op Fl d | \-debug +.Op Fl h | \-help +.Op Fl p | \-public +.Op Fl v | \-version +.Sh DESCRIPTION +.Nm +is a tool to migrate existing DNS Zones into the GNU Name System (GNS) using incremental zone transfers (AXFR/IXFR). +To achieve this it uses +.Xr gnunet-identity 1 , +.Xr gnunet-namestore 1 , +.Xr gnunet-gns 1 . +As +.Nm +relies on these 3 GNUnet services, +.Xr gnunet-arm 1 +must be installed and running. +.Bl -tag -width Ds +.It Ar domain Fl d Fl p +Migrate the DOMAIN passed as domain. +The debug and public options are optional. +.It Ar domain port Fl d Fl p +Migrate the DOMAIN domain, using port for zone transfer. +The debug and public options are optional. +.It Ar domain Fl n Ar transferns Fl d Fl p +Migrate the DOMAIN domain from the DNS server transferns. +The debug and public options are optional. +.It Ar domain Fl n Ar transferns Ar port Fl d Fl p +Migrate the DOMAIN domain from the DNS server transferns using port for the zone transfer. +The debug and public options are optional. +.It Fl d | \-debug +Enable debugging +.It Fl h | \-help +Print short help on options +.It Fl p | \-public +Make records public on the DHT +.It Fl v | \-version +Print ascension version number +.El +.\" .Sh FILES +.Sh EXAMPLES +To transfer the sy TLD from ns1.tld.sy: +.Pp +.Dl $ ascension sy -n ns1.tld.sy. +.Pp +To transfer the nu TLD from zonedata.iis.se with debug options enabled: +.Pp +.Dl $ ascension nu -n zonedata.iis.se. -d +.Sh SEE ALSO +.Xr gnunet-arm 1 , +.Xr gnunet-gns 1 , +.Xr gnunet-identity 1 , +.Xr gnunet-namestore 1 +.Sh HISTORY +The +.Nm +tool was designed and written in 2018 by +.An rexxnor Aq Mt rexxnor+gnunet@brief.li . +.Sh AUTHORS +This man page was written by +.An ng0 Aq Mt ng0@gnunet.org , +it first appeared in +.Nm +0.5.1. +.Sh BUGS +Report bugs by using +.Lk https://bugs.gnunet.org +or by sending electronic mail to +.Aq Mt bug-gnunet@gnu.org . diff --git a/deb_dist/ascension-0.5.0/debian/python3-ascension/usr/share/doc/python3-ascension/changelog.Debian.gz b/deb_dist/ascension-0.5.0/debian/python3-ascension/usr/share/doc/python3-ascension/changelog.Debian.gz Binary files differ. diff --git a/deb_dist/ascension-0.5.0/debian/python3-ascension/usr/share/doc/python3-ascension/copyright b/deb_dist/ascension-0.5.0/debian/python3-ascension/usr/share/doc/python3-ascension/copyright @@ -0,0 +1,21 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: python3-ascension +Source: <https://git.gnunet.org/ascension.git/> + +Files: * +Copyright: 2019 GNUnet e.V. +License: AGPL-3.0 + Source: python3-ascension + Section: contrib + Priority: optional + Maintainer: rexxnor <rexxnor+gnunet@brief.li> + Build-Depends: debhelper (>= 9), python3-ascension, bind9 + Standards-Version: 3.9.8 + Homepage: https://git.gnunet.org/ascension.git/ + + Package: ascension-bind + Architecture: any + Depends: ${shlibs:Depends}, ${misc:Depends} + Description: Tool to migrate DNS Zones to the GNU Name System + Tool to easily migrate existing DNS Zones into the GNU Name System using + incremental zone transfers (AXFR/IXFR). diff --git a/deb_dist/ascension-0.5.0/debian/python3-ascension/usr/share/man/man1/ascension.1.gz b/deb_dist/ascension-0.5.0/debian/python3-ascension/usr/share/man/man1/ascension.1.gz Binary files differ. diff --git a/deb_dist/ascension-0.5.0/debian/rules b/deb_dist/ascension-0.5.0/debian/rules @@ -0,0 +1,8 @@ +#!/usr/bin/make -f + +# This file was automatically generated by stdeb 0.8.5 at +# Tue, 30 Apr 2019 19:01:03 +0000 +export PYBUILD_NAME=ascension +%: + dh $@ --with python3 --buildsystem=pybuild + diff --git a/deb_dist/ascension-0.5.0/debian/source/format b/deb_dist/ascension-0.5.0/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/deb_dist/ascension-0.5.0/debian/watch b/deb_dist/ascension-0.5.0/debian/watch @@ -0,0 +1,4 @@ +# please also check http://pypi.debian.net/ascension/watch +version=3 +opts=uversionmangle=s/(rc|a|b|c)/~$1/ \ +http://pypi.debian.net/ascension/ascension-(.+)\.(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz))) +\ No newline at end of file diff --git a/deb_dist/ascension-0.5.0/setup.cfg b/deb_dist/ascension-0.5.0/setup.cfg @@ -0,0 +1,4 @@ +[egg_info] +tag_build = +tag_date = 0 + diff --git a/deb_dist/ascension-0.5.0/setup.py b/deb_dist/ascension-0.5.0/setup.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +""" +This file is part of Ascension. +Copyright (C) 2019 GNUnet e.V. + +Ascension is free software: you can redistribute it and/or modify it +under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, +or (at your option) any later version. + +Ascension is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +SPDX-License-Identifier: AGPL3.0-or-later + +Author rexxnor +""" + +import setuptools + +with open("README", "r") as fh: + long_description = fh.read() + +setuptools.setup( + name="ascension", + version="0.5.0", + author="rexxnor", + author_email="rexxnor+gnunet@brief.li", + description="Tool to migrate DNS Zones to the GNU Name System", + long_description=long_description, + url="https://gnunet.org/git/ascension.git/", + packages=['ascension'], + data_files=[('man/man1', ['ascension.1'])], + classifiers=[ + "Programming Language :: Python :: 3", + ], + entry_points={ + 'console_scripts': [ + 'ascension=ascension.ascension:main', + ], + }, + install_requires=[ + 'coverage', + 'dnspython', + 'docopt', + 'mock', + 'pbr', + 'six', + ], +) diff --git a/deb_dist/ascension-0.6.1/.pc/.quilt_patches b/deb_dist/ascension-0.6.1/.pc/.quilt_patches @@ -0,0 +1 @@ +debian/patches diff --git a/deb_dist/ascension-0.6.1/.pc/.quilt_series b/deb_dist/ascension-0.6.1/.pc/.quilt_series @@ -0,0 +1 @@ +series diff --git a/deb_dist/ascension-0.6.1/.pc/.version b/deb_dist/ascension-0.6.1/.pc/.version @@ -0,0 +1 @@ +2 diff --git a/deb_dist/ascension-0.6.1/.pc/applied-patches b/deb_dist/ascension-0.6.1/.pc/applied-patches diff --git a/deb_dist/ascension-0.6.1/PKG-INFO b/deb_dist/ascension-0.6.1/PKG-INFO @@ -0,0 +1,81 @@ +Metadata-Version: 1.1 +Name: ascension +Version: 0.6.1 +Summary: Tool to migrate DNS Zones to the GNU Name System +Home-page: https://gnunet.org/git/ascension.git/ +Author: rexxnor +Author-email: rexxnor+gnunet@brief.li +License: UNKNOWN +Description: # Ascension + + Tool to easily migrate existing DNS Zones into the GNU Name System using + incremental zone transfers (AXFR/IXFR). + + ## How to install + To install the ascension simply execute one of the following commands in the + freshly cloned directory: + + ```bash + # System wide installation + sudo python3 setup.py install + + # Local installation through virtualenv + python3 -m venv .venv + source .venv/bin/activate + python3 setup.py install + ``` + + ## How to install (Developer) + A developer installation is very handy when you are making changes to the source + code as this way you don't need to re-run the installation procedure every time + you make a change. + + ```bash + # installation through virtualenv + python3 -m venv .venv + source .venv/bin/activate + python3 setup.py develop + ``` + + ## How to use + If you have installed it, simply execute ascension with one of several options. + You can also just run the file ascension.py itself directly. + + Taken from the docstring of the ascension.py file: + ``` + Ascension + + Usage: + ascension <domain> [-d] [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run] + ascension <domain> <port> [-d] [-p] [-s] [--minimum-ttl=<ttl>] + ascension <domain> -n <transferns> [-d] [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run] + ascension <domain> -n <transferns> <port> [-d] [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run] + ascension -p | --public + ascension -s | --debug + ascension -s | --standalone + ascension -h | --help + ascension -v | --version + + Options: + <domain> Domain to migrate + <port> Port for zone transfer + <transferns> DNS Server that does the zone transfer + --minimum-ttl=<ttl> Minimum TTL for records to migrate [default: 3600] + --dry-run Only try if a zone transfer is allowed + -p --public Make records public on the DHT + -s --standalone Run ascension once + -d --debug Enable debugging + -h --help Show this screen. + -v --version Show version. + ``` + + Example use: + ``` + # Transfers the sy TLD from ns1.tld.sy. + ascension sy -n ns1.tld.sy. + # Transfers the nu TLD from zonedata.iis.se with debug options enabled + ascension nu -n zonedata.iis.se. -d + ``` + +Platform: UNKNOWN +Classifier: Programming Language :: Python :: 3 diff --git a/deb_dist/ascension-0.6.1/README b/deb_dist/ascension-0.6.1/README @@ -0,0 +1,70 @@ +# Ascension + +Tool to easily migrate existing DNS Zones into the GNU Name System using +incremental zone transfers (AXFR/IXFR). + +## How to install +To install the ascension simply execute one of the following commands in the +freshly cloned directory: + +```bash +# System wide installation +sudo python3 setup.py install + +# Local installation through virtualenv +python3 -m venv .venv +source .venv/bin/activate +python3 setup.py install +``` + +## How to install (Developer) +A developer installation is very handy when you are making changes to the source +code as this way you don't need to re-run the installation procedure every time +you make a change. + +```bash +# installation through virtualenv +python3 -m venv .venv +source .venv/bin/activate +python3 setup.py develop +``` + +## How to use +If you have installed it, simply execute ascension with one of several options. +You can also just run the file ascension.py itself directly. + +Taken from the docstring of the ascension.py file: +``` +Ascension + +Usage: + ascension <domain> [-d] [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run] + ascension <domain> <port> [-d] [-p] [-s] [--minimum-ttl=<ttl>] + ascension <domain> -n <transferns> [-d] [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run] + ascension <domain> -n <transferns> <port> [-d] [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run] + ascension -p | --public + ascension -s | --debug + ascension -s | --standalone + ascension -h | --help + ascension -v | --version + +Options: + <domain> Domain to migrate + <port> Port for zone transfer + <transferns> DNS Server that does the zone transfer + --minimum-ttl=<ttl> Minimum TTL for records to migrate [default: 3600] + --dry-run Only try if a zone transfer is allowed + -p --public Make records public on the DHT + -s --standalone Run ascension once + -d --debug Enable debugging + -h --help Show this screen. + -v --version Show version. +``` + +Example use: +``` +# Transfers the sy TLD from ns1.tld.sy. +ascension sy -n ns1.tld.sy. +# Transfers the nu TLD from zonedata.iis.se with debug options enabled +ascension nu -n zonedata.iis.se. -d +``` diff --git a/deb_dist/ascension-0.6.1/ascension.1 b/deb_dist/ascension-0.6.1/ascension.1 @@ -0,0 +1,108 @@ +.\" This file is part of Ascension. +.\" Copyright (C) 2018,2019 GNUnet e.V. +.\" +.\" Permission is granted to copy, distribute and/or modify this document +.\" under the terms of the GNU Free Documentation License, Version 1.3 or +.\" any later version published by the Free Software Foundation; with no +.\" Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A +.\" copy of the license is included in the file +.\" ``FDL-1.3''. +.\" +.\" A copy of the license is also available from the Free Software +.\" Foundation Web site at http://www.gnu.org/licenses/fdl.html. +.\" +.\" Alternately, this document is also available under the General +.\" Public License, version 3 or later, as published by the Free Software +.\" Foundation. A copy of the license is included in the file +.\" ``GPL3''. +.\" +.\" A copy of the license is also available from the Free Software +.\" Foundation Web site at http://www.gnu.org/licenses/gpl.html. +.\" +.\" SPDX-License-Identifier: GPL3.0-or-later OR FDL1.3-or-later +.\" +.Dd May 9, 2019 +.Dt ASCENSION 1 +.Os +.Sh NAME +.Nm ascension +.Nd migrate existing DNS zones into the GNU Name System +.Sh SYNOPSIS +.Nm +.Op Ar domain Fl d Fl p Fl s \- minimum-ttl=<ttl> \- dry-run +.Op Ar domain port Fl d Fl p Fl s \- minimum-ttl=<ttl> \- dry-run +.Op Ar domain Fl n Ar transferns Fl d Fl p Fl s Fl \- minimum-ttl=<ttl> \- dry-run +.Op Ar domain Fl n Ar transferns Ar port Fl d Fl p Fl s \- minimum-ttl=<ttl> \- dry-run +.Op Fl d | \-debug +.Op Fl h | \-help +.Op Fl p | \-public +.Op Fl v | \-version +.Op Fl s | \-standalone +.Sh DESCRIPTION +.Nm +is a tool to migrate existing DNS Zones into the GNU Name System (GNS) using incremental zone transfers (AXFR/IXFR). +To achieve this it uses +.Xr gnunet-identity 1 , +.Xr gnunet-namestore 1 , +.Xr gnunet-gns 1 . +As +.Nm +relies on these 3 GNUnet services, +.Xr gnunet-arm 1 +must be installed and running. +.Bl -tag -width Ds +.It Ar domain Fl d Fl p Fl s Fl minimum-ttl=<ttl> +Migrate the DOMAIN passed as domain. +The debug, public and standalone options are optional. +.It Ar domain port Fl d Fl p Fl s Fl minimum-ttl=<ttl> +Migrate the DOMAIN domain, using port for zone transfer. +The debug, public and standalone options are optional. +.It Ar domain Fl n Ar transferns Fl d Fl p Fl s Fl minimum-ttl=<ttl> +Migrate the DOMAIN domain from the DNS server transferns. +The debug, public and standalone options are optional. +.It Ar domain Fl n Ar transferns Ar port Fl d Fl p Fl s Fl minimum-ttl=<ttl> +Migrate the DOMAIN domain from the DNS server transferns using port for the zone transfer. +The debug, public and standalone options are optional. +.It Fl s | \-standalone +Run Ascension once +.It Fl d | \-debug +Enable debugging +.It Fl h | \-help +Print short help on options +.It Fl p | \-public +Make records public on the DHT +.It Fl v | \-version +Print ascension version number +.El +.\" .Sh FILES +.Sh EXAMPLES +To transfer the sy TLD from ns1.tld.sy: +.Pp +.Dl $ ascension sy -n ns1.tld.sy. +.Pp +To transfer the nu TLD from zonedata.iis.se with debug options enabled: +.Pp +.Dl $ ascension nu -n zonedata.iis.se. -d +.Sh SEE ALSO +.Xr gnunet-arm 1 , +.Xr gnunet-gns 1 , +.Xr gnunet-identity 1 , +.Xr gnunet-namestore 1 +.Sh HISTORY +The +.Nm +tool was designed and written in 2018 by +.An rexxnor Aq Mt rexxnor+gnunet@brief.li . +.Sh AUTHORS +This man page was written by +.An ng0 Aq Mt ng0@gnunet.org +and updated by +.An rexxnor Aq Mt rexxnor+gnunet@brief.li +it first appeared in +.Nm +0.5.1. +.Sh BUGS +Report bugs by using +.Lk https://bugs.gnunet.org +or by sending electronic mail to +.Aq Mt bug-gnunet@gnu.org . diff --git a/deb_dist/ascension-0.6.1/ascension/__init__.py b/deb_dist/ascension-0.6.1/ascension/__init__.py diff --git a/deb_dist/ascension-0.6.1/ascension/ascension.py b/deb_dist/ascension-0.6.1/ascension/ascension.py @@ -0,0 +1,789 @@ +#!/usr/bin/env python3 +# This file is part of Ascension. +# Copyright (C) 2019 GNUnet e.V. +# +# Ascension is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# Ascension is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# SPDX-License-Identifier: AGPL3.0-or-later +# +# Author rexxnor +""" +Usage: + ascension <domain> [-d] [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run] + ascension <domain> <port> [-d] [-p] [-s] [--minimum-ttl=<ttl>] + ascension <domain> -n <transferns> [-d] [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run] + ascension <domain> -n <transferns> <port> [-d] [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run] + ascension -p | --public + ascension -s | --debug + ascension -s | --standalone + ascension -h | --help + ascension -v | --version + +Options: + <domain> Domain to migrate + <port> Port for zone transfer + <transferns> DNS Server that does the zone transfer + --minimum-ttl=<ttl> Minimum TTL for records to migrate [default: 3600] + --dry-run Only try if a zone transfer is allowed + -p --public Make records public on the DHT + -s --standalone Run ascension once + -d --debug Enable debugging + -h --help Show this screen. + -v --version Show version. +""" + +# imports +import logging +import queue +import re +import socket +import sys +import time +import subprocess as sp +import threading +import dns.query +import dns.resolver +import dns.zone +import docopt + +# GLOBALS +GNUNET_ZONE_CREATION_COMMAND = 'gnunet-identity' +GNUNET_NAMESTORE_COMMAND = 'gnunet-namestore' +GNUNET_GNS_COMMAND = 'gnunet-gns' +GNUNET_ARM_COMMAND = 'gnunet-arm' +# This is the list of record types Ascension (and GNS) currently +# explicitly supports. Record types we encounter that are not +# in this list and not in the OBSOLETE_RECORD_TYPES list will +# create a warning (information loss during migration). +SUPPORTED_RECORD_TYPES = [ + "A", "AAAA", "NS", "MX", "SRV", "TXT", "CNAME", +] +# Record types that exist in DNS but that won't ever exist in GNS +# as they are not needed anymore (so we should not create a warning +# if we drop one of these). +OBSOLETE_RECORD_TYPES = [ + "PTR", + "SIG", "KEY", + "RRSIG", "NSEC", "DNSKEY", "NSEC3", "NSEC3PARAM", "CDNSKEY", + "TKEY", "TSIG", + "TA", "DLV", +] + +class Ascender(): + """ + Class that provides migration for any given domain + """ + def __init__(self, + domain: str, + transferns: str, + port: str, + flags: str, + minimum: str) -> None: + self.domain = domain + if domain[-1] == '.': + self.domain = self.domain[:-1] + self.port = int(port) + self.transferns = transferns + self.soa = None + self.tld = self.domain.split(".")[::-1][0] + self.zone = None + self.zonegenerator = None + self.flags = flags + self.minimum = int(minimum) + self.subzonedict = dict() + + def bootstrap_zone(self) -> None: + """ + Creates the zone in gnunet + """ + try: + ret = sp.run([GNUNET_ZONE_CREATION_COMMAND, + '-C', self.domain]) + logging.info("executed command: %s", " ".join(ret.args)) + except sp.CalledProcessError: + logging.info("Zone %s already exists!", self.domain) + + def get_dns_zone_serial(self, + domain: str, + resolver=None) -> int: + """ + Gets the current serial for a given zone + :param domain: Domain to query for in DNS + :param resolver: Nameserver to query in DNS, defaults to None + :returns: Serial of the zones SOA record + """ + # Makes domains better resolvable + domain = domain + "." + # SOA is different if taken directly from SOA record + # compared to AXFR/IXFR - changed to respect this + try: + soa_answer = dns.resolver.query(domain, 'SOA') + master_answer = dns.resolver.query(soa_answer[0].mname, 'A') + except dns.resolver.NoAnswer: + logging.warning("The domain '%s' is not publicly resolvable.", + domain) + except dns.resolver.NXDOMAIN: + logging.warning("The domain '%s' is not publicly resolvable.", + domain) + except Exception: + logging.warning("The domain '%s' is not publicly resolvable.", + domain) + + try: + if resolver: + zone = dns.zone.from_xfr(dns.query.xfr( + resolver, domain, port=self.port)) + else: + zone = dns.zone.from_xfr(dns.query.xfr( + master_answer[0].address, domain, + port=self.port)) + except dns.resolver.NoAnswer: + logging.critical("Nameserver for '%s' did not answer.", domain) + return None + except dns.exception.FormError: + logging.critical("Domain '%s' does not allow xfr requests.", + domain) + return None + except dns.query.TransferError: + logging.critical("Domain '%s' does not allow xfr requests.", + domain) + return None + except Exception: + logging.error("Unexpected error while transfering domain '%s'", + domain) + return None + + for soa_record in zone.iterate_rdatas(rdtype=dns.rdatatype.SOA): + if not self.transferns: + mname = soa_record[2].mname + if self.domain not in mname: + self.transferns = str(soa_record[2].mname) + "." + domain + else: + self.transferns = str(soa_record[2].mname) + return int(soa_record[2].serial) + + def add_records_to_gns(self) -> None: + """ + Extracts records from zone and adds them to GNS + :raises AttributeError: When getting incomplete data + """ + logging.info("Starting to add records into GNS...") + + # Defining FIFO Queue + taskqueue = queue.Queue(maxsize=5) + + # Defining worker + def worker(): + while True: + # define recordline + recordline = list() + label = "" + domain = None + + labelrecords = taskqueue.get() + # break if taskqueue is empty + if labelrecords is None: + break + + # execute thing to run on item + label, listofrdatasets = labelrecords + subzones = label.split('.') + domain = self.domain + + if len(subzones) > 1: + label = subzones[0] + subdomains = ".".join(subzones[1:]) + subzone = "%s.%s" % (subdomains, domain) + fqdn = "%s.%s.%s" % (label, subdomains, domain) + if fqdn in self.subzonedict.keys(): + label = "@" + domain = fqdn + elif subzone in self.subzonedict.keys(): + domain = subzone + + for rdataset in listofrdatasets: + for record in rdataset: + rdtype = dns.rdatatype.to_text(record.rdtype) + if rdtype not in SUPPORTED_RECORD_TYPES: + continue + + try: + if rdataset.ttl <= self.minimum: + ttl = self.minimum + else: + ttl = rdataset.ttl + except AttributeError: + ttl = self.minimum + + value = str(record) + + # ignore NS for itself here + if label == '@' and rdtype == 'NS': + logging.info("ignoring NS record for itself") + + # modify value to fit gns syntax + rdtype, value, label = \ + self.transform_to_gns_format(record, + rdtype, + domain, + label) + # skip record if value is none + if value is None: + continue + + if isinstance(value, list): + for element in value: + # build recordline + recordline.append("-R") + recordline.append('%d %s %s %s' % + (int(ttl), + rdtype, + self.flags, + element)) + else: + # build recordline + recordline.append("-R") + + # TODO possible regression here; maybe use a separate + # list to pass those arguments to prevent quoting + # issues in the future. + recordline.append('%d %s %s %s' % + (int(ttl), + rdtype, + self.flags, + value)) + + # add recordline to gns and filter out empty lines + if len(recordline) > 1: + self.add_recordline_to_gns(recordline, + domain, + label) + + taskqueue.task_done() + # End of worker + + + # Check if a delegated zone is available in GNS as per NS record + 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. + # alice NS IN ns.alice + # bob NS IN ns.bob + # carol NS IN ns.alice + # => carol GNS2DNS GNS ns.alice@$IP + # dave.foo NS IN gns--pkey--$KEY.bob + # => dave.foo PKEY GNS $KEY + # 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)) + illegalchars = ["I", "L", "O", "U", "i", "l", "o", "u"] + for nsrecord in nsrecords: + name = str(nsrecord[0]) + values = nsrecord[1] + ttl = values.ttl + + gnspkeys = list(filter(lambda record: + str(record).startswith('gns--pkey--'), + values)) + + 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 = str(gnspkeys[0]) + # FIXME: drop all NS records under this name later! + # => new map, if entry present during NS processing, skip! + if not any(illegal in gnspkey for illegal in illegalchars): + self.add_pkey_record_to_zone(gnspkey[11:], + self.domain, + name, + ttl) + + # 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: + work = list() + work.append(rdset) + customrdataset[name] = work + else: + customrdataset[name].append(rdset) + + for label, value in customrdataset.items(): + if value is None: + continue + + subzones = label.split('.') + label = subzones[0] + subdomain = ".".join(subzones[1:]) + zonename = "%s.%s" % (subdomain, self.domain) + + try: + if value.ttl <= self.minimum: + ttl = self.minimum + else: + ttl = value.ttl + except AttributeError: + ttl = self.minimum + + if len(subzones) > 1: + if self.subzonedict.get(zonename): + continue + else: + self.subzonedict[zonename] = (False, ttl) + + self.create_zone_hierarchy() + + # Create one thread + thread = threading.Thread(target=worker) + thread.start() + + # add records + for label, value in customrdataset.items(): + if value is None: + continue + taskqueue.put((label, value)) + + # Block until all tasks are done + taskqueue.join() + + # Stop workers and threads + taskqueue.put(None) + thread.join(timeout=10) + if thread.is_alive(): + logging.critical("thread join timed out, still running") + + # Add soa record to GNS once completed (updates the previous one) + self.add_soa_record_to_gns(self.soa) + + logging.info("All records have been added!") + + @staticmethod + def add_recordline_to_gns(recordline: list, + zonename: str, + label: str) -> None: + """ + Replaces records in zone or adds them if not + :param recordline: records to replace as list in form + ['-R', 'TTL TYPE FLAGS VALUE'] + :param zonename: zonename of zone to add records to + :param label: label under which to add the records + """ + logging.info("trying to add %d records with name %s", + len(recordline)/2, label) + + ret = sp.run([GNUNET_NAMESTORE_COMMAND, + '-z', zonename, + '-n', str(label), + ] + recordline) + + if ret.returncode != 0: + logging.warning("failed adding record with name %s", + ' '.join(ret.args)) + else: + logging.info("successfully added record with command %s", + ' '.join(ret.args)) + + def resolve_glue(self, + authorityname: str) -> list: + """ + 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]: + 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, + zonename: str, + label: str) -> tuple: + """ + Transforms value of record to GNS compatible format + :param record: record to transform + :param rdtype: record value to transform + :param zonename: name of the zone to add to + :param label: label under which the record is stored + :returns: a tuple consisting of the new rdtype, the label and value + """ + value = str(record) + if label is None: + label = '@' + if rdtype == 'SOA': + zonetuple = str(value).split(' ') + authns, owner, serial, refresh, retry, expiry, irefresh = zonetuple + if authns[-1] == '.': + authns = authns[:-1] + if owner[-1] == '.': + owner = owner[:-1] + # hacky and might cause bugs + authns += self.tld + owner += self.tld + value = "rname=%s.%s mname=%s.%s %d,%d,%d,%d,%d" % ( + authns, zonename, owner, zonename, + int(serial), int(refresh), int(retry), + int(expiry), int(irefresh) + ) + elif rdtype in ['CNAME']: + if value[-1] == ".": + value = value[:-1] + else: + value = "%s.%s" % (value, zonename) + elif rdtype == 'NS': + nameserver = str(record.target) + if nameserver[-1] == ".": + nameserver = nameserver[:-1] + if value[-1] == ".": + # FQDN provided + if value.endswith(".%s." % zonename): + # in bailiwick + value = self.resolve_glue(record.target) + else: + # out of bailiwick + 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 = 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' + elif rdtype == 'MX': + priority, mailserver = str(value).split(' ') + if mailserver[-1] == ".": + mailserver = mailserver[:-1] + mailserver = '%s.%s' % (mailserver, zonename) + value = '%s,%s' % (priority, mailserver) + logging.info("transformed %s record to GNS format", rdtype) + elif rdtype == 'SRV': + # this is the number for a SRV record + rdtype = 'BOX' + srv = 33 + + # tearing the record apart + try: + srvrecord = str(label).split('.') + proto = srvrecord[1] + except IndexError: + logging.warning("could not parse SRV label %s", label) + return (rdtype, None, None) + priority, weight, destport, target = value.split(' ') + + try: + protostring = proto.strip('_') + protonum = socket.getprotobyname(protostring) + except OSError: + logging.warning("invalid protocol: %s", protostring) + return (rdtype, None, None) + + if target[:-1] == ".": + value = '%s %s %s %s %s %s %s' % ( + destport, protonum, srv, priority, weight, destport, + "%s" % target + ) + else: + value = '%s %s %s %s %s %s %s' % ( + destport, protonum, srv, priority, weight, destport, + "%s.%s" % (target, zonename) + ) + + label = target + else: + logging.info("Did not transform record of type: %s", rdtype) + return (rdtype, value, label) + + def get_gns_zone_serial(self) -> int: + """ + Fetches the zones serial from GNS + :returns: serial of the SOA record in GNS + """ + try: + serial = sp.check_output([GNUNET_GNS_COMMAND, + '-t', 'SOA', + '-u', '%s' % self.domain,]) + serial = serial.decode() + except sp.CalledProcessError: + serial = "" + soa_serial = 0 + soapattern = re.compile(r'.+\s(\d+),\d+,\d+,\d+,\d+', re.M) + if re.findall(soapattern, serial): + soa_serial = re.findall(soapattern, serial)[0] + else: + soa_serial = 0 + return int(soa_serial) + + @staticmethod + def get_zone_soa(zone) -> dns.rdatatype.SOA: + """ + Fetches soa record from zone a given zone + :param zone: A dnspython zone + :returns: SOA record of given zone + """ + soa = None + for soarecord in zone.iterate_rdatas(rdtype=dns.rdatatype.SOA): + if str(soarecord[0]) == '@': + soa = soarecord + return soa + + def add_soa_record_to_gns(self, record) -> None: + """ + Adds a SOA record to GNS + :param record: The record to add + """ + label, ttl, rdata = record + zonetuple = str(rdata).split(' ') + authns, owner, serial, refresh, retry, expiry, irefresh = zonetuple + if authns[-1] == '.': + authns = authns[:-1] + else: + authns = "%s.%s" % (authns, self.domain) + if owner[-1] == '.': + owner = owner[:-1] + else: + owner = "%s.%s" % (owner, self.domain) + + value = "rname=%s mname=%s %s,%s,%s,%s,%s" % (authns, + owner, + serial, + refresh, + retry, + expiry, + irefresh) + recordval = '%s %s %s %s' % (ttl, "SOA", self.flags, str(value)) + recordline = ['-R', recordval] + self.add_recordline_to_gns(recordline, self.domain, str(label)) + + @staticmethod + def create_zone_and_get_pkey(zonestring: str) -> str: + """ + Creates the zone in zonestring and returns pkey + :param zonestring: The label name of the zone + :returns: gnunet pkey of the zone + """ + try: + ret = sp.run([GNUNET_ZONE_CREATION_COMMAND, + '-C', zonestring, + '-V'], + stdout=sp.PIPE, + stderr=sp.DEVNULL, + check=True) + logging.info("executed command: %s", " ".join(ret.args)) + pkey_zone = ret.stdout.decode().strip() + except sp.CalledProcessError: + ret = sp.run([GNUNET_ZONE_CREATION_COMMAND, + '-dq', + '-e', zonestring], + stdout=sp.PIPE) + logging.info("executed command: %s", " ".join(ret.args)) + pkey_zone = ret.stdout.decode().strip() + return pkey_zone + + @staticmethod + def add_pkey_record_to_zone(pkey: str, + domain: str, + label: str, + ttl: str) -> None: + """ + Adds the pkey of the subzone to the parent zone + :param pkey: the public key of the child zone + :param domain: the name of the parent zone + :param label: the label under which to add the pkey + :param ttl: the time to live the record should have + """ + #lookup = sp.run(GNUNET_NAMESTORE_COMMAND, + # '-z', domain, + # '-n', label, + # '-t', 'PKEY') + #if not 'Got result:' in lookup.stdout: + debug = " ".join([GNUNET_NAMESTORE_COMMAND, + '-z', domain, + '-a', '-n', label, + '-t', 'PKEY', + '-V', pkey, + '-e', "%ss" % ttl]) + ret = sp.run([GNUNET_NAMESTORE_COMMAND, + '-z', domain, + '-a', '-n', label, + '-t', 'PKEY', + '-V', pkey, + '-e', "%ss" % ttl]) + logging.info("executed command: %s", debug) + if ret.returncode != 0: + logging.warning("failed to add PKEY record %s to %s", + label, domain) + #logging.warning("PKEY record %s already exists in %s", label, domain) + + def create_zone_hierarchy(self) -> None: + """ + Creates the zone hierarchy in GNS for label + """ + domain = self.domain + + # Build Dictionary from GNS identities + ids = sp.run([GNUNET_ZONE_CREATION_COMMAND, '-d'], stdout=sp.PIPE) + domainlist = ''.join(col for col in ids.stdout.decode()).split('\n') + altdomainlist = [e for e in domainlist if domain + " " in e] + for zone in altdomainlist: + zonename, _, pkey = zone.split(" ") + self.subzonedict[zonename] = (pkey, self.minimum) + + zonelist = self.subzonedict.items() + sortedlist = sorted(zonelist, key=lambda s: len(str(s).split('.'))) + for zone, pkeyttltuple in sortedlist: + pkey, ttl = pkeyttltuple + if not pkey: + domain = ".".join(zone.split('.')[1::]) + label = zone.split('.')[0] + pkey = self.create_zone_and_get_pkey(zone) + logging.info("adding zone %s with %s pkey into %s", zone, pkey, domain) + self.add_pkey_record_to_zone(pkey, domain, label, pkeyttltuple[1]) + self.subzonedict[zone] = (pkey, ttl) + +def main(): + """ + Initializes object and handles arguments + """ + # argument parsing from docstring definition + args = docopt.docopt(__doc__, version='Ascension 0.6.1') + + # argument parsing + debug = args['--debug'] + domain = args.get('<domain>', None) + transferns = args['<transferns>'] if args['<transferns>'] else None + port = args['<port>'] if args['<port>'] else "53" + flags = "p" if args.get('--public') else "n" + standalone = bool(args.get('--standalone')) + dryrun = bool(args.get('--dry-run')) + minimum = args['--minimum-ttl'] + + # Change logging severity to debug + if debug: + logging.basicConfig(level=logging.DEBUG) + + # Initialize class instance + ascender = Ascender(domain, transferns, port, flags, minimum) + + # Do dey run before GNUnet check + if dryrun: + dns_zone_serial = ascender.get_dns_zone_serial(ascender.domain, + ascender.transferns) + if not dns_zone_serial: + return 1 + else: + return 0 + + # Checks if GNUnet services are running + try: + sp.check_output([GNUNET_ARM_COMMAND, '-I'], timeout=1) + except sp.TimeoutExpired: + logging.critical('GNUnet services are not running!') + sys.exit(1) + + # 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() + if gns_zone_serial: + ascender.zonegenerator = dns.query.xfr(ascender.transferns, + ascender.domain, + rdtype=dns.rdatatype.IXFR, + serial=gns_zone_serial, + port=ascender.port) + else: + ascender.zonegenerator = dns.query.xfr(ascender.transferns, + ascender.domain, + port=ascender.port) + dns_zone_serial = ascender.get_dns_zone_serial(ascender.domain, + ascender.transferns) + + if not dns_zone_serial: + logging.error("Could not get DNS zone serial") + if standalone: + return 1 + time.sleep(retry) + 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) + continue + elif gns_zone_serial > dns_zone_serial: + logging.critical("SOA serial in GNS is bigger than SOA serial in DNS?") + logging.critical("GNS zone: %s, DNS zone: %s", gns_zone_serial, dns_zone_serial) + if standalone: + return 1 + time.sleep(retry) + 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, + check_origin=False) + ascender.soa = ascender.get_zone_soa(ascender.zone) + refresh = int(str(ascender.soa[2]).split(" ")[3]) + retry = int(str(ascender.soa[2]).split(" ")[4]) + except dns.zone.BadZone: + logging.critical("Malformed DNS Zone '%s'", ascender.domain) + if standalone: + return 2 + time.sleep(retry) + continue + + ascender.add_records_to_gns() + logging.info("Finished migration of the zone %s", ascender.domain) + +if __name__ == '__main__': + main() diff --git a/deb_dist/ascension-0.6.1/debian/.debhelper/generated/python3-ascension/installed-by-dh_installdocs b/deb_dist/ascension-0.6.1/debian/.debhelper/generated/python3-ascension/installed-by-dh_installdocs diff --git a/deb_dist/ascension-0.6.1/debian/changelog b/deb_dist/ascension-0.6.1/debian/changelog @@ -0,0 +1,5 @@ +ascension (0.6.1-1) unstable; urgency=low + + * source package automatically created by stdeb 0.8.5 + + -- rexxnor <rexxnor+gnunet@brief.li> Fri, 10 May 2019 07:37:51 +0000 diff --git a/deb_dist/ascension-0.6.1/debian/compat b/deb_dist/ascension-0.6.1/debian/compat @@ -0,0 +1 @@ +7 diff --git a/deb_dist/ascension-0.6.1/debian/control b/deb_dist/ascension-0.6.1/debian/control @@ -0,0 +1,36 @@ +Source: ascension +Maintainer: rexxnor <rexxnor+gnunet@brief.li> +Section: python +Priority: optional +Build-Depends: python3-setuptools, python3-all, debhelper (>= 7.4.3) +Standards-Version: 3.9.1 + + + + + +Package: python3-ascension +Architecture: all +Depends: ${misc:Depends}, ${python3:Depends} +Description: Tool to migrate DNS Zones to the GNU Name System + # Ascension + . + Tool to easily migrate existing DNS Zones into the GNU Name System using + incremental zone transfers (AXFR/IXFR). + . + ## How to install + To install the ascension simply execute one of the following commands in the + freshly cloned directory: + . + ```bash + # System wide installation + sudo python3 setup.py install + . + # Local installation through virtualenv + python3 -m venv .venv + source .venv/bin/activate + python3 setup.py install + ``` + . + ## How to install (Developer) + diff --git a/deb_dist/ascension-0.6.1/debian/files b/deb_dist/ascension-0.6.1/debian/files @@ -0,0 +1,2 @@ +ascension_0.6.1-1_amd64.buildinfo python optional +python3-ascension_0.6.1-1_all.deb python optional diff --git a/deb_dist/ascension-0.6.1/debian/python3-ascension.postinst.debhelper b/deb_dist/ascension-0.6.1/debian/python3-ascension.postinst.debhelper @@ -0,0 +1,7 @@ + +# Automatically added by dh_python3: +if which py3compile >/dev/null 2>&1; then + py3compile -p python3-ascension +fi + +# End automatically added section diff --git a/deb_dist/ascension-0.6.1/debian/python3-ascension.prerm.debhelper b/deb_dist/ascension-0.6.1/debian/python3-ascension.prerm.debhelper @@ -0,0 +1,10 @@ + +# Automatically added by dh_python3: +if which py3clean >/dev/null 2>&1; then + py3clean -p python3-ascension +else + dpkg -L python3-ascension | perl -ne 's,/([^/]*)\.py$,/__pycache__/\1.*, or next; unlink $_ or die $! foreach glob($_)' + find /usr/lib/python3/dist-packages/ -type d -name __pycache__ -empty -print0 | xargs --null --no-run-if-empty rmdir +fi + +# End automatically added section diff --git a/deb_dist/ascension-0.6.1/debian/python3-ascension.substvars b/deb_dist/ascension-0.6.1/debian/python3-ascension.substvars @@ -0,0 +1,3 @@ +python3:Depends=python3-coverage, python3-dnspython, python3-docopt, python3-mock, python3-pbr, python3-six, python3:any, python3:any (>= 3.3.2-2~) +misc:Depends= +misc:Pre-Depends= diff --git a/deb_dist/ascension-0.6.1/debian/python3-ascension/DEBIAN/control b/deb_dist/ascension-0.6.1/debian/python3-ascension/DEBIAN/control @@ -0,0 +1,30 @@ +Package: python3-ascension +Source: ascension +Version: 0.6.1-1 +Architecture: all +Maintainer: rexxnor <rexxnor+gnunet@brief.li> +Installed-Size: 59 +Depends: python3-coverage, python3-dnspython, python3-docopt, python3-mock, python3-pbr, python3-six, python3:any (>= 3.3.2-2~) +Section: python +Priority: optional +Description: Tool to migrate DNS Zones to the GNU Name System + # Ascension + . + Tool to easily migrate existing DNS Zones into the GNU Name System using + incremental zone transfers (AXFR/IXFR). + . + ## How to install + To install the ascension simply execute one of the following commands in the + freshly cloned directory: + . + ```bash + # System wide installation + sudo python3 setup.py install + . + # Local installation through virtualenv + python3 -m venv .venv + source .venv/bin/activate + python3 setup.py install + ``` + . + ## How to install (Developer) diff --git a/deb_dist/ascension-0.6.1/debian/python3-ascension/DEBIAN/md5sums b/deb_dist/ascension-0.6.1/debian/python3-ascension/DEBIAN/md5sums @@ -0,0 +1,10 @@ +e39447d26076db60f6e3af5fcc58d379 usr/bin/ascension +9a1cca110e94552f9190fb1b0e3e5dad usr/lib/python3/dist-packages/ascension-0.6.1.egg-info/PKG-INFO +68b329da9893e34099c7d8ad5cb9c940 usr/lib/python3/dist-packages/ascension-0.6.1.egg-info/dependency_links.txt +9cda1022e5fc72a3762b4bc09ee0ddb5 usr/lib/python3/dist-packages/ascension-0.6.1.egg-info/entry_points.txt +d41d8cd98f00b204e9800998ecf8427e usr/lib/python3/dist-packages/ascension-0.6.1.egg-info/requires.txt +e616e4373e7b199db038fd8e938a3188 usr/lib/python3/dist-packages/ascension-0.6.1.egg-info/top_level.txt +d41d8cd98f00b204e9800998ecf8427e usr/lib/python3/dist-packages/ascension/__init__.py +60473b52ad93a5a6dcbcfd6b57ac0f00 usr/lib/python3/dist-packages/ascension/ascension.py +3211ad0ee8099a5512e496e8a4a39816 usr/man/man1/ascension.1 +18141e8fa1722169f414faf3c57b780a usr/share/doc/python3-ascension/changelog.Debian.gz diff --git a/deb_dist/ascension-0.6.1/debian/python3-ascension/DEBIAN/postinst b/deb_dist/ascension-0.6.1/debian/python3-ascension/DEBIAN/postinst @@ -0,0 +1,9 @@ +#!/bin/sh +set -e + +# Automatically added by dh_python3: +if which py3compile >/dev/null 2>&1; then + py3compile -p python3-ascension +fi + +# End automatically added section diff --git a/deb_dist/ascension-0.6.1/debian/python3-ascension/DEBIAN/prerm b/deb_dist/ascension-0.6.1/debian/python3-ascension/DEBIAN/prerm @@ -0,0 +1,12 @@ +#!/bin/sh +set -e + +# Automatically added by dh_python3: +if which py3clean >/dev/null 2>&1; then + py3clean -p python3-ascension +else + dpkg -L python3-ascension | perl -ne 's,/([^/]*)\.py$,/__pycache__/\1.*, or next; unlink $_ or die $! foreach glob($_)' + find /usr/lib/python3/dist-packages/ -type d -name __pycache__ -empty -print0 | xargs --null --no-run-if-empty rmdir +fi + +# End automatically added section diff --git a/deb_dist/ascension-0.6.1/debian/python3-ascension/usr/bin/ascension b/deb_dist/ascension-0.6.1/debian/python3-ascension/usr/bin/ascension @@ -0,0 +1,12 @@ +#! /usr/bin/python3 +# EASY-INSTALL-ENTRY-SCRIPT: 'ascension==0.6.1','console_scripts','ascension' +__requires__ = 'ascension==0.6.1' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('ascension==0.6.1', 'console_scripts', 'ascension')() + ) diff --git a/deb_dist/ascension-0.6.1/debian/python3-ascension/usr/man/man1/ascension.1 b/deb_dist/ascension-0.6.1/debian/python3-ascension/usr/man/man1/ascension.1 @@ -0,0 +1,108 @@ +.\" This file is part of Ascension. +.\" Copyright (C) 2018,2019 GNUnet e.V. +.\" +.\" Permission is granted to copy, distribute and/or modify this document +.\" under the terms of the GNU Free Documentation License, Version 1.3 or +.\" any later version published by the Free Software Foundation; with no +.\" Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A +.\" copy of the license is included in the file +.\" ``FDL-1.3''. +.\" +.\" A copy of the license is also available from the Free Software +.\" Foundation Web site at http://www.gnu.org/licenses/fdl.html. +.\" +.\" Alternately, this document is also available under the General +.\" Public License, version 3 or later, as published by the Free Software +.\" Foundation. A copy of the license is included in the file +.\" ``GPL3''. +.\" +.\" A copy of the license is also available from the Free Software +.\" Foundation Web site at http://www.gnu.org/licenses/gpl.html. +.\" +.\" SPDX-License-Identifier: GPL3.0-or-later OR FDL1.3-or-later +.\" +.Dd May 9, 2019 +.Dt ASCENSION 1 +.Os +.Sh NAME +.Nm ascension +.Nd migrate existing DNS zones into the GNU Name System +.Sh SYNOPSIS +.Nm +.Op Ar domain Fl d Fl p Fl s \- minimum-ttl=<ttl> \- dry-run +.Op Ar domain port Fl d Fl p Fl s \- minimum-ttl=<ttl> \- dry-run +.Op Ar domain Fl n Ar transferns Fl d Fl p Fl s Fl \- minimum-ttl=<ttl> \- dry-run +.Op Ar domain Fl n Ar transferns Ar port Fl d Fl p Fl s \- minimum-ttl=<ttl> \- dry-run +.Op Fl d | \-debug +.Op Fl h | \-help +.Op Fl p | \-public +.Op Fl v | \-version +.Op Fl s | \-standalone +.Sh DESCRIPTION +.Nm +is a tool to migrate existing DNS Zones into the GNU Name System (GNS) using incremental zone transfers (AXFR/IXFR). +To achieve this it uses +.Xr gnunet-identity 1 , +.Xr gnunet-namestore 1 , +.Xr gnunet-gns 1 . +As +.Nm +relies on these 3 GNUnet services, +.Xr gnunet-arm 1 +must be installed and running. +.Bl -tag -width Ds +.It Ar domain Fl d Fl p Fl s Fl minimum-ttl=<ttl> +Migrate the DOMAIN passed as domain. +The debug, public and standalone options are optional. +.It Ar domain port Fl d Fl p Fl s Fl minimum-ttl=<ttl> +Migrate the DOMAIN domain, using port for zone transfer. +The debug, public and standalone options are optional. +.It Ar domain Fl n Ar transferns Fl d Fl p Fl s Fl minimum-ttl=<ttl> +Migrate the DOMAIN domain from the DNS server transferns. +The debug, public and standalone options are optional. +.It Ar domain Fl n Ar transferns Ar port Fl d Fl p Fl s Fl minimum-ttl=<ttl> +Migrate the DOMAIN domain from the DNS server transferns using port for the zone transfer. +The debug, public and standalone options are optional. +.It Fl s | \-standalone +Run Ascension once +.It Fl d | \-debug +Enable debugging +.It Fl h | \-help +Print short help on options +.It Fl p | \-public +Make records public on the DHT +.It Fl v | \-version +Print ascension version number +.El +.\" .Sh FILES +.Sh EXAMPLES +To transfer the sy TLD from ns1.tld.sy: +.Pp +.Dl $ ascension sy -n ns1.tld.sy. +.Pp +To transfer the nu TLD from zonedata.iis.se with debug options enabled: +.Pp +.Dl $ ascension nu -n zonedata.iis.se. -d +.Sh SEE ALSO +.Xr gnunet-arm 1 , +.Xr gnunet-gns 1 , +.Xr gnunet-identity 1 , +.Xr gnunet-namestore 1 +.Sh HISTORY +The +.Nm +tool was designed and written in 2018 by +.An rexxnor Aq Mt rexxnor+gnunet@brief.li . +.Sh AUTHORS +This man page was written by +.An ng0 Aq Mt ng0@gnunet.org +and updated by +.An rexxnor Aq Mt rexxnor+gnunet@brief.li +it first appeared in +.Nm +0.5.1. +.Sh BUGS +Report bugs by using +.Lk https://bugs.gnunet.org +or by sending electronic mail to +.Aq Mt bug-gnunet@gnu.org . diff --git a/deb_dist/ascension-0.6.1/debian/python3-ascension/usr/share/doc/python3-ascension/changelog.Debian.gz b/deb_dist/ascension-0.6.1/debian/python3-ascension/usr/share/doc/python3-ascension/changelog.Debian.gz Binary files differ. diff --git a/deb_dist/ascension-0.6.1/debian/rules b/deb_dist/ascension-0.6.1/debian/rules @@ -0,0 +1,31 @@ +#!/usr/bin/make -f + +# This file was automatically generated by stdeb 0.8.5 at +# Fri, 10 May 2019 07:37:51 +0000 + +%: + dh $@ --with python3 --buildsystem=python_distutils + + +override_dh_auto_clean: + python3 setup.py clean -a + find . -name \*.pyc -exec rm {} \; + + + +override_dh_auto_build: + python3 setup.py build --force + + + +override_dh_auto_install: + python3 setup.py install --force --root=debian/python3-ascension --no-compile -O0 --install-layout=deb --prefix=/usr + + + +override_dh_python2: + dh_python2 --no-guessing-versions + + + + diff --git a/deb_dist/ascension-0.6.1/debian/source/format b/deb_dist/ascension-0.6.1/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/deb_dist/ascension-0.6.1/debian/source/options b/deb_dist/ascension-0.6.1/debian/source/options @@ -0,0 +1 @@ +extend-diff-ignore="\.egg-info$" +\ No newline at end of file diff --git a/deb_dist/ascension-0.6.1/setup.cfg b/deb_dist/ascension-0.6.1/setup.cfg @@ -0,0 +1,4 @@ +[egg_info] +tag_build = +tag_date = 0 + diff --git a/deb_dist/ascension-0.6.1/setup.py b/deb_dist/ascension-0.6.1/setup.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +""" +This file is part of Ascension. +Copyright (C) 2019 GNUnet e.V. + +Ascension is free software: you can redistribute it and/or modify it +under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, +or (at your option) any later version. + +Ascension is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +SPDX-License-Identifier: AGPL3.0-or-later + +Author rexxnor +""" + +import setuptools + +with open("README", "r") as fh: + long_description = fh.read() + +setuptools.setup( + name="ascension", + version="0.6.1", + author="rexxnor", + author_email="rexxnor+gnunet@brief.li", + description="Tool to migrate DNS Zones to the GNU Name System", + long_description=long_description, + url="https://gnunet.org/git/ascension.git/", + packages=['ascension'], + data_files=[('man/man1', ['ascension.1'])], + classifiers=[ + "Programming Language :: Python :: 3", + ], + entry_points={ + 'console_scripts': [ + 'ascension=ascension.ascension:main', + ], + }, + install_requires=[ + 'coverage', + 'dnspython', + 'docopt', + 'mock', + 'pbr', + 'six', + ], +) diff --git a/deb_dist/python3-ascension_0.5.0-1_all.deb b/deb_dist/python3-ascension_0.5.0-1_all.deb Binary files differ. diff --git a/deb_dist/python3-ascension_0.6.1-1_all.deb b/deb_dist/python3-ascension_0.6.1-1_all.deb Binary files differ. diff --git a/debian/ascension-bind-0.0.1/debian/ascension-bind.config b/debian/ascension-bind-0.0.1/debian/ascension-bind.config @@ -5,7 +5,7 @@ # load debconf library . /usr/share/debconf/confmodule -set -e +#set -e if [ -n "$DEBIAN_SCRIPT_DEBUG" ]; then set -v -x; DEBIAN_SCRIPT_TRACE=1; fi ${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*" 1>&2 } @@ -48,16 +48,15 @@ db_input medium ascension-bind/publishing || true db_go || true PUBLIC=$RET +echo "Zonestatus check" zonestatus=true for ZONE in "${zones[@]}" do - echo "$ZONE" | hexdump -C - ZONE=echo "$ZONE" | tr -d '\n' - echo "$ZONE" | hexdump -C - exit 1 - zonestatus=zonestatus && ascension "$ZONE" -n localhost + ZONE=$( echo "$ZONE" | tr -d '\n') + zonestatus=zonestatus && ascension "$ZONE" -n localhost --dry-run done +echo "After Dry Runs" if [ -z $zonestatus ]; then echo "Some zones don't allow zone transfer" if grep allow-transfer /etc/bind/named.conf* &> /dev/null; then @@ -72,7 +71,7 @@ if [ -z $zonestatus ]; then zonestatus=true for ZONE in "${zones[@]}" do - ZONE=${ZONE} | tr -d '\n' + ZONE=$( echo "$ZONE" | tr -d '\n') zonestatus=zonestatus && ascension "$ZONE" -n localhost done if [ -z $zonestatus ]; then @@ -85,12 +84,14 @@ if [ -z $zonestatus ]; then fi fi +echo "Everything okay, templating files" mkdir -p /etc/ascension.d/ for ZONE in "${zones[@]}" do - ZONE=${ZONE} | tr -d '\n' + ZONE=$( echo "$ZONE" | tr -d '\n') + FILECONV=$( echo "$ZONE" | tr '.' '_') echo "Creating ascension import config files for $ZONE" - cat > "/etc/ascension.d/bind-import-$ZONE.conf" << EOF + cat > "/etc/ascension.d/bind-import-$FILE.conf" << EOF [ascension] ZONE = $ZONE TRANSFERNS = localhost @@ -99,7 +100,7 @@ PUBLIC = $PUBLIC EOF touch "/etc/ascension.d/bind-import-$ZONE.conf" echo "Creating systemd unit file." - cat > "/etc/ascension.d/ascension-bind-$ZONE.service" << EOF + cat > "/etc/ascension.d/ascension-bind-$FILECONV.service" << EOF [Unit] Description=Ascension-bind for $ZONE After=gnunet-ascension.service @@ -112,15 +113,16 @@ ExecStart=/usr/bin/ascension $ZONE -n localhost [Install] WantedBy=multi-user.target EOF - ln -sf "/etc/ascension.d/ascension-bind-$ZONE.service" "/lib/systemd/system/ascension-bind-$ZONE.service" + ln -sf "/etc/ascension.d/ascension-bind-$FILECONV.service" "/lib/systemd/system/ascension-bind-$FILECONV.service" done for ZONE in "${zones[@]}" do - ZONE=${ZONE} | tr -d '\n' - echo "Starting and enabling ascension-bind-$ZONE" - systemctl start "ascension-bind-$ZONE" - systemctl enable "ascension-bind-$ZONE" + ZONE=$( echo "$ZONE" | tr -d '\n') + ZONE=$( echo "$ZONE" | tr '.' '_') + echo "Starting and enabling ascension-bind-$FILECONV" + systemctl start "ascension-bind-$FILECONV" + systemctl enable "ascension-bind-$FILECONV" #deb-systemd-invoke start "ascension-bind-$ZONE" #deb-systemd-invoke enable "ascension-bind-$ZONE" done diff --git a/debian/ascension-bind-0.0.1/debian/ascension-bind/DEBIAN/config b/debian/ascension-bind-0.0.1/debian/ascension-bind/DEBIAN/config @@ -5,7 +5,7 @@ # load debconf library . /usr/share/debconf/confmodule -set -e +#set -e if [ -n "$DEBIAN_SCRIPT_DEBUG" ]; then set -v -x; DEBIAN_SCRIPT_TRACE=1; fi ${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*" 1>&2 } @@ -48,16 +48,15 @@ db_input medium ascension-bind/publishing || true db_go || true PUBLIC=$RET +echo "Zonestatus check" zonestatus=true for ZONE in "${zones[@]}" do - echo "$ZONE" | hexdump -C - ZONE=echo "$ZONE" | tr -d '\n' - echo "$ZONE" | hexdump -C - exit 1 - zonestatus=zonestatus && ascension "$ZONE" -n localhost + ZONE=$( echo "$ZONE" | tr -d '\n') + zonestatus=zonestatus && ascension "$ZONE" -n localhost --dry-run done +echo "After Dry Runs" if [ -z $zonestatus ]; then echo "Some zones don't allow zone transfer" if grep allow-transfer /etc/bind/named.conf* &> /dev/null; then @@ -72,7 +71,7 @@ if [ -z $zonestatus ]; then zonestatus=true for ZONE in "${zones[@]}" do - ZONE=${ZONE} | tr -d '\n' + ZONE=$( echo "$ZONE" | tr -d '\n') zonestatus=zonestatus && ascension "$ZONE" -n localhost done if [ -z $zonestatus ]; then @@ -85,12 +84,14 @@ if [ -z $zonestatus ]; then fi fi +echo "Everything okay, templating files" mkdir -p /etc/ascension.d/ for ZONE in "${zones[@]}" do - ZONE=${ZONE} | tr -d '\n' + ZONE=$( echo "$ZONE" | tr -d '\n') + FILECONV=$( echo "$ZONE" | tr '.' '_') echo "Creating ascension import config files for $ZONE" - cat > "/etc/ascension.d/bind-import-$ZONE.conf" << EOF + cat > "/etc/ascension.d/bind-import-$FILE.conf" << EOF [ascension] ZONE = $ZONE TRANSFERNS = localhost @@ -99,7 +100,7 @@ PUBLIC = $PUBLIC EOF touch "/etc/ascension.d/bind-import-$ZONE.conf" echo "Creating systemd unit file." - cat > "/etc/ascension.d/ascension-bind-$ZONE.service" << EOF + cat > "/etc/ascension.d/ascension-bind-$FILECONV.service" << EOF [Unit] Description=Ascension-bind for $ZONE After=gnunet-ascension.service @@ -112,15 +113,16 @@ ExecStart=/usr/bin/ascension $ZONE -n localhost [Install] WantedBy=multi-user.target EOF - ln -sf "/etc/ascension.d/ascension-bind-$ZONE.service" "/lib/systemd/system/ascension-bind-$ZONE.service" + ln -sf "/etc/ascension.d/ascension-bind-$FILECONV.service" "/lib/systemd/system/ascension-bind-$FILECONV.service" done for ZONE in "${zones[@]}" do - ZONE=${ZONE} | tr -d '\n' - echo "Starting and enabling ascension-bind-$ZONE" - systemctl start "ascension-bind-$ZONE" - systemctl enable "ascension-bind-$ZONE" + ZONE=$( echo "$ZONE" | tr -d '\n') + ZONE=$( echo "$ZONE" | tr '.' '_') + echo "Starting and enabling ascension-bind-$FILECONV" + systemctl start "ascension-bind-$FILECONV" + systemctl enable "ascension-bind-$FILECONV" #deb-systemd-invoke start "ascension-bind-$ZONE" #deb-systemd-invoke enable "ascension-bind-$ZONE" done diff --git a/debian/ascension-bind-0.0.1/debian/ascension-bind/DEBIAN/control b/debian/ascension-bind-0.0.1/debian/ascension-bind/DEBIAN/control @@ -2,7 +2,7 @@ Package: ascension-bind Version: 0.0.1-1 Architecture: amd64 Maintainer: rexxnor <rexxnor@brief.li> -Installed-Size: 16 +Installed-Size: 17 Depends: debconf (>= 0.5) | debconf-2.0 Section: net Priority: optional diff --git a/helpers/python3-ascension.postinst b/helpers/python3-ascension.postinst @@ -0,0 +1,46 @@ +#!/bin/sh +# postinst script for ascension-bind +# +# see: dh_installdeb(1) +# load debconf library +set -e + +if ! id ascension; then + adduser --system ascension +fi +# ok if this fails as gnunet is not yet a dependency +if ! id gnunet; then + addgroup --system gnunet + adduser ascension gnunet +fi + +mkdir -p /etc/ascension.d/ + +# add systemd unit file + cat > "/etc/ascension.d/gnunet-ascension.service" << EOF +[Unit] +Description=Starting GNUnet peer for ascension +After=network.target + +[Service] +Type=oneshot +RemainAfterExit=yes +User=ascension +ExecStart=/usr/bin/gnunet-arm -s +ExecStop=/usr/bin/gnunet-arm -e +ExecReload=/usr/bin/gnunet-arm -r + +[Install] +WantedBy=multi-user.target +EOF + +# link the systemd unit file +ln -sf "/etc/ascension.d/gnunet-ascension.service" "/lib/systemd/system/gnunet-ascension.service" +systemctl daemon-reload + +# start and enable service +systemctl start gnunet-ascension +systemctl enable gnunet-ascension + +exit 0 +#DEBHELPER# diff --git a/helpers/python3-ascension.prerm b/helpers/python3-ascension.prerm @@ -0,0 +1,22 @@ +#!/bin/sh +# prerm script for ascension-bind +# +# see: dh_installdeb(1) +# load debconf library +set -e + +mkdir -p /etc/ascension.d/ + +# remove systemd stuff +systemctl disable gnunet-ascension +systemctl stop gnunet-ascension + +# remove the systemd files +unlink /lib/systemd/system/gnunet-ascension.service +rm /etc/ascension.d/gnunet-ascension.service + +# link the systemd unit file +systemctl daemon-reload + +exit 0 +#DEBHELPER#