Use alpine and build tor from source

This commit is contained in:
Christophe Mehay 2016-09-23 23:57:58 +02:00
parent 5463744e49
commit 38ba81f386
8 changed files with 71 additions and 23 deletions

1
.dockerignore Normal file
View file

@ -0,0 +1 @@
keys/

View file

@ -1,20 +1,37 @@
FROM debian:jessie FROM alpine
ENV DEBIAN_FRONTEND=noninteractive
ENV HOME /var/lib/tor ENV HOME /var/lib/tor
ENV TOR_VERSION 0.2.8.8
RUN apt-get update && apt-get install --no-install-recommends -y \ RUN apk add --no-cache git libevent-dev openssl-dev gcc make automake ca-certificates autoconf musl-dev && \
tor \ mkdir -p /usr/local/src/ && \
python3-pip git clone https://git.torproject.org/tor.git /usr/local/src/tor && \
cd /usr/local/src/tor && \
RUN pip3 install pyentrypoint==0.3.8 git checkout tor-${TOR_VERSION} && \
./autogen.sh && ./configure --disable-asciidoc && make && make install && \
cd .. && \
rm -rf tor && \
apk add --no-cache python3 python3-dev && \
python3 -m ensurepip && \
rm -r /usr/lib/python*/ensurepip && \
pip3 install --upgrade pip setuptools pycrypto && \
apk del git libevent-dev openssl-dev make automake python3-dev gcc autoconf musl-dev && \
apk add --no-cache libevent openssl
ADD assets/entrypoint-config.yml / ADD assets/entrypoint-config.yml /
ADD assets/onions /usr/local/src/onions ADD assets/onions /usr/local/src/onions
ADD assets/torrc /etc/tor/torrc ADD assets/torrc /var/local/tor/torrc.tpl
RUN mkdir -p /etc/tor/
RUN pip install pyentrypoint==0.3.8
RUN cd /usr/local/src/onions && python3 setup.py install RUN cd /usr/local/src/onions && python3 setup.py install
RUN mkdir -p ${HOME}/.tor && \
addgroup -S -g 107 tor && \
adduser -S -G tor -u 104 -H -h ${HOME} tor
VOLUME ["/var/lib/tor/hidden_service/"] VOLUME ["/var/lib/tor/hidden_service/"]
ENTRYPOINT ["pyentrypoint"] ENTRYPOINT ["pyentrypoint"]

View file

@ -1,7 +1,7 @@
command: tor command: tor
user: debian-tor user: tor
group: debian-tor group: tor
secret_env: secret_env:
- '*_KEY' - '*_KEY'
@ -11,8 +11,8 @@ pre_conf_commands:
- onions --setup-hosts - onions --setup-hosts
post_conf_commands: post_conf_commands:
- timeout 3s tor > /dev/null || true - timeout -t 3 tor > /dev/null || true
- onions - onions
- chown -R debian-tor:debian-tor $HOME - chown -R tor:tor $HOME
debug: false debug: false

View file

@ -12,11 +12,31 @@ import argparse
from jinja2 import Environment from jinja2 import Environment
from jinja2 import FileSystemLoader from jinja2 import FileSystemLoader
import socket
from Crypto.PublicKey import RSA
from hashlib import sha1
from base64 import b32encode
class Setup(object): class Setup(object):
hidden_service_dir = "/var/lib/tor/hidden_service/" hidden_service_dir = "/var/lib/tor/hidden_service/"
torrc = '/etc/tor/torrc' torrc = '/usr/local/etc/tor/torrc'
torrc_template = '/var/local/tor/torrc.tpl'
def onion_url_gen(self, key):
"Get onion url from private key"
# Convert private RSA to public DER
priv = RSA.importKey(key.strip())
der = priv.publickey().exportKey("DER")
# hash key, keep first half of sha1, base32 encode
onion = b32encode(sha1(der[22:]).digest()[:10])
return '{onion}.onion'.format(onion=onion.decode().lower())
def _add_host(self, host): def _add_host(self, host):
if host not in self.setup: if host not in self.setup:
@ -31,6 +51,10 @@ class Setup(object):
if port not in self.setup[host]['ports']: if port not in self.setup[host]['ports']:
self.setup[host]['ports'].append(port) self.setup[host]['ports'].append(port)
def _get_ip(self):
for host in self.setup:
self.setup[host]['ip'] = str(socket.gethostbyname(host))
def _get_key(self, host, key): def _get_key(self, host, key):
self._add_host(host) self._add_host(host)
assert len(key) > 800 assert len(key) > 800
@ -68,12 +92,17 @@ class Setup(object):
if 'key' in conf: if 'key' in conf:
serv_dir = os.path.join(self.hidden_service_dir, link) serv_dir = os.path.join(self.hidden_service_dir, link)
os.makedirs(serv_dir, exist_ok=True) os.makedirs(serv_dir, exist_ok=True)
os.chmod(serv_dir, 0o700)
with open(os.path.join(serv_dir, 'private_key'), 'w') as f: with open(os.path.join(serv_dir, 'private_key'), 'w') as f:
f.write(conf['key']) f.write(conf['key'])
os.fchmod(f.fileno(), 0o600)
with open(os.path.join(serv_dir, 'hostname'), 'w') as f:
f.write(self.onion_url_gen(conf['key']))
def _set_conf(self): def _set_conf(self):
env = Environment(loader=FileSystemLoader('/')) env = Environment(loader=FileSystemLoader('/'))
temp = env.get_template(self.torrc) temp = env.get_template(self.torrc_template)
with open(self.torrc, mode='w') as f: with open(self.torrc, mode='w') as f:
f.write(temp.render(setup=self.setup, f.write(temp.render(setup=self.setup,
env=os.environ)) env=os.environ))
@ -83,6 +112,7 @@ class Setup(object):
try: try:
self._get_setup_from_env() self._get_setup_from_env()
self._get_setup_from_links() self._get_setup_from_links()
self._get_ip()
self._set_keys() self._set_keys()
self._set_conf() self._set_conf()
except: except:

View file

@ -6,7 +6,7 @@ from setuptools import setup
setup( setup(
name='onions', name='onions',
version='0.1', version='0.2',
packages=find_packages(), packages=find_packages(),
@ -31,6 +31,9 @@ setup(
"Topic :: System :: Installation/Setup", "Topic :: System :: Installation/Setup",
], ],
install_requires=['pyentrypoint',
'Jinja2>=2.8',
'pycrypto',],
entry_points={ entry_points={
'console_scripts': [ 'console_scripts': [

View file

@ -2,7 +2,7 @@
HiddenServiceDir /var/lib/tor/hidden_service/{{service}} HiddenServiceDir /var/lib/tor/hidden_service/{{service}}
{% for ports in conf['ports'] %} {% for ports in conf['ports'] %}
# PORT {{service}} {{ports[0]}} # PORT {{service}} {{ports[0]}}
HiddenServicePort {{ports[0]}} {{service}}:{{ports[1]}} HiddenServicePort {{ports[0]}} {{conf['ip']}}:{{ports[1]}}
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}

View file

@ -5,7 +5,6 @@ version: "2"
services: services:
tor: tor:
image: goldy/tor-hidden-service image: goldy/tor-hidden-service
# or
build: . build: .
links: links:
- hello - hello

View file

@ -2,8 +2,6 @@
tor: tor:
image: goldy/tor-hidden-service image: goldy/tor-hidden-service
# or
build: .
links: links:
- hello - hello
- world - world