From a9d0524ccc2192cbca42fddc12132e8543a98d21 Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Mon, 2 Nov 2020 23:47:38 +0000 Subject: [PATCH] + added sandbox script * handle sigterm --- sandboxed-onionr.py | 33 +++++++++++++++++++++ src/lan/discover.py | 2 ++ src/lan/getip.py | 21 ++++++++----- src/onionrcommands/daemonlaunch/__init__.py | 16 ++++++++-- 4 files changed, 62 insertions(+), 10 deletions(-) create mode 100644 sandboxed-onionr.py diff --git a/sandboxed-onionr.py b/sandboxed-onionr.py new file mode 100644 index 00000000..bb85ebe0 --- /dev/null +++ b/sandboxed-onionr.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 + +import os, sys +import tempfile, shutil +import stat + +env_var = "firejailed-onionr" + +def copytree(src, dst, symlinks=False, ignore=None): + for item in os.listdir(src): + if item in (".git", ".vscode", ".github"): + continue + s = os.path.join(src, item) + d = os.path.join(dst, item) + if os.path.isdir(s): + shutil.copytree(s, d, symlinks, ignore) + else: + shutil.copy2(s, d) + +env_var = "firejailed-onionr" +directory = os.path.dirname(os.path.realpath(sys.argv[0])) + +if not os.getenv(env_var): + temp_dir = tempfile.mkdtemp() + print(temp_dir) + copytree(directory, temp_dir) + os.system(f"firejail --env={env_var}={temp_dir} --private={temp_dir} python3 ./sandboxed-onionr.py") + sys.exit(0) + +os.system(f"python3 -m pip install -r ./requirements.txt --user") +os.system(f"./onionr.sh start &") + + diff --git a/src/lan/discover.py b/src/lan/discover.py index aae3e1f8..42827c4f 100644 --- a/src/lan/discover.py +++ b/src/lan/discover.py @@ -72,6 +72,8 @@ def advertise_service(specific_ips=None): MULTICAST_TTL = 3 ips = best_ip + if not ips: + return sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, MULTICAST_TTL) diff --git a/src/lan/getip.py b/src/lan/getip.py index 23f41c64..0031734b 100644 --- a/src/lan/getip.py +++ b/src/lan/getip.py @@ -6,6 +6,8 @@ from ipaddress import IPv4Address from psutil import net_if_addrs from socket import AF_INET + +import logger """ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,13 +26,18 @@ from socket import AF_INET lan_ips = [] # https://psutil.readthedocs.io/en/latest/#psutil.net_if_addrs -for interface in net_if_addrs().keys(): - for address in net_if_addrs()[interface]: - # Don't see benefit in ipv6, so just check for v4 addresses - if address[0] == AF_INET: - # Mark the address for use in LAN if it is a private address - if IPv4Address(address[1]).is_private and not IPv4Address(address[1]).is_loopback: - lan_ips.append(address[1]) +def _get_lan_ips(): + for interface in net_if_addrs().keys(): + for address in net_if_addrs()[interface]: + # Don't see benefit in ipv6, so just check for v4 addresses + if address[0] == AF_INET: + # Mark the address for use in LAN if it is a private address + if IPv4Address(address[1]).is_private and not IPv4Address(address[1]).is_loopback: + lan_ips.append(address[1]) +try: + _get_lan_ips() +except OSError: + logger.warn("Could not identify LAN ips due to OSError.") # These are more likely to be actual local subnets rather than VPNs for ip in lan_ips: diff --git a/src/onionrcommands/daemonlaunch/__init__.py b/src/onionrcommands/daemonlaunch/__init__.py index 383f57d2..193eb54e 100755 --- a/src/onionrcommands/daemonlaunch/__init__.py +++ b/src/onionrcommands/daemonlaunch/__init__.py @@ -5,6 +5,7 @@ launch the api servers and communicator import os import sys import platform +import signal from threading import Thread from stem.connection import IncorrectPassword @@ -117,14 +118,22 @@ def _setup_online_mode( cleanup.delete_run_files() sys.exit(1) if len(net.myID) > 0 and security_level == 0: - logger.debug('Started .onion service: %s' % - (logger.colors.underline + net.myID)) + logger.debug( + 'Started .onion service: %s' % + (logger.colors.underline + net.myID)) else: logger.debug('.onion service disabled') def daemon(): """Start Onionr's primary threads for communicator, API server, node, and LAN.""" + + def _handle_sig_term(signum, frame): + logger.info( + "Received sigterm, shutting down gracefully", terminal=True) + localcommand.local_command('/shutdownclean') + signal.signal(signal.SIGTERM, _handle_sig_term) + # Determine if Onionr is in offline mode. # When offline, Onionr can only use LAN and disk transport offline_mode = config.get('general.offline_mode', False) @@ -184,7 +193,8 @@ def daemon(): _setup_online_mode(use_existing_tor, net, security_level) _show_info_messages() - + logger.info( + "Onionr daemon is running under " + str(os.getpid()), terminal=True) events.event('init', threaded=False) events.event('daemon_start') if config.get('transports.lan', True):