From 9345d27d6a4e143d0f2a9205ef31bc8ec938034f Mon Sep 17 00:00:00 2001 From: Duncan X Simpson Date: Tue, 15 Dec 2020 22:36:34 -0700 Subject: [PATCH 01/15] Compare uid not username in create_dirs() --- src/utils/createdirs.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/utils/createdirs.py b/src/utils/createdirs.py index d0590bf4..b56eaa93 100644 --- a/src/utils/createdirs.py +++ b/src/utils/createdirs.py @@ -4,8 +4,6 @@ Create required Onionr directories """ import os import stat -from pwd import getpwuid -from getpass import getuser from . import identifyhome import filepaths @@ -27,10 +25,6 @@ import onionrexceptions home = identifyhome.identify_home() -def find_owner(filename): - return getpwuid(os.stat(filename).st_uid).pw_name - - def create_dirs(): """Create onionr data-related directories in order of the hardcoded list below, @@ -41,7 +35,7 @@ def create_dirs(): if not os.path.exists(path): os.makedirs(path) else: - if getuser() != find_owner(path): + if os.getuid() != os.stat(path).st_uid: raise onionrexceptions.InsecureDirectoryUsage( "Directory " + path + " already exists and is not owned by the same user") @@ -54,4 +48,4 @@ def create_dirs(): try: db() except FileExistsError: - pass \ No newline at end of file + pass From 2dc11303d78dac8df8197ebc7b8a77777bb56083 Mon Sep 17 00:00:00 2001 From: Duncan X Simpson Date: Mon, 14 Dec 2020 23:20:27 -0700 Subject: [PATCH 02/15] Docker improvements - Create run-onionr-node.sh to parse env and supply args to run-onionr-node.py - Dockerfile: - Run onionr by default rather than bash - Run as unprivileged user by default instead of root - Use /app for all code - Specify python 3.7 (3.8 fails to build cffi) - Use apt-get rather than apt (apt's CLI is not stable) - Slight reformatting and consolidation --- .dockerignore | 3 +++ Dockerfile | 7 ++++--- run-onionr-node.sh | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100755 run-onionr-node.sh diff --git a/.dockerignore b/.dockerignore index b45826ec..27001b70 100755 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,6 @@ onionr/data/**/* onionr/data MY-RUN.sh +Dockerfile +.dockerignore +.git diff --git a/Dockerfile b/Dockerfile index c8e93527..12953ac1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,12 @@ FROM python:3.7 +EXPOSE 8080 USER root RUN mkdir /app WORKDIR /app -ENV PORT=8080 -EXPOSE 8080 +ENV ONIONR_DOCKER=true #Install needed packages RUN apt-get update && apt-get install -y tor locales @@ -26,5 +26,6 @@ VOLUME /app/data/ #Default to running as nonprivileged user RUN chmod g=u -R /app USER 1000 +ENV HOME=/app -CMD ["bash", "./onionr.sh"] +CMD ["bash", "./run-onionr-node.sh"] diff --git a/run-onionr-node.sh b/run-onionr-node.sh new file mode 100755 index 00000000..42f37565 --- /dev/null +++ b/run-onionr-node.sh @@ -0,0 +1,51 @@ +#!/bin/sh +set -x +ORIG_ONIONR_RUN_DIR=`pwd` +export ORIG_ONIONR_RUN_DIR +cd "$(dirname "$0")" + +if [[ -n "$ONIONR_DOCKER" ]]; then + [[ -f "/privkey" ]] && privkey_opt="--private-key /privkey" + [[ -n "$ONIONR_ONBOARDING" ]] || ONIONR_ONBOARDING=0 + [[ -n "$ONIONR_OPEN_UI" ]] || ONIONR_OPEN_UI=0 + [[ -n "$ONIONR_RANDOM_LOCALHOST_IP" ]] || ONIONR_RANDOM_LOCALHOST_IP=0 + [[ -n "$ONIONR_BIND_ADDRESS" ]] || ONIONR_BIND_ADDRESS=0.0.0.0 + [[ -n "$ONIONR_PORT" ]] || ONIONR_PORT=8080 +fi + +[[ -n "$ONIONR_PRIVATE_KEY_FILE" ]] && privkey_opt="--private-key $ONIONR_PRIVATE_KEY_FILE" +[[ -n "$ONIONR_USE_BOOTSTRAP_FILE" ]] && bootstrap_opt="--use-bootstrap-file $ONIONR_USE_BOOTSTRAP_FILE" +[[ -n "$ONIONR_SHOW_STATS" ]] && show_stats_opt="--show-stats $ONIONR_SHOW_STATS" +[[ -n "$ONIONR_ONBOARDING" ]] && onboarding_opt="--onboarding $ONIONR_ONBOARDING" +[[ -n "$ONIONR_SECURITY_LEVEL" ]] && security_level_opt="--security-level $ONIONR_SECURITY_LEVEL" +[[ -n "$ONIONR_OPEN_UI" ]] && open_ui_opt="--open-ui $ONIONR_OPEN_UI" +[[ -n "$ONIONR_RANDOM_LOCALHOST_IP" ]] && random_localhost_ip_opt="--random-localhost-ip $ONIONR_RANDOM_LOCALHOST_IP" +[[ -n "$ONIONR_USE_TOR" ]] && use_tor_opt="--use-tor $ONIONR_USE_TOR" +[[ -n "$ONIONR_ANIMATED_BACKGROUND" ]] && animated_background_opt="--animated-background $ONIONR_ANIMATED_BACKGROUND" +[[ -n "$ONIONR_KEEP_LOG" ]] && keep_log_opt="--keep-log-on-exit $ONIONR_KEEP_LOG" +[[ -n "$ONIONR_USE_UPLOAD_MIXING" ]] && use_upload_mixing_opt="--use-upload-mixing $ONIONR_USE_UPLOAD_MIXING" +[[ -n "$ONIONR_DEV_MODE" ]] && dev_mode_opt="--dev-mode $ONIONR_DEV_MODE" +[[ -n "$ONIONR_DISABLE_PLUGIN_LIST" ]] && disable_plugin_list_opt=" --disable-plugin-list $ONIONR_DISABLE_PLUGIN_LIST" +[[ -n "$ONIONR_STORE_PLAINTEXT" ]] && store_plaintext_opt="--store-plaintext $ONIONR_STORE_PLAINTEXT" +[[ -n "$ONIONR_BIND_ADDRESS" ]] && bind_address_opt="--bind-address $ONIONR_BIND_ADDRESS" +[[ -n "$ONIONR_PORT" ]] && port_opt="--port $ONIONR_PORT" + + +python3 run-onionr-node.py \ + $privkey_opt \ + $bootstrap_opt \ + $show_stats_opt \ + $onboarding_opt \ + $security_level_opt \ + $open_ui_opt \ + $random_localhost_ip_opt \ + $use_tor_opt \ + $animated_background_opt \ + $keep_log_opt \ + $use_upload_mixing_opt \ + $dev_mode_opt \ + $disable_plugin_list_opt \ + $store_plaintext_opt \ + $bind_address_opt \ + $port_opt \ + "$@" From 513b758c7a229294d7fd4eb17adf11df777921db Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Fri, 22 Jan 2021 18:55:58 +0000 Subject: [PATCH 03/15] removed process info from run-onionr-node script --- run-onionr-node.py | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/run-onionr-node.py b/run-onionr-node.py index 15fd581e..58415634 100755 --- a/run-onionr-node.py +++ b/run-onionr-node.py @@ -9,10 +9,8 @@ from subprocess import DEVNULL import ujson from psutil import Popen from psutil import Process -import psutil import sys -import curses script_dir = os.path.dirname(os.path.realpath(__file__)) sys.path.append(script_dir + '/src/') @@ -23,36 +21,6 @@ from etc import onionrvalues sub_script = script_dir + '/' + onionrvalues.SCRIPT_NAME -def show_info(p: Process): - def pbar(window): - window.addstr(8, 10, "Onionr statistics") - window.addstr(9, 10, "-" * 17) - curses.curs_set(0) - while True: - threads = p.num_threads() - open_files = len(p.open_files()) - cpu_percent = p.cpu_percent() - block_count = len(blockmetadb.get_block_list()) - for proc in p.children(recursive=True): - threads += proc.num_threads() - cpu_percent += proc.cpu_percent() - try: - open_files += len(proc.open_files()) - except psutil.AccessDenied: - pass - cpu_percent = cpu_percent * 100 - window.addstr(11, 10, f"Threads: {threads}") - window.addstr(10, 10, f"Open files: {open_files}") - window.addstr(12, 10, f"CPU: {cpu_percent}%") - window.addstr(13, 10, f"Blocks: {block_count}") - window.refresh() - sleep(0.5) - sleep(15) - curses.wrapper(pbar) - while True: - sleep(1) - - parser = argparse.ArgumentParser() parser.add_argument( @@ -179,6 +147,4 @@ else: p = Popen([sub_script, 'start'], stdout=DEVNULL) p = p.children()[0] -if args.show_stats: - Thread(target=show_info, args=[p], daemon=True).start() p.wait() From 6b6a69837070d54c51153100c2a5a17433d514d3 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 30 Dec 2020 17:58:21 +0000 Subject: [PATCH 04/15] Bump pip-tools from 5.4.0 to 5.5.0 Bumps [pip-tools](https://github.com/jazzband/pip-tools) from 5.4.0 to 5.5.0. - [Release notes](https://github.com/jazzband/pip-tools/releases) - [Changelog](https://github.com/jazzband/pip-tools/blob/master/CHANGELOG.md) - [Commits](https://github.com/jazzband/pip-tools/compare/5.4.0...5.5.0) Signed-off-by: dependabot-preview[bot] --- requirements-dev.in | 2 +- requirements-dev.txt | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/requirements-dev.in b/requirements-dev.in index 88f9db9b..c1bc5f92 100644 --- a/requirements-dev.in +++ b/requirements-dev.in @@ -1,3 +1,3 @@ pdoc3==0.9.1 -pip-tools==5.4.0 +pip-tools==5.5.0 helium==3.0.5 diff --git a/requirements-dev.txt b/requirements-dev.txt index 8bb6e5e8..3cf414a1 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -56,18 +56,14 @@ markupsafe==1.1.1 \ pdoc3==0.9.1 \ --hash=sha256:e1848d5485b8dd4662272f83bb5f7df4a68e0a5d76c87be30327977777168894 \ # via -r requirements-dev.in -pip-tools==5.4.0 \ - --hash=sha256:a4d3990df2d65961af8b41dacc242e600fdc8a65a2e155ed3d2fc18a5c209f20 \ - --hash=sha256:b73f76fe6464b95e41d595a9c0302c55a786dbc54b63ae776c540c04e31914fb \ +pip-tools==5.5.0 \ + --hash=sha256:10841c1e56c234d610d0466447685b9ea4ee4a2c274f858c0ef3c33d9bd0d985 \ + --hash=sha256:cb0108391366b3ef336185097b3c2c0f3fa115b15098dafbda5e78aef70ea114 \ # via -r requirements-dev.in selenium==3.141.0 \ --hash=sha256:2d7131d7bc5a5b99a2d9b04aaf2612c411b03b8ca1b1ee8d3de5845a9be2cb3c \ --hash=sha256:deaf32b60ad91a4611b98d8002757f29e6f2c2d5fcaf202e1c9ad06d6772300d \ # via helium -six==1.14.0 \ - --hash=sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a \ - --hash=sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c \ - # via pip-tools urllib3==1.25.9 \ --hash=sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527 \ --hash=sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115 \ From cb2e29ad6e6512d8d4a7e0891ba4221631cdc91e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 16 Jan 2021 20:31:06 +0000 Subject: [PATCH 05/15] Bump pdoc3 from 0.9.1 to 0.9.2 Bumps [pdoc3](https://github.com/pdoc3/pdoc) from 0.9.1 to 0.9.2. - [Release notes](https://github.com/pdoc3/pdoc/releases) - [Changelog](https://github.com/pdoc3/pdoc/blob/master/CHANGELOG) - [Commits](https://github.com/pdoc3/pdoc/compare/0.9.1...0.9.2) Signed-off-by: dependabot-preview[bot] --- requirements-dev.in | 2 +- requirements-dev.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements-dev.in b/requirements-dev.in index c1bc5f92..4c0d2439 100644 --- a/requirements-dev.in +++ b/requirements-dev.in @@ -1,3 +1,3 @@ -pdoc3==0.9.1 +pdoc3==0.9.2 pip-tools==5.5.0 helium==3.0.5 diff --git a/requirements-dev.txt b/requirements-dev.txt index 3cf414a1..51fef1db 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -53,8 +53,8 @@ markupsafe==1.1.1 \ --hash=sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7 \ --hash=sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be \ # via mako -pdoc3==0.9.1 \ - --hash=sha256:e1848d5485b8dd4662272f83bb5f7df4a68e0a5d76c87be30327977777168894 \ +pdoc3==0.9.2 \ + --hash=sha256:9df5d931f25f353c69c46819a3bd03ef96dd286f2a70bb1b93a23a781f91faa1 \ # via -r requirements-dev.in pip-tools==5.5.0 \ --hash=sha256:10841c1e56c234d610d0466447685b9ea4ee4a2c274f858c0ef3c33d9bd0d985 \ From 8083489110272347cb841a5ae1a38d18c3597330 Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Fri, 22 Jan 2021 18:55:58 +0000 Subject: [PATCH 06/15] removed process info from run-onionr-node script --- run-onionr-node.py | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/run-onionr-node.py b/run-onionr-node.py index 15fd581e..58415634 100755 --- a/run-onionr-node.py +++ b/run-onionr-node.py @@ -9,10 +9,8 @@ from subprocess import DEVNULL import ujson from psutil import Popen from psutil import Process -import psutil import sys -import curses script_dir = os.path.dirname(os.path.realpath(__file__)) sys.path.append(script_dir + '/src/') @@ -23,36 +21,6 @@ from etc import onionrvalues sub_script = script_dir + '/' + onionrvalues.SCRIPT_NAME -def show_info(p: Process): - def pbar(window): - window.addstr(8, 10, "Onionr statistics") - window.addstr(9, 10, "-" * 17) - curses.curs_set(0) - while True: - threads = p.num_threads() - open_files = len(p.open_files()) - cpu_percent = p.cpu_percent() - block_count = len(blockmetadb.get_block_list()) - for proc in p.children(recursive=True): - threads += proc.num_threads() - cpu_percent += proc.cpu_percent() - try: - open_files += len(proc.open_files()) - except psutil.AccessDenied: - pass - cpu_percent = cpu_percent * 100 - window.addstr(11, 10, f"Threads: {threads}") - window.addstr(10, 10, f"Open files: {open_files}") - window.addstr(12, 10, f"CPU: {cpu_percent}%") - window.addstr(13, 10, f"Blocks: {block_count}") - window.refresh() - sleep(0.5) - sleep(15) - curses.wrapper(pbar) - while True: - sleep(1) - - parser = argparse.ArgumentParser() parser.add_argument( @@ -179,6 +147,4 @@ else: p = Popen([sub_script, 'start'], stdout=DEVNULL) p = p.children()[0] -if args.show_stats: - Thread(target=show_info, args=[p], daemon=True).start() p.wait() From 3a98183fa01cde48efaeae86f14346653b5b6b32 Mon Sep 17 00:00:00 2001 From: Duncan X Simpson Date: Tue, 15 Dec 2020 22:36:34 -0700 Subject: [PATCH 07/15] Compare uid not username in create_dirs() --- src/utils/createdirs.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/utils/createdirs.py b/src/utils/createdirs.py index d0590bf4..b56eaa93 100644 --- a/src/utils/createdirs.py +++ b/src/utils/createdirs.py @@ -4,8 +4,6 @@ Create required Onionr directories """ import os import stat -from pwd import getpwuid -from getpass import getuser from . import identifyhome import filepaths @@ -27,10 +25,6 @@ import onionrexceptions home = identifyhome.identify_home() -def find_owner(filename): - return getpwuid(os.stat(filename).st_uid).pw_name - - def create_dirs(): """Create onionr data-related directories in order of the hardcoded list below, @@ -41,7 +35,7 @@ def create_dirs(): if not os.path.exists(path): os.makedirs(path) else: - if getuser() != find_owner(path): + if os.getuid() != os.stat(path).st_uid: raise onionrexceptions.InsecureDirectoryUsage( "Directory " + path + " already exists and is not owned by the same user") @@ -54,4 +48,4 @@ def create_dirs(): try: db() except FileExistsError: - pass \ No newline at end of file + pass From 133b3ea699e6e721d7563fcec4a5f758016fbe76 Mon Sep 17 00:00:00 2001 From: Duncan X Simpson Date: Mon, 14 Dec 2020 23:20:27 -0700 Subject: [PATCH 08/15] Docker improvements - Create run-onionr-node.sh to parse env and supply args to run-onionr-node.py - Dockerfile: - Run onionr by default rather than bash - Run as unprivileged user by default instead of root - Use /app for all code - Specify python 3.7 (3.8 fails to build cffi) - Use apt-get rather than apt (apt's CLI is not stable) - Slight reformatting and consolidation - do not use devnull in run-onionr-node.py --- .dockerignore | 3 +++ Dockerfile | 7 ++++--- run-onionr-node.py | 7 +++---- run-onionr-node.sh | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 7 deletions(-) create mode 100755 run-onionr-node.sh diff --git a/.dockerignore b/.dockerignore index b45826ec..27001b70 100755 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,6 @@ onionr/data/**/* onionr/data MY-RUN.sh +Dockerfile +.dockerignore +.git diff --git a/Dockerfile b/Dockerfile index c8e93527..12953ac1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,12 @@ FROM python:3.7 +EXPOSE 8080 USER root RUN mkdir /app WORKDIR /app -ENV PORT=8080 -EXPOSE 8080 +ENV ONIONR_DOCKER=true #Install needed packages RUN apt-get update && apt-get install -y tor locales @@ -26,5 +26,6 @@ VOLUME /app/data/ #Default to running as nonprivileged user RUN chmod g=u -R /app USER 1000 +ENV HOME=/app -CMD ["bash", "./onionr.sh"] +CMD ["bash", "./run-onionr-node.sh"] diff --git a/run-onionr-node.py b/run-onionr-node.py index 58415634..96fcdc72 100755 --- a/run-onionr-node.py +++ b/run-onionr-node.py @@ -140,11 +140,10 @@ with open(config_file, 'w') as cf: cf.write(ujson.dumps(config, reject_bytes=False)) if args.open_ui: - p = Popen([sub_script, 'start'], stdout=DEVNULL) + p = Popen([sub_script, 'start']) sleep(2) - Popen([sub_script, 'openhome'], stdout=DEVNULL) + Popen([sub_script, 'openhome']) else: - p = Popen([sub_script, 'start'], stdout=DEVNULL) + p = Popen([sub_script, 'start']) -p = p.children()[0] p.wait() diff --git a/run-onionr-node.sh b/run-onionr-node.sh new file mode 100755 index 00000000..42f37565 --- /dev/null +++ b/run-onionr-node.sh @@ -0,0 +1,51 @@ +#!/bin/sh +set -x +ORIG_ONIONR_RUN_DIR=`pwd` +export ORIG_ONIONR_RUN_DIR +cd "$(dirname "$0")" + +if [[ -n "$ONIONR_DOCKER" ]]; then + [[ -f "/privkey" ]] && privkey_opt="--private-key /privkey" + [[ -n "$ONIONR_ONBOARDING" ]] || ONIONR_ONBOARDING=0 + [[ -n "$ONIONR_OPEN_UI" ]] || ONIONR_OPEN_UI=0 + [[ -n "$ONIONR_RANDOM_LOCALHOST_IP" ]] || ONIONR_RANDOM_LOCALHOST_IP=0 + [[ -n "$ONIONR_BIND_ADDRESS" ]] || ONIONR_BIND_ADDRESS=0.0.0.0 + [[ -n "$ONIONR_PORT" ]] || ONIONR_PORT=8080 +fi + +[[ -n "$ONIONR_PRIVATE_KEY_FILE" ]] && privkey_opt="--private-key $ONIONR_PRIVATE_KEY_FILE" +[[ -n "$ONIONR_USE_BOOTSTRAP_FILE" ]] && bootstrap_opt="--use-bootstrap-file $ONIONR_USE_BOOTSTRAP_FILE" +[[ -n "$ONIONR_SHOW_STATS" ]] && show_stats_opt="--show-stats $ONIONR_SHOW_STATS" +[[ -n "$ONIONR_ONBOARDING" ]] && onboarding_opt="--onboarding $ONIONR_ONBOARDING" +[[ -n "$ONIONR_SECURITY_LEVEL" ]] && security_level_opt="--security-level $ONIONR_SECURITY_LEVEL" +[[ -n "$ONIONR_OPEN_UI" ]] && open_ui_opt="--open-ui $ONIONR_OPEN_UI" +[[ -n "$ONIONR_RANDOM_LOCALHOST_IP" ]] && random_localhost_ip_opt="--random-localhost-ip $ONIONR_RANDOM_LOCALHOST_IP" +[[ -n "$ONIONR_USE_TOR" ]] && use_tor_opt="--use-tor $ONIONR_USE_TOR" +[[ -n "$ONIONR_ANIMATED_BACKGROUND" ]] && animated_background_opt="--animated-background $ONIONR_ANIMATED_BACKGROUND" +[[ -n "$ONIONR_KEEP_LOG" ]] && keep_log_opt="--keep-log-on-exit $ONIONR_KEEP_LOG" +[[ -n "$ONIONR_USE_UPLOAD_MIXING" ]] && use_upload_mixing_opt="--use-upload-mixing $ONIONR_USE_UPLOAD_MIXING" +[[ -n "$ONIONR_DEV_MODE" ]] && dev_mode_opt="--dev-mode $ONIONR_DEV_MODE" +[[ -n "$ONIONR_DISABLE_PLUGIN_LIST" ]] && disable_plugin_list_opt=" --disable-plugin-list $ONIONR_DISABLE_PLUGIN_LIST" +[[ -n "$ONIONR_STORE_PLAINTEXT" ]] && store_plaintext_opt="--store-plaintext $ONIONR_STORE_PLAINTEXT" +[[ -n "$ONIONR_BIND_ADDRESS" ]] && bind_address_opt="--bind-address $ONIONR_BIND_ADDRESS" +[[ -n "$ONIONR_PORT" ]] && port_opt="--port $ONIONR_PORT" + + +python3 run-onionr-node.py \ + $privkey_opt \ + $bootstrap_opt \ + $show_stats_opt \ + $onboarding_opt \ + $security_level_opt \ + $open_ui_opt \ + $random_localhost_ip_opt \ + $use_tor_opt \ + $animated_background_opt \ + $keep_log_opt \ + $use_upload_mixing_opt \ + $dev_mode_opt \ + $disable_plugin_list_opt \ + $store_plaintext_opt \ + $bind_address_opt \ + $port_opt \ + "$@" From 4e96d18396aa4b73b88cc30dc15cf6ac1d0b04f5 Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Fri, 22 Jan 2021 20:36:35 +0000 Subject: [PATCH 09/15] print tor errors to stdout --- src/netcontroller/torcontrol/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/netcontroller/torcontrol/__init__.py b/src/netcontroller/torcontrol/__init__.py index d1b8b3c9..cb9763e6 100644 --- a/src/netcontroller/torcontrol/__init__.py +++ b/src/netcontroller/torcontrol/__init__.py @@ -97,9 +97,11 @@ class NetController: logger.debug(line.decode().replace('\n', '')) else: if 'err' in line.decode(): - logger.error(line.decode().replace('\n', '')) + logger.error( + line.decode().replace('\n', ''), terminal=True) elif 'warn' in line.decode(): - logger.warn(line.decode().replace('\n', '')) + logger.warn( + line.decode().replace('\n', ''), terminal=True) else: logger.debug(line.decode().replace('\n', '')) else: From 7303cf041ed92926d2c36ef1c0a8fd51b4c272af Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Fri, 22 Jan 2021 21:14:34 +0000 Subject: [PATCH 10/15] if binding to 0.0.0.0, don't validate source ip in client api --- src/httpapi/security/client.py | 7 ++++--- src/netcontroller/torcontrol/__init__.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/httpapi/security/client.py b/src/httpapi/security/client.py index 11ee4f99..71393dec 100644 --- a/src/httpapi/security/client.py +++ b/src/httpapi/security/client.py @@ -54,9 +54,10 @@ class ClientAPISecurity: """Validate request has set password & is the correct hostname.""" # For the purpose of preventing DNS rebinding attacks localhost = True - if request.host != '%s:%s' % \ - (client_api.host, client_api.bindPort): - localhost = False + if client_api.host != '0.0.0.0': + if request.host != '%s:%s' % \ + (client_api.host, client_api.bindPort): + localhost = False if not localhost and public_remote_enabled: if request.host not in public_remote_hostnames: diff --git a/src/netcontroller/torcontrol/__init__.py b/src/netcontroller/torcontrol/__init__.py index cb9763e6..2e861e6c 100644 --- a/src/netcontroller/torcontrol/__init__.py +++ b/src/netcontroller/torcontrol/__init__.py @@ -91,7 +91,7 @@ class NetController: if '100' not in line.decode(): logger.info(line.decode().strip(), terminal=True) if 'bootstrapped 100' in line.decode().lower(): - logger.info(line.decode()) + logger.info(line.decode(), terminal=True) break elif 'opening socks listener' in line.decode().lower(): logger.debug(line.decode().replace('\n', '')) From 9306143e4c567758e56828cbf5fefb93ddbee4b4 Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Fri, 22 Jan 2021 21:41:06 +0000 Subject: [PATCH 11/15] dont check hostname if not bound to loopback in client api security --- src/httpapi/security/client.py | 25 ++++++++++++------------ src/netcontroller/torcontrol/__init__.py | 4 ++-- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/httpapi/security/client.py b/src/httpapi/security/client.py index 71393dec..716e9295 100644 --- a/src/httpapi/security/client.py +++ b/src/httpapi/security/client.py @@ -3,6 +3,7 @@ Process incoming requests to the client api server to validate that they are legitimate and not DNSR/XSRF or other local adversary """ +from ipaddress import ip_address import hmac from flask import Blueprint, request, abort, g @@ -53,22 +54,22 @@ class ClientAPISecurity: def validate_request(): """Validate request has set password & is the correct hostname.""" # For the purpose of preventing DNS rebinding attacks - localhost = True - if client_api.host != '0.0.0.0': + if ip_address(client_api.host).is_loopback: + localhost = True if request.host != '%s:%s' % \ (client_api.host, client_api.bindPort): localhost = False - if not localhost and public_remote_enabled: - if request.host not in public_remote_hostnames: - logger.warn( - f'{request.host} not in {public_remote_hostnames}') - abort(403) - else: - if not localhost: - logger.warn( - f'Possible DNS rebinding attack by {request.host}') - abort(403) + if not localhost and public_remote_enabled: + if request.host not in public_remote_hostnames: + logger.warn( + f'{request.host} not in {public_remote_hostnames}') + abort(403) + else: + if not localhost: + logger.warn( + f'Possible DNS rebinding attack by {request.host}') + abort(403) # Add shared objects try: diff --git a/src/netcontroller/torcontrol/__init__.py b/src/netcontroller/torcontrol/__init__.py index 2e861e6c..a5e57495 100644 --- a/src/netcontroller/torcontrol/__init__.py +++ b/src/netcontroller/torcontrol/__init__.py @@ -121,8 +121,8 @@ class NetController: with open(self.dataDir + 'torPid.txt', 'w') as tor_pid_file: tor_pid_file.write(str(tor.pid)) - multiprocessing.Process(target=watchdog.watchdog, - args=[os.getpid(), tor.pid], daemon=True).start() + #multiprocessing.Process(target=watchdog.watchdog, + # args=[os.getpid(), tor.pid], daemon=True).start() logger.info('Finished starting Tor.', terminal=True) From 7fa320cfc5f0f1abd95581779298bfc5ec3fe09f Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Fri, 22 Jan 2021 22:58:12 +0000 Subject: [PATCH 12/15] don't print version command to devnull in run script either added docker and VPS documentation --- docs/docker.md | 28 ++++++++++++++++++++++++++++ docs/vps-cloud-guide.md | 18 ++++++++++++++++++ run-onionr-node.py | 3 ++- 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 docs/docker.md create mode 100644 docs/vps-cloud-guide.md diff --git a/docs/docker.md b/docs/docker.md new file mode 100644 index 00000000..f350bd3d --- /dev/null +++ b/docs/docker.md @@ -0,0 +1,28 @@ +# Running Onionr in Docker + +A Dockerfile is included in the root directory of Onionr. + +In Docker version 20.10 (and probably others), there is a strange bug where Onionr must be run with -it or stdout will be garbled and it may hang. + +## Clone and build the image + +`$ git clone https://git.voidnet.tech/kev/onionr/` +`$ cd onionr` +`$ sudo docker build -t onionr .` + + +## Run Onionr + +`$ sudo docker run -it -p 8080:8080 onionr` + +Onionr will be accessible over any network interface by default, so make sure to either change the entry point bind-address argument or set a firewall rule. + +That said, Onionr does protect it's interface by default with a web token, which will be shown in stdout. + +**However, anyone who can access the port may be able to see what Onionr sites you have saved and potentially deanonymize your node** + +## View the UI + +Visit the address and port for the machine Onionr is running on, for example: http://192.168.1.5:8080/# + +If you want a secure connection to the interface, either use a proxy such as nginx or caddy, or use [SSH tunneling](./vps-cloud-guide.md). diff --git a/docs/vps-cloud-guide.md b/docs/vps-cloud-guide.md new file mode 100644 index 00000000..ff931f46 --- /dev/null +++ b/docs/vps-cloud-guide.md @@ -0,0 +1,18 @@ +# Cloud/Server Hosting Onionr + +Cloud hosting is not the recommended way to run Onionr, as it gives the cloud provider control over your data. + +That said, it is quite useful and by running a 24/7 Onionr node you contribute to the network's health. + +![https://cock.li/img/cockbox.png](https://cockbox.org/?r=12) + +[Cockbox](https://cockbox.org/?r=12) is the recommended provider, as they do not demand personal information and accept Monero. This is an affiliate link, which gives us a commission at no expense or complication to you. + + +1. [Install Onionr like normal](./basic-onionr-user-guide.pdf) or [from Docker](./docker.md) +2. Run with specific host and port to bind to: `$ ./run-onionr-node.py --bind-address 0.0.0.0 --port 8080` +3. Get the web security token: `$ ./onionr.sh get-web` (the long string at the end of the URL) +4. [Configure Firefox for SSH tunneling](https://web.archive.org/web/20210123034529/https://gist.github.com/brentjanderson/6ed800376e53746d2d28ba7b6bdcdc12). `Set network.proxy.allow_hijacking_localhost` to true in about:config + + +Disable random host binding in config (general.security.random_bind_ip = false) if you have Onionr auto start. You may also want to disable deniable block inserts. \ No newline at end of file diff --git a/run-onionr-node.py b/run-onionr-node.py index 96fcdc72..2419c72f 100755 --- a/run-onionr-node.py +++ b/run-onionr-node.py @@ -79,8 +79,9 @@ parser.add_argument( args = parser.parse_args() -p = Popen([sub_script, 'version'], stdout=DEVNULL) +p = Popen([sub_script, 'version']) p.wait() +print("Configuring Onionr before starting daemon") from filepaths import config_file, keys_file from coredb import blockmetadb import onionrcrypto From 914b505dfa5e27a866b8fc5d4a342374484cd24d Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Sat, 23 Jan 2021 05:41:36 +0000 Subject: [PATCH 13/15] added remote ui plugin --- scripts/remote-ui.py | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100755 scripts/remote-ui.py diff --git a/scripts/remote-ui.py b/scripts/remote-ui.py new file mode 100755 index 00000000..b63540c3 --- /dev/null +++ b/scripts/remote-ui.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 + +"""Craft and send requests to the local client API""" + + +import sys +import os +import time +from threading import Thread +if not os.path.exists('onionr.sh'): + os.chdir('../') +sys.path.append("src/") + +import filepaths +import config +config.reload() + +with open(filepaths.private_API_host_file, 'r') as host: + hostname = host.read() + +port = config.get("client.client.port", 0) +if not port: + print("Could not get port for Onionr UI. Try again") + sys.exit(1) +torrc = f""" +HiddenServiceDir remote-onionr-hs +HiddenServicePort 80 {hostname}:{port} +""" + +with open("remote-onionr-torrc", "w") as torrc_f: + torrc_f.write(torrc) + + +def show_onion(): + while True: + time.sleep(1) + try: + with open("remote-onionr-hs/hostname", "r") as f: + o = f.read() + print("UI Onion (Keep secret):", o) + config.set("ui.public_remote_enabled", True) + config.set("ui.public_remote_hosts", [o]) + config.save() + break + except FileNotFoundError: + pass + +Thread(target=show_onion, daemon=True).start() + +os.system("tor -f remote-onionr-torrc") From 735220d8da138ca4aeb9650c6d4c33922e487858 Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Sat, 23 Jan 2021 19:21:02 +0000 Subject: [PATCH 14/15] update runtime result --- tests/runtime-result.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/runtime-result.txt b/tests/runtime-result.txt index e1b6872c..5b6a44e2 100644 --- a/tests/runtime-result.txt +++ b/tests/runtime-result.txt @@ -1 +1 @@ -1610736254 \ No newline at end of file +1611429331 \ No newline at end of file From 3e17cf7c0b86e968dd22f937cd71bb11c96ed4ea Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Sun, 24 Jan 2021 07:16:44 +0000 Subject: [PATCH 15/15] added papers list dev doc --- docs/dev/selected-papers.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 docs/dev/selected-papers.md diff --git a/docs/dev/selected-papers.md b/docs/dev/selected-papers.md new file mode 100644 index 00000000..52bc6e25 --- /dev/null +++ b/docs/dev/selected-papers.md @@ -0,0 +1,9 @@ +# Interesting papers related to Onionr development + +A paper being listed here is not end-all-be-all endorsement of every detail inside. + +* [Epidemic Routing for Partially-Connected Ad Hoc Networks](https://web.archive.org/web/20200208074703/http://issg.cs.duke.edu/epidemic/epidemic.pdf) +* [Freenet: A distibuted decentralized information storage and retrieval system](https://freenetproject.org/assets/papers/ddisrs.pdf) +* [Protecting Free Expression Online with Freenet](https://freenetproject.org/assets/papers/ddisrs.pdf) +* [Bitmessage: A Peer‐to‐Peer Message Authentication and Delivery System](https://archive.org/details/BitmessageWhitepaper/) +* [MuON: Epidemic based Mutual Anonymity](https://web.archive.org/web/20060901153544/http://www.csl.mtu.edu/cs6461/www/Reading/MuON_ICNP2005.pdf)