diff --git a/Dockerfile b/Dockerfile
index 546152db..c8e93527 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,28 +1,30 @@
-FROM python
+FROM python:3.7
-#Base settings
-ENV HOME /root
+USER root
+
+RUN mkdir /app
+WORKDIR /app
+
+ENV PORT=8080
+EXPOSE 8080
#Install needed packages
-RUN apt update && apt install -y tor locales
+RUN apt-get update && apt-get install -y tor locales
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
locale-gen
-ENV LANG en_US.UTF-8
-ENV LANGUAGE en_US:en
-ENV LC_ALL en_US.UTF-8
+ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8
-WORKDIR /srv/
-ADD ./requirements.txt /srv/requirements.txt
+ADD ./requirements.txt /app/requirements.txt
RUN pip3 install --require-hashes -r requirements.txt
-WORKDIR /root/
#Add Onionr source
-COPY . /root/
-VOLUME /root/data/
+COPY . /app/
-#Set upstart command
-CMD bash
+VOLUME /app/data/
-#Expose ports
-EXPOSE 8080
+#Default to running as nonprivileged user
+RUN chmod g=u -R /app
+USER 1000
+
+CMD ["bash", "./onionr.sh"]
diff --git a/README.md b/README.md
index 5eea66c5..86d265b3 100644
--- a/README.md
+++ b/README.md
@@ -70,7 +70,7 @@ Not yet usable:
## Watch the talk from BSidesPDX 2019
-
+
diff --git a/run-onionr-node.py b/run-onionr-node.py
index 2c8f3431..15fd581e 100755
--- a/run-onionr-node.py
+++ b/run-onionr-node.py
@@ -55,6 +55,12 @@ def show_info(p: Process):
parser = argparse.ArgumentParser()
+parser.add_argument(
+ "--bind-address", help="Address to bind to. Be very careful with non-loopback",
+ type=str, default="")
+parser.add_argument(
+ "--port", help="Port to bind to, must be available and possible",
+ type=int, default=0)
parser.add_argument(
"--use-bootstrap-file", help="Use bootstrap node list file",
type=int, default=1)
@@ -129,6 +135,13 @@ config['general']['dev_mode'] = False
config['general']['store_plaintext_blocks'] = True
config['general']['use_bootstrap_list'] = True
config['transports']['tor'] = True
+config['general']['bind_port'] = 0 # client api server port
+config['general']['bind_address'] = '' # client api server address
+
+if args.bind_address:
+ config['general']['bind_address'] = args.bind_address
+if args.port:
+ config['client']['client']['port'] = args.port
if not args.use_bootstrap_file:
config['general']['use_bootstrap_list'] = False
diff --git a/src/apiservers/private/__init__.py b/src/apiservers/private/__init__.py
index 3bc0df3a..657c30b7 100644
--- a/src/apiservers/private/__init__.py
+++ b/src/apiservers/private/__init__.py
@@ -50,13 +50,20 @@ class PrivateAPI:
self.startTime = epoch.get_epoch()
app = flask.Flask(__name__)
+
+
bind_port = int(config.get('client.client.port', 59496))
self.bindPort = bind_port
self.clientToken = config.get('client.webpassword')
- self.host = httpapi.apiutils.setbindip.set_bind_IP(
- private_API_host_file)
+ if config.get('general.bind_address'):
+ with open(private_API_host_file, 'w') as bindFile:
+ bindFile.write(config.get('general.bind_address'))
+ self.host = config.get('general.bind_address')
+ else:
+ self.host = httpapi.apiutils.setbindip.set_bind_IP(
+ private_API_host_file)
logger.info('Running api on %s:%s' % (self.host, self.bindPort))
self.httpServer = ''
diff --git a/static-data/default_config.json b/static-data/default_config.json
index 2a788eb3..dcad2e50 100755
--- a/static-data/default_config.json
+++ b/static-data/default_config.json
@@ -8,6 +8,7 @@
"general": {
"allow_public_api_dns_rebinding": false,
"announce_node": true,
+ "bind_address": "",
"dev_mode": false,
"display_header": true,
"ephemeral_tunnels": false,
diff --git a/tests/test_default_config_json.py b/tests/test_default_config_json.py
index b50db4b2..2678b13c 100644
--- a/tests/test_default_config_json.py
+++ b/tests/test_default_config_json.py
@@ -24,6 +24,7 @@ class OnionrConfig(unittest.TestCase):
self.assertEqual(conf['allocations']['disk'], 1073741824)
self.assertEqual(conf['allocations']['disk'], 1073741824)
self.assertEqual(conf['general']['announce_node'], True)
+ self.assertEqual(conf['general']['bind_address'], '')
self.assertEqual(conf['general']['dev_mode'], False)
self.assertEqual(conf['general']['display_header'], True)
self.assertEqual(conf['general']['ephemeral_tunnels'], False)