commit 72effbd4ed90c004b216e8085d59d8dd827d3328
parent 03360197bbb34602309fed8b3633a9fc4d8d1c63
Author: rexxnor <rexxnor+gnunet@brief.li>
Date: Wed, 6 Mar 2019 20:37:53 +0100
added DNSCurve, added CIscript, build deb and manpage, improved tests
Diffstat:
13 files changed, 380 insertions(+), 78 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -96,4 +96,9 @@ ENV/
# mkdocs documentation
/site
.idea/
+
+# bind stuff
+managed-keys.bind
managed-keys.bind.jnl
+ascension/test/managed-keys.bind
+ascension/test/managed-keys.bind.jnl
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
@@ -0,0 +1,29 @@
+---
+image: debian
+
+stages:
+ - build_deb
+
+run-build_deb:
+ stage: build_deb
+ script:
+ - apt update
+ - apt install -y python-all python3-stdeb git
+ - python3 setup.py --command-package=stdeb.command sdist_dsc
+ - cd deb_dist/*/ || exit
+ - cp ../../helpers/ascension.1 debian/ascension.1
+ - echo "debian/ascension.1" > debian/python3-ascension.manpages
+ - dh_installman
+ - dpkg-buildpackage -rfakeroot -uc -us
+ - cd ../../ || exit
+ - apt install -y ./deb_dist/python3-ascension*.deb
+ - ascension -h
+ - bash helpers/gnunet-installer-0.11-debian.sh Production
+ - apt install -y bind9 dnsutils procps
+ - gnunet-arm -Esq
+ - cd ascension/test/
+ - bash test_ascension_simple.sh
+ - gnunet-arm -e
+ artifacts:
+ paths:
+ - deb_dist/python3-ascension*.deb
diff --git a/ascension/ascension.py b/ascension/ascension.py
@@ -20,22 +20,24 @@
# Author rexxnor
"""
Usage:
- ascension <domain> [-d] [-p]
- ascension <domain> <port> [-d] [-p]
- ascension <domain> -n <transferns> [-d] [-p]
- ascension <domain> -n <transferns> <port> [-d] [-p]
+ ascension <domain> [-d] [-p] [-s]
+ ascension <domain> <port> [-d] [-p] [-s]
+ ascension <domain> -n <transferns> [-d] [-p] [-s]
+ ascension <domain> -n <transferns> <port> [-d] [-p] [-s]
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
- -p --public Make records public on the DHT
- -d --debug Enable debugging
- -h --help Show this screen.
- -v --version Show version.
+ <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
+ -s --standalone Run ascension once
+ -d --debug Enable debugging
+ -h --help Show this screen.
+ -v --version Show version.
"""
# imports
@@ -208,15 +210,6 @@ class Ascender():
# execute thing to run on item
label, listofrdatasets = labelrecords
- # TODO Add the not-in-bailiwick case
- # subzones = label.split('.')
- # elif len(subzones) > 1:
- # ttl = cls.soa[1]
- # cls.create_zone_hierarchy(subzones, ttl)
- # label = subzones[0]
- # subdomains = ".".join(subzones[1:])
- # domain = "%s.%s" % (subdomains, cls.domain)
-
for rdataset in listofrdatasets:
for record in rdataset:
rdtype = dns.rdatatype.to_text(record.rdtype)
@@ -275,6 +268,21 @@ class Ascender():
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']:
+ print("zone exists in GNS, adding it to local store")
+ cls.add_pkey_record_to_zone(pkey[11:], cls.domain,
+ label, ttl)
+ return
+
# Create one thread
thread = threading.Thread(target=worker)
thread.start()
@@ -370,11 +378,6 @@ class Ascender():
value = value[:-1]
elif rdtype == 'NS':
nameserver = str(record)
- if nameserver[0:2] == 'uz5':
- logging.info("zone has a dnscurve record")
- # TODO extract public key from NS record (dnscurve)
- # encoded_pkey = nameserver[2:].split('.')[0]
- # pkey =
if value[-1] == ".":
value = value[:-1]
else:
@@ -611,25 +614,25 @@ class Ascender():
: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
"""
debug = " ".join([GNUNET_NAMESTORE_COMMAND,
'-z', domain,
'-a', '-n', label,
'-t', 'PKEY',
'-V', pkey,
- '-e', "%s" % ttl])
+ '-e', "%ds" % ttl])
ret = sp.run([GNUNET_NAMESTORE_COMMAND,
'-z', domain,
'-a', '-n', label,
'-t', 'PKEY',
'-V', pkey,
- '-e', "%s" % ttl])
+ '-e', "%ds" % ttl])
logging.info("executed command: %s", debug)
if ret.returncode != 0:
logging.warning("failed to add PKEY record %s to %s",
label, domain)
-
@classmethod
def create_zone_hierarchy(cls, labels, ttl):
"""
@@ -657,6 +660,7 @@ def main():
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'))
# Change logging severity to debug
if debug:
@@ -682,6 +686,8 @@ def main():
logging.info("Finished migrating of the zone %s", 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)
diff --git a/ascension/test/basic_named.conf b/ascension/test/basic_named.conf
@@ -8,10 +8,6 @@ options {
// Add this for no IPv4:
// listen-on { none; };
- allow-recursion { 127.0.0.1; };
- allow-transfer { 127.0.0.1; };
- allow-update { none; };
-
version none;
hostname none;
server-id none;
diff --git a/ascension/test/gnunet.zone b/ascension/test/gnunet.zone
@@ -6,7 +6,9 @@ $TTL 3600
604800 ; Expire
3600 ) ; Negative Cache TTL
@ IN NS ns1.gnunet.org.
+@ IN NS gns--pkey--7h4hfww26fmdamt243dhssens2w5qevphbm9bhv54sz3cz1053ng.gnunet.org.
@ IN A 127.0.0.1
+gns--pkey--7h4hfww26fmdamt243dhssens2w5qevphbm9bhv54sz3cz1053ng IN A 0.0.0.0
www IN A 127.0.0.1
owncloud IN A 127.0.0.1
nextcloud IN A 127.0.0.1
diff --git a/ascension/test/managed-keys.bind b/ascension/test/managed-keys.bind
@@ -1,33 +0,0 @@
-$ORIGIN .
-$TTL 0 ; 0 seconds
-@ IN SOA . . (
- 24 ; serial
- 0 ; refresh (0 seconds)
- 0 ; retry (0 seconds)
- 0 ; expire (0 seconds)
- 0 ; minimum (0 seconds)
- )
- KEYDATA 20181113222352 20181020181422 19700101000000 257 3 8 (
- AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQ
- bSEW0O8gcCjFFVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh
- /RStIoO8g0NfnfL2MTJRkxoXbfDaUeVPQuYEhg37NZWA
- JQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaDX6RS6CXp
- oY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3
- LQpzW5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGO
- Yl7OyQdXfZ57relSQageu+ipAdTTJ25AsRTAoub8ONGc
- LmqrAmRLKBP1dfwhYB4N7knNnulqQxA+Uk1ihz0=
- ) ; KSK; alg = RSASHA256; key id = 19036
- ; next refresh: Tue, 13 Nov 2018 22:23:52 GMT
- ; trusted since: Sat, 20 Oct 2018 18:14:22 GMT
- KEYDATA 20181113222352 20181020181422 19700101000000 257 3 8 (
- AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTO
- iW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN
- 7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5
- LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8
- efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7
- pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLY
- A4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws
- 9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU=
- ) ; KSK; alg = RSASHA256; key id = 20326
- ; next refresh: Tue, 13 Nov 2018 22:23:52 GMT
- ; trusted since: Sat, 20 Oct 2018 18:14:22 GMT
diff --git a/ascension/test/managed-keys.bind.jnl b/ascension/test/managed-keys.bind.jnl
Binary files differ.
diff --git a/ascension/test/test_ascension_simple.sh b/ascension/test/test_ascension_simple.sh
@@ -12,8 +12,7 @@
# Shutdown named
function cleanup {
pkill named
- gnunet-identity -D gnunet
- gnunet-identity -D org
+ gnunet-identity -D gnunet.org
}
# Check for required packages
@@ -28,6 +27,17 @@ if ! [ -x "$(command -v ascension)" ]; then
exit 1
fi
+if ! [ -x "$(command -v gnunet-arm)" ]; then
+ echo 'gnunet is not installed' >&2
+ exit 1
+fi
+
+gnunet-arm -T 1s -I -q 2>&1 /dev/null
+if [ "$?" -ne 0 ]; then
+ echo "The gnunet peer is not running" >&2
+ exit 1
+fi
+
# Start named with a simple zone
named -c basic_named.conf -p 5000
@@ -40,7 +50,7 @@ if [ "$?" -ne 0 ]; then
fi
# Let ascension run on gnunet.org test domain
-ascension gnunet.org -ns 127.0.0.1 -p 5000
+ascension gnunet.org -n 127.0.0.1 -p 5000 -s -d
if [ "$?" -ne 0 ]; then
echo "ascension failed adding the records!"
cleanup
@@ -64,23 +74,23 @@ function checkfailimp {
}
# TESTING explicit records
-gnunet-gns -t CNAME -u asdf.gnunet
+gnunet-gns -t CNAME -u asdf.gnunet.org
checkfailexp
-gnunet-gns -t AAAA -u foo.gnunet
+gnunet-gns -t AAAA -u foo.gnunet.org
checkfailexp
-gnunet-gns -t A -u mail.gnunet
+gnunet-gns -t A -u mail.gnunet.org
checkfailexp
-gnunet-gns -t A -u ns1.gnunet
+gnunet-gns -t A -u ns1.gnunet.org
checkfailexp
-gnunet-gns -t A -u ns2.gnunet
+gnunet-gns -t A -u ns2.gnunet.org
checkfailexp
gnunet-gns -t A -u ns2.gnunet.org
checkfailexp
-gnunet-gns -t MX -u mail.gnunet
+gnunet-gns -t MX -u mail.gnunet.org
checkfailexp
-gnunet-gns -t A -u nextcloud.gnunet
+gnunet-gns -t A -u nextcloud.gnunet.org
checkfailexp
-gnunet-gns -t SOA -u @.gnunet
+gnunet-gns -t SOA -u @.gnunet.org
checkfailexp
# cleanup if we get this far
diff --git a/ascension/test/test_ascension_sophisticated.sh b/ascension/test/test_ascension_sophisticated.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+# Copyright (C) 2019 rexxnor
+# License AGPLv3+: GNU AGPL version 3 or later <https://www.gnu.org/licenses/agpl.html>
+# This is free software: you are free to change and redistribute it.
+# There is NO WARRANTY, to the extent permitted by law.
+#
+# Returns 1 on basic error
+# Returns 2 on explicit test case errors
+# Returns 3 on implicit test case errors
+
+# Shutdown named
+function cleanup {
+ pkill named
+ gnunet-identity -D gnunet.org
+}
+
+# Check for required packages
+if ! [ -x "$(command -v named)" ]; then
+ echo 'bind/named is not installed' >&2
+ exit 1
+fi
+
+if ! [ -x "$(command -v ascension)" ]; then
+ echo 'ascension is not installed' >&2
+ exit 1
+fi
+
+if ! [ -x "$(command -v gnunet-arm)" ]; then
+ echo 'gnunet is not installed' >&2
+ exit 1
+fi
+
+gnunet-arm -T 1s -I
+if [ "$?" -ne 0 ]; then
+ echo "The gnunet peer is not running" >&2
+ exit 1
+fi
+
+# Get the hostname to simulate external host
+myhostname=$(echo -n "$(hostname)")
+
+# Start named with a simple zone
+named -c basic_named.conf -p 5000
+
+# Check if domain resolves
+nslookup gnunet.org "$myhostname" -port=5000
+if [ "$?" -ne 0 ]; then
+ echo "Something went wrong with named"
+ cleanup
+ exit 1
+fi
+
+# Let ascension run on gnunet.org test domain
+ascension gnunet.org -n "$myhostname" -p 5000 -s -d
+if [ "$?" -ne 0 ]; then
+ echo "ascension failed adding the records!"
+ cleanup
+ exit 1
+fi
+
+function checkfailexp {
+ if [ "$?" -ne 0 ]; then
+ echo "required record not present"
+ cleanup
+ exit 2
+ fi
+}
+
+function checkfailimp {
+ if [ "$?" -ne 0 ]; then
+ echo "implied record not present"
+ cleanup
+ exit 3
+ fi
+}
+
+# TESTING explicit records
+gnunet-gns -t PKEY -u @.gnunet.org
+checkfailexp
+
+# cleanup if we get this far
+cleanup
+
+# finish
+echo "All records added successfully!!"
diff --git a/helpers/ascension.1 b/helpers/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/helpers/ciscript.sh b/helpers/ciscript.sh
@@ -0,0 +1,21 @@
+# Copyright (C) 2019 rexxnor
+# License AGPLv3+: GNU AGPL version 3 or later <https://www.gnu.org/licenses/agpl.html>
+# This is free software: you are free to change and redistribute it.
+# There is NO WARRANTY, to the extent permitted by law.
+apt update
+apt install -y python-all python3-stdeb git
+python3 setup.py --command-package=stdeb.command sdist_dsc
+cd deb_dist/*/ || exit
+cp ../../helpers/ascension.1 debian/ascension.1
+echo "debian/ascension.1" > debian/python3-ascension.manpages
+dh_installman
+dpkg-buildpackage -rfakeroot -uc -us
+cd ../../ || exit
+apt install -y ./deb_dist/python3-ascension*.deb
+ascension -h
+bash helpers/gnunet-installer-0.11-debian.sh Production
+apt install -y bind9 dnsutils procps
+gnunet-arm -Esq
+cd ascension/test/
+bash test_ascension_simple.sh
+gnunet-arm -e
diff --git a/helpers/gnunet-installer-0.11-debian.sh b/helpers/gnunet-installer-0.11-debian.sh
@@ -0,0 +1,138 @@
+#!/bin/bash
+# Written by Torsten Grothoff
+# Licensed under GPLv3+
+# Updated by rexxnor
+# SPDX-License-Identifier: GPL3.0-or-later
+
+export bold="\e[1m"
+export dim="\e[2m"
+export underlined="\e[4m"
+export blink="\e[5m"
+export inverted="\e[7m"
+export hidden="\e[8m"
+export resetall="\e[0m" #All
+export resetbold="\e[21m" #Bold
+export resetdim="\e[22m" #Dim
+export resetunderlined="\e[24m" #Underlined
+export resetblink="\e[25m" #Blink
+export resetinverted="\e[27m" #Inverted
+export resethidden="\e[28m" #Hidden
+export defaultcolor="\e[39m"
+export black="\e[30m"
+export red="\e[31m"
+export green="\e[32m"
+export yellow="\e[33m"
+export blue="\e[34m"
+export magenta="\e[35m"
+export cyan="\e[36m"
+export lightgray="\e[37m"
+export darkgray="\e[90m"
+export lightred="\e[91m"
+export lightgreen="\e[92m"
+export lightyellow="\e[93m"
+export lightblue="\e[94m"
+export lightmagenta="\e[95m"
+export lightcyan="\e[96m"
+export white="\e[97m"
+export default
+export blackbg="\e[30m"
+export redbg="\e[31m"
+export greenbg="\e[42m"
+export yellowbg="\e[43m"
+export bluebg="\e[44m"
+export magentabg="\e[45m"
+export cyanbg="\e[46m"
+export lightgraybg="\e[47m"
+export darkgraybg="\e[100m"
+export lightredbg="\e[101m"
+export lightgreenbg="\e[102m"
+export lightyellowbg="\e[103m"
+export lightbluebg="\e[104m"
+export lightmagentabg="\e[105m"
+export lightcyanbg="\e[106m"
+export whitebg="\e[107m"
+function errorhandler {
+ errorcode=$?
+ if [[ "$errorcode" != "0" ]]; then
+ echo "An Error has Occured [Error Code: $errorcode]."
+ if [[ "$errorcode" == "127" ]]; then
+ echo "Potential Fatal Error; Exiting"
+ exit 127
+ fi
+ fi
+}
+if [[ "$UID" -ne 0 ]]; then
+ if [[ "$1" == "--ignore-root-check" ]]; then
+ echo "Warning: You are not running this file as root; As such, this installer will probabally not work. Expect Errors"
+ else
+ echo "You must run this program as root that way it can work\nIf you are sure you want to continue without root[will most likely not work]; run this file with --ignore-root-check"
+ exit 1
+ fi
+fi
+apt install --yes --fix-missing git libtool autoconf autopoint build-essential libgcrypt-dev libidn11-dev zlib1g-dev libunistring-dev libglpk-dev miniupnpc libextractor-dev libjansson-dev libcurl4-gnutls-dev libsqlite3-dev openssl libnss3-tools
+apt install --yes git libtool autoconf autopoint \
+build-essential libgcrypt-dev libidn11-dev zlib1g-dev \
+libunistring-dev libglpk-dev miniupnpc libextractor-dev \
+libjansson-dev libcurl4-gnutls-dev libsqlite3-dev openssl \
+libnss3-tools libmicrohttpd-dev libgnutls28-dev libp11-kit-dev libp11-kit0 dialog
+errorhandler
+mkdir ~/gnunet_installation
+cd ~/gnunet_installation
+git clone --depth 1 https://gnunet.org/git/gnunet.git
+git clone --depth 1 https://gnunet.org/git/libmicrohttpd.git
+cd ~/gnunet_installation/libmicrohttpd
+autoreconf -fi
+apt install -y libgnutls28-dev
+./configure --disable-doc --prefix=/opt/libmicrohttpd
+make -j$(nproc || echo -n 1)
+make install
+#
+if [[ "$1" == "Production" || "$1" == "Development" ]]; then
+ echo "$1" > ./result.txt
+fi
+
+if [[ ! -f ./result.txt ]]; then
+ dialog --menu Production\ Or\ Developement? -1 -1 2 Production 1 Development 2 2> ./result.txt
+fi
+if [[ `cat ./result.txt` == Production ]]; then
+ cd ~/gnunet_installation/gnunet
+ ./bootstrap
+ export GNUNET_PREFIX=/usr
+ ./configure --prefix=$GNUNET_PREFIX --disable-documentation --with-microhttpd=/opt/libmicrohttpd
+ addgroup gnunetdns
+ adduser --system --group --disabled-login --home /var/lib/gnunet gnunet
+ make -j$(nproc || echo -n 1)
+ make install
+else
+ if [[ `cat ./result.txt` == Developement ]]; then
+ cd ~/gnunet_installation/gnunet
+ ./bootstrap
+ export GNUNET_PREFIX=/usr
+ export CFLAGS="-g -Wall -O0"
+ ./configure --prefix=$GNUNET_PREFIX --disable-documentation --enable-logging=verbose --with-microhttpd=/opt/libmicrohttpd
+ make -j$(nproc || echo -n 1)
+ make install
+ fi
+fi
+rm ~/gnunet_installation/libmicrohttpd/result.txt
+touch ~/.config/gnunet.conf
+echo -e "Associating ${green}gnunet://${resetall} with gnunet"
+for n in `cat /etc/passwd | awk '{print $6}' FS=:`; do
+ dir=`echo $n/.local/share/applications`
+ echo "[Added Associations]
+ x-scheme-handler/gnunet=gnunet.desktop" >> $dir/mimeapps.list
+ echo "[Desktop Entry]
+Version=1.0
+Type=Application
+Exec=sh -c \"gnunet-uri $@\"
+Icon=/usr/share/gnunet/gnunet-logo-color.png
+StartupNotify=false
+Terminal=false
+Categories=Internet
+MimeType=x-scheme-handler/gnunet
+Name=GNUNet
+Comment=GNUNet Protocol Executer
+GenericName=GNUNet Protocol Executer[Created By Gnunet Installer; by TStudios]" > $dir/gnunet.desktop
+ chmod 644 gnunet.desktop
+done
+echo -e "To start GNUNet Services: ${green}gnunet-arm -s${resetall}\nTo view GNUNet Services: ${green}gnunet-arm -I${resetall}\nTo Stop GNUNet Services: ${green}gnunet-arm -e${resetall}\n\n${red}NOTE: This GNUNet Installation Might only be available as ${green}ROOT${resetall}\n${lightgreen}For more info: https://gnunet.org/en/tutorial-debian9.html${resetall}"
diff --git a/setup.py b/setup.py
@@ -45,8 +45,6 @@ setuptools.setup(
},
install_requires=[
'coverage',
- 'daemon',
- 'daemonize',
'dnspython',
'docopt',
'mock',