aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrexxnor <rexxnor+git@brief.li>2020-04-26 12:15:57 +0200
committerrexxnor <rexxnor+git@brief.li>2020-04-26 21:57:39 +0200
commitc7b20648a731b7a9ba07e3b42fa4e6fc410b333c (patch)
tree2b429d110289929f4b55cc311cbf671518600632
parent1990ea7518d7ef0de3a8743ede70f7d3a3efdb0a (diff)
downloadascension-c7b20648a731b7a9ba07e3b42fa4e6fc410b333c.tar.gz
ascension-c7b20648a731b7a9ba07e3b42fa4e6fc410b333c.zip
refactored argument parsing and updated man page accordingly
- switched from docopt to argparse - improved docstring by removing docopt format - updated man page with more verbose instructions
-rw-r--r--README43
-rw-r--r--ascension-0.5.0.tar.gzbin9836 -> 0 bytes
-rw-r--r--ascension-0.6.1.tar.gzbin10617 -> 0 bytes
-rw-r--r--ascension.174
-rw-r--r--ascension/ascension.py146
5 files changed, 138 insertions, 125 deletions
diff --git a/README b/README
index ed6e926..bda0fbc 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
1# Ascension 1#Ascension
2 2
3Tool to easily migrate existing DNS Zones into the GNU Name System using 3Tool to easily migrate existing DNS Zones into the GNU Name System using
4incremental zone transfers (AXFR/IXFR). 4incremental zone transfers (AXFR/IXFR).
@@ -35,30 +35,25 @@ You can also just run the file ascension.py itself directly.
35 35
36Taken from the docstring of the ascension.py file: 36Taken from the docstring of the ascension.py file:
37``` 37```
38Ascension 38usage: ascension.py [-h] [-n NAMESERVER] [-P PORT] [-t] [-s] [-p] [-g] [-v] [-V] domain
39
40Easy tool to migrate DNS zones into GNS
39 41
40Usage: 42positional arguments:
41 ascension <domain> [-d] [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run] 43 domain Domain to be migrated
42 ascension <domain> <port> [-d] [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run]
43 ascension <domain> -n <transferns> [-d] [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run]
44 ascension <domain> -n <transferns> <port> [-d] [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run]
45 ascension -p | --public
46 ascension -s | --debug
47 ascension -s | --standalone
48 ascension -h | --help
49 ascension -v | --version
50 44
51Options: 45optional arguments:
52 <domain> Domain to migrate 46 -h, --help show this help message and exit
53 <port> Port for zone transfer 47 -n NAMESERVER, --nameserver NAMESERVER
54 <transferns> DNS Server that does the zone transfer 48 Nameserver to use for migrating
55 --minimum-ttl=<ttl> Minimum TTL for records to migrate [default: 3600] 49 -P PORT, --port PORT Port to use for zone transfer with nameserver
56 --dry-run Only try if a zone transfer is allowed 50 -t, --ttl Sets TTL of records lower than TTL to specified TTL
57 -p --public Make records public on the DHT 51 -s, --standalone Run ascension once and not as daemon
58 -s --standalone Run ascension once 52 -p, --public Push records to the public DHT
59 -d --debug Enable debugging 53 -g, --dryrun Tests if zone is transferrable without changing anything
60 -h --help Show this screen. 54 -v, --verbose Enable verbose debugging
61 -v --version Show version. 55 -V, --version show program's version number and exit
56Ascension
62``` 57```
63 58
64Example use: 59Example use:
@@ -66,5 +61,5 @@ Example use:
66# Transfers the sy TLD from ns1.tld.sy. 61# Transfers the sy TLD from ns1.tld.sy.
67ascension sy -n ns1.tld.sy. 62ascension sy -n ns1.tld.sy.
68# Transfers the nu TLD from zonedata.iis.se with debug options enabled 63# Transfers the nu TLD from zonedata.iis.se with debug options enabled
69ascension nu -n zonedata.iis.se. -d 64ascension nu -n zonedata.iis.se. -v
70``` 65```
diff --git a/ascension-0.5.0.tar.gz b/ascension-0.5.0.tar.gz
deleted file mode 100644
index b0468bc..0000000
--- a/ascension-0.5.0.tar.gz
+++ /dev/null
Binary files differ
diff --git a/ascension-0.6.1.tar.gz b/ascension-0.6.1.tar.gz
deleted file mode 100644
index f306bab..0000000
--- a/ascension-0.6.1.tar.gz
+++ /dev/null
Binary files differ
diff --git a/ascension.1 b/ascension.1
index c28f84b..e364695 100644
--- a/ascension.1
+++ b/ascension.1
@@ -21,56 +21,64 @@
21.\" 21.\"
22.\" SPDX-License-Identifier: GPL3.0-or-later OR FDL1.3-or-later 22.\" SPDX-License-Identifier: GPL3.0-or-later OR FDL1.3-or-later
23.\" 23.\"
24.Dd May 9, 2019 24.Dd April 26, 2020
25.Dt ASCENSION 1 25.Dt ASCENSION 1
26.Os 26.Os
27.Sh NAME 27.Sh NAME
28.Nm ascension 28.Nm Ascension
29.Nd migrate existing DNS zones into the GNU Name System 29.Nd migrate existing DNS zones into the GNU Name System
30.Sh SYNOPSIS 30.Sh SYNOPSIS
31.Nm 31.Op -n NAMESERVER
32.Op Ar domain Fl d Fl p Fl s -minimum-ttl=<ttl> -dry-run 32.Op -P PORT
33.Nm 33.Op -t TTL
34.Op Ar domain port Fl d Fl p Fl s -minimum-ttl=<ttl> -dry-run 34.Op -s
35.Nm 35.Op -p
36.Op Ar domain Fl n Ar transferns Fl d Fl p Fl s Fl -minimum-ttl=<ttl> -dry-run 36.Op -v
37.Nm 37.Op -g
38.Op Ar domain Fl n Ar transferns Ar port Fl d Fl p Fl s -minimum-ttl=<ttl> -dry-run 38.Op -V
39domain
39.Sh DESCRIPTION 40.Sh DESCRIPTION
40.Nm 41.Nm
41is a tool to migrate existing DNS Zones into the GNU Name System (GNS) using incremental zone transfers (AXFR/IXFR). 42is a tool to migrate existing DNS Zones into the GNU Name System (GNS) using incremental zone transfers (AXFR/IXFR).
42To achieve this it uses 43To achieve this it calls
43.Xr gnunet-identity 1 , 44.Xr gnunet-identity 1 ,
44.Xr gnunet-namestore 1 , 45.Xr gnunet-namestore 1 ,
45.Xr gnunet-gns 1 . 46.Xr gnunet-gns 1 .
46As
47.Nm 47.Nm
48relies on these 3 GNUnet services, 48relies on GNUnet and these 3 GNUnet services,
49.Xr gnunet-arm 1 49.Xr gnunet-arm 1
50must be installed and running. 50must be installed and running.
51.Bl -tag -width Ds 51.Bl -tag -width Ds
52.It Ar domain Fl d Fl p Fl s -minimum-ttl=<ttl> -dry-run 52.It Ar domain
53Migrate the DOMAIN passed as domain. 53The domain that should be migrated to the GNU Name System (GNS)
54The debug, public and standalone options are optional. 54.It Fl n | \-nameserver Ar NAMESERVER
55.It Ar domain port Fl d Fl p Fl s -minimum-ttl=<ttl> -dry-run 55Nameserver to contact for zone transfer. Defaults to name server listed in the SOA record
56Migrate the DOMAIN domain, using port for zone transfer. 56.It Fl p | \-port Ar PORT
57The debug, public and standalone options are optional. 57Use the specified port when contacting the nameserver to transfer the zone
58.It Ar domain Fl n Ar transferns Fl d Fl p Fl s -minimum-ttl=<ttl> -dry-run 58.It Fl t | \-ttl Ar TTL
59Migrate the DOMAIN domain from the DNS server transferns. 59When adding records to GNS a small ttl in DNS can cause issues as records need
60The debug, public and standalone options are optional. 60to be resigned often (every ttl seconds as recordsets in GNS are signed with an
61.It Ar domain Fl n Ar transferns Ar port Fl d Fl p Fl s -minimum-ttl=<ttl> -dry-run 61absolut expiration time) to remain valid. Therefore this ttl specifies the
62Migrate the DOMAIN domain from the DNS server transferns using port for the zone transfer. 62lowest ttl a record will have in GNS.
63The debug, public and standalone options are optional.
64.It Fl s | \-standalone 63.It Fl s | \-standalone
65Run Ascension once 64Run Ascension to migrate a zone once. If not specified it will run as a daemon
66.It Fl d | \-debug 65that updates the zone after the expiry specified in the zones SOA record has
67Enable debugging 66elapsed.
68.It Fl h | \-help 67.It Fl v | \-verbose
69Print short help on options 68Increase logging verbosity. Shows more log levels than default including INFO,
69DEBUG and WARNING.
70.It Fl p | \-public 70.It Fl p | \-public
71Make records public on the DHT 71Set the public flag for records and publish them on the DHT. When in possession
72of the public key of the zone in BASE32 format anyone can resolve a record
73within the zone provided they also know the label under which the recorset is
74stored.
75.It Fl g | \-dryrun
76Checks whether or not the domains nameserver supports zone transfer for the
77given domain. When a nameserver is specified it will be checked instead.
78.It Fl h | \-help
79Show the usage and argument syntax of Ascension.
72.It Fl v | \-version 80.It Fl v | \-version
73Print ascension version number 81Show the current version number
74.El 82.El
75.\" .Sh FILES 83.\" .Sh FILES
76.Sh EXAMPLES 84.Sh EXAMPLES
@@ -78,7 +86,7 @@ To transfer the sy TLD from ns1.tld.sy:
78.Pp 86.Pp
79.Dl $ ascension sy -n ns1.tld.sy. 87.Dl $ ascension sy -n ns1.tld.sy.
80.Pp 88.Pp
81To transfer the nu TLD from zonedata.iis.se with debug options enabled: 89To test if the given domains nameserver supports zone transfers for that zone:
82.Pp 90.Pp
83.Dl $ ascension nu -n zonedata.iis.se. -d 91.Dl $ ascension nu -n zonedata.iis.se. -d
84.Sh SEE ALSO 92.Sh SEE ALSO
diff --git a/ascension/ascension.py b/ascension/ascension.py
index bb65b13..e756bc6 100644
--- a/ascension/ascension.py
+++ b/ascension/ascension.py
@@ -1,49 +1,28 @@
1#!/usr/bin/env python3 1#!/usr/bin/env python3
2# This file is part of Ascension.
3# Copyright (C) 2019 GNUnet e.V.
4#
5# Ascension is free software: you can redistribute it and/or modify it
6# under the terms of the GNU Affero General Public License as published
7# by the Free Software Foundation, either version 3 of the License,
8# or (at your option) any later version.
9#
10# Ascension is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# Affero General Public License for more details.
14#
15# You should have received a copy of the GNU Affero General Public License
16# along with this program. If not, see <http://www.gnu.org/licenses/>.
17#
18# SPDX-License-Identifier: AGPL3.0-or-later
19#
20# Author rexxnor
21""" 2"""
22Usage: 3This file is part of Ascension.
23 ascension <domain> [-d] [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run] 4Copyright (C) 2019-2020 GNUnet e.V.
24 ascension <domain> <port> [-d] [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run] 5
25 ascension <domain> -n <transferns> [-d] [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run] 6Ascension is free software: you can redistribute it and/or modify it
26 ascension <domain> -n <transferns> <port> [-d] [-p] [-s] [--minimum-ttl=<ttl>] [--dry-run] 7under the terms of the GNU Affero General Public License as published
27 ascension -p | --public 8by the Free Software Foundation, either version 3 of the License,
28 ascension -d | --debug 9or (at your option) any later version.
29 ascension -s | --standalone 10
30 ascension -h | --help 11Ascension is distributed in the hope that it will be useful, but
31 ascension -v | --version 12WITHOUT ANY WARRANTY; without even the implied warranty of
32 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33Options: 14Affero General Public License for more details.
34 <domain> Domain to migrate 15
35 <port> Port for zone transfer 16You should have received a copy of the GNU Affero General Public License
36 <transferns> DNS Server that does the zone transfer 17along with this program. If not, see <http://www.gnu.org/licenses/>.
37 --minimum-ttl=<ttl> Minimum TTL for records to migrate [default: 3600] 18
38 --dry-run Only try if a zone transfer is allowed 19SPDX-License-Identifier: AGPL3.0-or-later
39 -p --public Make records public on the DHT 20
40 -s --standalone Run ascension once 21Author rexxnor
41 -d --debug Enable debugging
42 -h --help Show this screen.
43 -v --version Show version.
44""" 22"""
45 23
46# imports 24# imports
25import argparse
47import logging 26import logging
48import os 27import os
49import queue 28import queue
@@ -56,13 +35,13 @@ import threading
56import dns.query 35import dns.query
57import dns.resolver 36import dns.resolver
58import dns.zone 37import dns.zone
59import docopt
60 38
61# GLOBALS for different environments 39# GLOBALS for different environments
62GNUNET_ZONE_CREATION_COMMAND = 'gnunet-identity' 40GNUNET_ZONE_CREATION_COMMAND = 'gnunet-identity'
63GNUNET_NAMESTORE_COMMAND = 'gnunet-namestore' 41GNUNET_NAMESTORE_COMMAND = 'gnunet-namestore'
64GNUNET_GNS_COMMAND = 'gnunet-gns' 42GNUNET_GNS_COMMAND = 'gnunet-gns'
65GNUNET_ARM_COMMAND = 'gnunet-arm' 43GNUNET_ARM_COMMAND = 'gnunet-arm'
44
66# This is the list of record types Ascension (and GNS) currently 45# This is the list of record types Ascension (and GNS) currently
67# explicitly supports. Record types we encounter that are not 46# explicitly supports. Record types we encounter that are not
68# in this list and not in the OBSOLETE_RECORD_TYPES list will 47# in this list and not in the OBSOLETE_RECORD_TYPES list will
@@ -70,6 +49,7 @@ GNUNET_ARM_COMMAND = 'gnunet-arm'
70SUPPORTED_RECORD_TYPES = [ 49SUPPORTED_RECORD_TYPES = [
71 "A", "AAAA", "NS", "MX", "SRV", "TXT", "CNAME" 50 "A", "AAAA", "NS", "MX", "SRV", "TXT", "CNAME"
72] 51]
52
73# Record types that exist in DNS but that won't ever exist in GNS 53# Record types that exist in DNS but that won't ever exist in GNS
74# as they are not needed anymore (so we should not create a warning 54# as they are not needed anymore (so we should not create a warning
75# if we drop one of these). 55# if we drop one of these).
@@ -122,7 +102,7 @@ class Ascender():
122 keystring = ret.stdout.decode().strip() 102 keystring = ret.stdout.decode().strip()
123 pkey, _, privkey = keystring.split(" ") 103 pkey, _, privkey = keystring.split(" ")
124 self.subzonedict[self.domain] = (pkey, self.minimum, privkey) 104 self.subzonedict[self.domain] = (pkey, self.minimum, privkey)
125 logging.info("executed command: %s", " ".join(ret.args)) 105 logging.info("Executed command: %s", " ".join(ret.args))
126 except sp.CalledProcessError: 106 except sp.CalledProcessError:
127 ret = sp.run([GNUNET_ZONE_CREATION_COMMAND, 107 ret = sp.run([GNUNET_ZONE_CREATION_COMMAND,
128 '-dqpe', self.domain], 108 '-dqpe', self.domain],
@@ -194,7 +174,7 @@ class Ascender():
194 174
195 def add_records_to_gns(self) -> None: 175 def add_records_to_gns(self) -> None:
196 """ 176 """
197 Extracts records from zone and adds them to GNS 177 Extracts records from transferred zone and adds them to GNS
198 :raises AttributeError: When getting incomplete data 178 :raises AttributeError: When getting incomplete data
199 """ 179 """
200 logging.info("Starting to add records into GNS...") 180 logging.info("Starting to add records into GNS...")
@@ -332,7 +312,7 @@ class Ascender():
332 taskqueue.put(None) 312 taskqueue.put(None)
333 thread.join(timeout=10) 313 thread.join(timeout=10)
334 if thread.is_alive(): 314 if thread.is_alive():
335 logging.critical("thread join timed out, still running") 315 logging.critical("Thread joining timed out, still running")
336 316
337 # Add soa record to GNS once completed (updates the previous one) 317 # Add soa record to GNS once completed (updates the previous one)
338 self.add_soa_record_to_gns(self.soa) 318 self.add_soa_record_to_gns(self.soa)
@@ -739,37 +719,33 @@ class Ascender():
739 logging.info("adding zone %s with %s pkey into %s", zone, pkey, domain) 719 logging.info("adding zone %s with %s pkey into %s", zone, pkey, domain)
740 self.add_pkey_record_to_zone(pkey, domain, label, ttl) 720 self.add_pkey_record_to_zone(pkey, domain, label, ttl)
741 721
742def main(): 722def main(args):
743 """ 723 """
744 Initializes object and handles arguments 724 Initializes object and handles arguments
745 """ 725 """
746 # argument parsing from docstring definition 726 flags = "p" if args.public else "n"
747 args = docopt.docopt(__doc__, version='Ascension 0.11.5')
748
749 # argument parsing
750 debug = args['--debug']
751 domain = args.get('<domain>', None)
752 transferns = args['<transferns>'] if args['<transferns>'] else None
753 port = args['<port>'] if args['<port>'] else "53"
754 flags = "p" if args.get('--public') else "n"
755 standalone = bool(args.get('--standalone'))
756 dryrun = bool(args.get('--dry-run'))
757 minimum = args['--minimum-ttl']
758 727
759 # Change logging severity to debug 728 # Change logging severity to debug
760 if debug: 729 if args.verbose:
761 logging.basicConfig(level=logging.DEBUG) 730 logging.basicConfig(level=logging.DEBUG)
762 731
763 # Initialize class instance 732 # Initialize class instance
764 ascender = Ascender(domain, transferns, port, flags, minimum) 733 ascender = Ascender(args.domain,
734 args.nameserver,
735 args.port,
736 flags,
737 args.ttl)
765 738
766 # Do dry run before GNUnet check 739 # Do dry run before GNUnet check
767 if dryrun: 740 if args.dryrun:
768 dns_zone_serial = ascender.get_dns_zone_serial(ascender.domain, 741 dns_zone_serial = ascender.get_dns_zone_serial(ascender.domain,
769 ascender.transferns) 742 ascender.transferns)
770 if dns_zone_serial is None: 743 if dns_zone_serial is None:
744 logging.critical('The specified domain is not transferrable \
745 using the given option!')
771 return 1 746 return 1
772 else: 747 else:
748 logging.critical('SUCCESS! The specified domain is transferrable!')
773 return 0 749 return 0
774 750
775 # Checks if GNUnet services are running 751 # Checks if GNUnet services are running
@@ -779,7 +755,7 @@ def main():
779 logging.critical('GNUnet services are not running!') 755 logging.critical('GNUnet services are not running!')
780 sys.exit(1) 756 sys.exit(1)
781 757
782 # Set to defaults to use before we get a SOA for the first time 758 # Set defaults to use before we get a SOA for the first time
783 retry = 300 759 retry = 300
784 refresh = 300 760 refresh = 300
785 761
@@ -804,7 +780,7 @@ def main():
804 780
805 if not dns_zone_serial: 781 if not dns_zone_serial:
806 logging.error("Could not get DNS zone serial") 782 logging.error("Could not get DNS zone serial")
807 if standalone: 783 if args.standalone:
808 return 1 784 return 1
809 time.sleep(retry) 785 time.sleep(retry)
810 continue 786 continue
@@ -815,21 +791,21 @@ def main():
815 elif gns_zone_serial == dns_zone_serial: 791 elif gns_zone_serial == dns_zone_serial:
816 logging.info("GNS zone is up to date.") 792 logging.info("GNS zone is up to date.")
817 print("GNS zone is up to date.") 793 print("GNS zone is up to date.")
818 if standalone: 794 if args.standalone:
819 return 0 795 return 0
820 time.sleep(refresh) 796 time.sleep(refresh)
821 continue 797 continue
822 elif gns_zone_serial > dns_zone_serial: 798 elif gns_zone_serial > dns_zone_serial:
823 logging.critical("SOA serial in GNS is bigger than SOA serial in DNS?") 799 logging.critical("SOA serial in GNS is bigger than SOA serial in DNS?")
824 logging.critical("GNS zone: %s, DNS zone: %s", gns_zone_serial, dns_zone_serial) 800 logging.critical("GNS zone: %s, DNS zone: %s", gns_zone_serial, dns_zone_serial)
825 if standalone: 801 if args.standalone:
826 return 1 802 return 1
827 time.sleep(retry) 803 time.sleep(retry)
828 continue 804 continue
829 else: 805 else:
830 logging.info("GNS zone is out of date, performing incremental transfer.") 806 logging.info("GNS zone is out of date, performing incremental transfer.")
831 needsupdate = True 807 needsupdate = True
832 if standalone: 808 if args.standalone:
833 return 1 809 return 1
834 print("GNS zone is out of date, performing incremental transfer.") 810 print("GNS zone is out of date, performing incremental transfer.")
835 811
@@ -846,7 +822,7 @@ def main():
846 retry = int(str(ascender.soa[2]).split(" ")[4]) 822 retry = int(str(ascender.soa[2]).split(" ")[4])
847 except dns.zone.BadZone: 823 except dns.zone.BadZone:
848 logging.critical("Malformed DNS Zone '%s'", ascender.domain) 824 logging.critical("Malformed DNS Zone '%s'", ascender.domain)
849 if standalone: 825 if args.standalone:
850 return 2 826 return 2
851 time.sleep(retry) 827 time.sleep(retry)
852 continue 828 continue
@@ -857,4 +833,38 @@ def main():
857 logging.info("Finished migration of the zone %s", ascender.domain) 833 logging.info("Finished migration of the zone %s", ascender.domain)
858 834
859if __name__ == '__main__': 835if __name__ == '__main__':
860 main() 836 parser = argparse.ArgumentParser(
837 description='Easy tool to migrate DNS zones into GNS',
838 )
839 parser.add_argument('domain', metavar='domain',
840 type=str,
841 help='Domain to be migrated into GNS')
842 parser.add_argument('-n', '--nameserver',
843 help='Nameserver to use for migrating',
844 required=False)
845 parser.add_argument('-P', '--port',
846 help='Port to use for zone transfer with nameserver',
847 required=False,
848 default=53)
849 parser.add_argument('-t', '--ttl',
850 help='Sets the minimum ttl of records added to GNS',
851 required=False, default=3600)
852 parser.add_argument('-s', '--standalone',
853 help='Run ascension once and not as daemon',
854 action='store_true',
855 required=False, default=False)
856 parser.add_argument('-p', '--public',
857 help='Push records to the public DHT',
858 action='store_true',
859 required=False, default=False)
860 parser.add_argument('-g', '--dryrun',
861 help='Tests if zone is transferrable without changing anything',
862 action='store_true',
863 required=False, default=False)
864 parser.add_argument('-v', '--verbose',
865 help='Enable verbose debugging',
866 action='store_true',
867 required=False, default=False)
868 parser.add_argument('-V', '--version', action='version', version='%(prog)s 0.11.5')
869 args = parser.parse_args()
870 main(args)