Merge branch 'master' into integrate-new-blocks
This commit is contained in:
commit
003718db04
@ -1,3 +1,6 @@
|
|||||||
onionr/data/**/*
|
onionr/data/**/*
|
||||||
onionr/data
|
onionr/data
|
||||||
MY-RUN.sh
|
MY-RUN.sh
|
||||||
|
Dockerfile
|
||||||
|
.dockerignore
|
||||||
|
.git
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
FROM python:3.7
|
FROM python:3.7
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
RUN mkdir /app
|
RUN mkdir /app
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
ENV PORT=8080
|
ENV ONIONR_DOCKER=true
|
||||||
EXPOSE 8080
|
|
||||||
|
|
||||||
#Install needed packages
|
#Install needed packages
|
||||||
RUN apt-get update && apt-get install -y tor locales
|
RUN apt-get update && apt-get install -y tor locales
|
||||||
@ -26,5 +26,6 @@ VOLUME /app/data/
|
|||||||
#Default to running as nonprivileged user
|
#Default to running as nonprivileged user
|
||||||
RUN chmod g=u -R /app
|
RUN chmod g=u -R /app
|
||||||
USER 1000
|
USER 1000
|
||||||
|
ENV HOME=/app
|
||||||
|
|
||||||
CMD ["bash", "./onionr.sh"]
|
CMD ["bash", "./run-onionr-node.sh"]
|
||||||
|
9
docs/dev/selected-papers.md
Normal file
9
docs/dev/selected-papers.md
Normal file
@ -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)
|
28
docs/docker.md
Normal file
28
docs/docker.md
Normal file
@ -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/#<long-token-taken-from-stdout>
|
||||||
|
|
||||||
|
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).
|
18
docs/vps-cloud-guide.md
Normal file
18
docs/vps-cloud-guide.md
Normal file
@ -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.
|
@ -9,10 +9,8 @@ from subprocess import DEVNULL
|
|||||||
import ujson
|
import ujson
|
||||||
from psutil import Popen
|
from psutil import Popen
|
||||||
from psutil import Process
|
from psutil import Process
|
||||||
import psutil
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import curses
|
|
||||||
|
|
||||||
script_dir = os.path.dirname(os.path.realpath(__file__))
|
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||||
sys.path.append(script_dir + '/src/')
|
sys.path.append(script_dir + '/src/')
|
||||||
@ -23,36 +21,6 @@ from etc import onionrvalues
|
|||||||
sub_script = script_dir + '/' + onionrvalues.SCRIPT_NAME
|
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 = argparse.ArgumentParser()
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
@ -111,8 +79,9 @@ parser.add_argument(
|
|||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
p = Popen([sub_script, 'version'], stdout=DEVNULL)
|
p = Popen([sub_script, 'version'])
|
||||||
p.wait()
|
p.wait()
|
||||||
|
print("Configuring Onionr before starting daemon")
|
||||||
from filepaths import config_file, keys_file
|
from filepaths import config_file, keys_file
|
||||||
from coredb import blockmetadb
|
from coredb import blockmetadb
|
||||||
import onionrcrypto
|
import onionrcrypto
|
||||||
@ -172,13 +141,10 @@ with open(config_file, 'w') as cf:
|
|||||||
cf.write(ujson.dumps(config, reject_bytes=False))
|
cf.write(ujson.dumps(config, reject_bytes=False))
|
||||||
|
|
||||||
if args.open_ui:
|
if args.open_ui:
|
||||||
p = Popen([sub_script, 'start'], stdout=DEVNULL)
|
p = Popen([sub_script, 'start'])
|
||||||
sleep(2)
|
sleep(2)
|
||||||
Popen([sub_script, 'openhome'], stdout=DEVNULL)
|
Popen([sub_script, 'openhome'])
|
||||||
else:
|
else:
|
||||||
p = Popen([sub_script, 'start'], stdout=DEVNULL)
|
p = Popen([sub_script, 'start'])
|
||||||
|
|
||||||
p = p.children()[0]
|
|
||||||
if args.show_stats:
|
|
||||||
Thread(target=show_info, args=[p], daemon=True).start()
|
|
||||||
p.wait()
|
p.wait()
|
||||||
|
51
run-onionr-node.sh
Executable file
51
run-onionr-node.sh
Executable file
@ -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 \
|
||||||
|
"$@"
|
50
scripts/remote-ui.py
Executable file
50
scripts/remote-ui.py
Executable file
@ -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")
|
@ -3,6 +3,7 @@
|
|||||||
Process incoming requests to the client api server to validate
|
Process incoming requests to the client api server to validate
|
||||||
that they are legitimate and not DNSR/XSRF or other local adversary
|
that they are legitimate and not DNSR/XSRF or other local adversary
|
||||||
"""
|
"""
|
||||||
|
from ipaddress import ip_address
|
||||||
import hmac
|
import hmac
|
||||||
|
|
||||||
from flask import Blueprint, request, abort, g
|
from flask import Blueprint, request, abort, g
|
||||||
@ -53,6 +54,7 @@ class ClientAPISecurity:
|
|||||||
def validate_request():
|
def validate_request():
|
||||||
"""Validate request has set password & is the correct hostname."""
|
"""Validate request has set password & is the correct hostname."""
|
||||||
# For the purpose of preventing DNS rebinding attacks
|
# For the purpose of preventing DNS rebinding attacks
|
||||||
|
if ip_address(client_api.host).is_loopback:
|
||||||
localhost = True
|
localhost = True
|
||||||
if request.host != '%s:%s' % \
|
if request.host != '%s:%s' % \
|
||||||
(client_api.host, client_api.bindPort):
|
(client_api.host, client_api.bindPort):
|
||||||
|
@ -91,15 +91,17 @@ class NetController:
|
|||||||
if '100' not in line.decode():
|
if '100' not in line.decode():
|
||||||
logger.info(line.decode().strip(), terminal=True)
|
logger.info(line.decode().strip(), terminal=True)
|
||||||
if 'bootstrapped 100' in line.decode().lower():
|
if 'bootstrapped 100' in line.decode().lower():
|
||||||
logger.info(line.decode())
|
logger.info(line.decode(), terminal=True)
|
||||||
break
|
break
|
||||||
elif 'opening socks listener' in line.decode().lower():
|
elif 'opening socks listener' in line.decode().lower():
|
||||||
logger.debug(line.decode().replace('\n', ''))
|
logger.debug(line.decode().replace('\n', ''))
|
||||||
else:
|
else:
|
||||||
if 'err' in line.decode():
|
if 'err' in line.decode():
|
||||||
logger.error(line.decode().replace('\n', ''))
|
logger.error(
|
||||||
|
line.decode().replace('\n', ''), terminal=True)
|
||||||
elif 'warn' in line.decode():
|
elif 'warn' in line.decode():
|
||||||
logger.warn(line.decode().replace('\n', ''))
|
logger.warn(
|
||||||
|
line.decode().replace('\n', ''), terminal=True)
|
||||||
else:
|
else:
|
||||||
logger.debug(line.decode().replace('\n', ''))
|
logger.debug(line.decode().replace('\n', ''))
|
||||||
else:
|
else:
|
||||||
@ -119,8 +121,8 @@ class NetController:
|
|||||||
with open(self.dataDir + 'torPid.txt', 'w') as tor_pid_file:
|
with open(self.dataDir + 'torPid.txt', 'w') as tor_pid_file:
|
||||||
tor_pid_file.write(str(tor.pid))
|
tor_pid_file.write(str(tor.pid))
|
||||||
|
|
||||||
multiprocessing.Process(target=watchdog.watchdog,
|
#multiprocessing.Process(target=watchdog.watchdog,
|
||||||
args=[os.getpid(), tor.pid], daemon=True).start()
|
# args=[os.getpid(), tor.pid], daemon=True).start()
|
||||||
|
|
||||||
logger.info('Finished starting Tor.', terminal=True)
|
logger.info('Finished starting Tor.', terminal=True)
|
||||||
|
|
||||||
|
@ -4,8 +4,6 @@ Create required Onionr directories
|
|||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import stat
|
import stat
|
||||||
from pwd import getpwuid
|
|
||||||
from getpass import getuser
|
|
||||||
|
|
||||||
from . import identifyhome
|
from . import identifyhome
|
||||||
import filepaths
|
import filepaths
|
||||||
@ -27,10 +25,6 @@ import onionrexceptions
|
|||||||
home = identifyhome.identify_home()
|
home = identifyhome.identify_home()
|
||||||
|
|
||||||
|
|
||||||
def find_owner(filename):
|
|
||||||
return getpwuid(os.stat(filename).st_uid).pw_name
|
|
||||||
|
|
||||||
|
|
||||||
def create_dirs():
|
def create_dirs():
|
||||||
"""Create onionr data-related directories in
|
"""Create onionr data-related directories in
|
||||||
order of the hardcoded list below,
|
order of the hardcoded list below,
|
||||||
@ -42,7 +36,7 @@ def create_dirs():
|
|||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
os.makedirs(path)
|
os.makedirs(path)
|
||||||
else:
|
else:
|
||||||
if getuser() != find_owner(path):
|
if os.getuid() != os.stat(path).st_uid:
|
||||||
raise onionrexceptions.InsecureDirectoryUsage(
|
raise onionrexceptions.InsecureDirectoryUsage(
|
||||||
"Directory " + path +
|
"Directory " + path +
|
||||||
" already exists and is not owned by the same user")
|
" already exists and is not owned by the same user")
|
||||||
|
@ -1 +1 @@
|
|||||||
1610736254
|
1611429331
|
Loading…
Reference in New Issue
Block a user