Compare commits

...

10 Commits

Author SHA1 Message Date
Kevin Froman ff1d7b4982 don't print version command to devnull in run script either 1 year ago
Kevin Froman 11490afee7 don't print version command to devnull in run script either 1 year ago
Kevin Froman 1ed1eec153 don't print version command to devnull in run script either 1 year ago
Kevin Froman f31888e541 don't print version command to devnull in run script either 1 year ago
Kevin Froman 51e97cd877 don't use tor watchdog for now 1 year ago
Kevin Froman 98bdc96699 dont check hostname if not bound to loopback in client api security 1 year ago
Kevin Froman 45b691a06a if binding to 0.0.0.0, don't validate source ip in client api 1 year ago
Kevin Froman b1441e8c10 print tor errors to stdout 1 year ago
Duncan X Simpson 62f405425c Docker improvements 1 year ago
Duncan X Simpson 5a3b679a0d Compare uid not username in create_dirs() 1 year ago
  1. 3
      .dockerignore
  2. 7
      Dockerfile
  3. 13
      run-onionr-node.py
  4. 51
      run-onionr-node.sh
  5. 32
      src/httpapi/security/client.py
  6. 12
      src/netcontroller/torcontrol/__init__.py
  7. 10
      src/utils/createdirs.py

3
.dockerignore

@ -1,3 +1,6 @@
onionr/data/**/*
onionr/data
MY-RUN.sh
Dockerfile
.dockerignore
.git

7
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"]

13
run-onionr-node.py

@ -79,8 +79,10 @@ parser.add_argument(
args = parser.parse_args()
p = Popen([sub_script, 'version'], stdout=DEVNULL)
p.wait()
#p = Popen([sub_script, 'version'])
#p.communicate()
os.system(f"{sub_script} version")
print("Configuring Onionr before starting daemon")
from filepaths import config_file, keys_file
from coredb import blockmetadb
import onionrcrypto
@ -140,11 +142,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()

51
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 \
"$@"

32
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,21 +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 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 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)
# Add shared objects
try:

12
src/netcontroller/torcontrol/__init__.py

@ -91,15 +91,17 @@ 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', ''))
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:
@ -119,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)

10
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
pass

Loading…
Cancel
Save