Add tests for Vanguards setup

pull/67/head
Christophe Mehay 4 years ago
parent 0334d7eb6b
commit 5b6e87c6e3

@ -45,8 +45,6 @@ COPY assets/vanguards.conf.tpl /var/local/tor/vanguards.conf.tpl
ENV VANGUARDS_CONFIG /etc/tor/vanguards.conf ENV VANGUARDS_CONFIG /etc/tor/vanguards.conf
RUN apk add socat
VOLUME ["/var/lib/tor/hidden_service/"] VOLUME ["/var/lib/tor/hidden_service/"]
ENTRYPOINT ["pyentrypoint"] ENTRYPOINT ["pyentrypoint"]

@ -192,9 +192,6 @@ Use these environment variables to enable control port
For critical hidden services, it's possible to increase security with [`Vanguards`](https://github.com/mikeperry-tor/vanguards) tool. For critical hidden services, it's possible to increase security with [`Vanguards`](https://github.com/mikeperry-tor/vanguards) tool.
#### Settings
It's not possible yet to custom all the settings using environment variable, but it's possible to mount configuration file to `/etc/tor/vanguards.conf` to custom `vanguards` settings.
### Run in the same container ### Run in the same container
@ -213,6 +210,22 @@ Use the same environment variable as `tor` to configure `vangards` (see upper).
* `TOR_CONTROL_PORT` * `TOR_CONTROL_PORT`
* `TOR_CONTROL_PASSWORD` * `TOR_CONTROL_PASSWORD`
##### more settings
Use `VANGUARDS_EXTRA_OPTIONS` environment variable to change any settings.
The following settings cannot me changer with this variable:
- `control_ip`:
- use `TOR_CONTROL_PORT`
- `control_port`:
- use `TOR_CONTROL_PORT`
- `control_socket`:
- use `TOR_CONTROL_PORT`
- `control_pass`:
- use `TOR_CONTROL_PASSWORD`
- `state_file`:
- use `VANGUARDS_STATE_FILE`
# Legacy deprecated doc # Legacy deprecated doc
> **WARNING**: ALL THE DOC BELLOW IS LEGACY, IT'S STILL WORKING BUT IT'S NOT RECOMMENDED ANYMORE AND COULD BE DROPPED IN FUTURE RELEASES. > **WARNING**: ALL THE DOC BELLOW IS LEGACY, IT'S STILL WORKING BUT IT'S NOT RECOMMENDED ANYMORE AND COULD BE DROPPED IN FUTURE RELEASES.

@ -29,7 +29,7 @@ ExitRelay 0
{% if onion.enable_control_port %} {% if onion.enable_control_port %}
{% if onion.control_socket %} {% if onion.control_socket %}
ControlPort unix:{{onion.control_socket}} ControlPort {{onion.control_socket}}
{% endif %} {% endif %}
{% if not onion.control_socket %} {% if not onion.control_socket %}
{% if onion.control_ip_binding.version() == 4 %} {% if onion.control_ip_binding.version() == 4 %}

@ -1,12 +1,7 @@
## Example vanguards configuration file
#
# The values in this file are the defaults. You do not need to specify
# options in your config file unless you wish to change the defaults.
## Global options ## Global options
[Global] [Global]
{% if env.get('TOR_CONTROL_PORT', '').startswith('unix:') %} {% if (env.get('TOR_CONTROL_PORT', '')).startswith('unix:') %}
{% set _, unix_path = env['TOR_CONTROL_PORT'].split(':', 1) %} {% set _, unix_path = env['TOR_CONTROL_PORT'].split(':', 1) %}
{% elif ':' in env.get('TOR_CONTROL_PORT', '') %} {% elif ':' in env.get('TOR_CONTROL_PORT', '') %}
{% set host, port = env['TOR_CONTROL_PORT'].split(':', 1) %} {% set host, port = env['TOR_CONTROL_PORT'].split(':', 1) %}
@ -14,18 +9,34 @@
{% set host = env.get('TOR_CONTROL_PORT') %} {% set host = env.get('TOR_CONTROL_PORT') %}
{% endif %} {% endif %}
# IP address that the Tor control port is listening on:
control_ip = {{ host or '' }} control_ip = {{ host or '' }}
# TCP port the control port is listening on:
control_port = {{ port or 9051 }} control_port = {{ port or 9051 }}
# If set, use this filesystem control socket instead of IP+Port:
control_socket = {{ unix_path or '' }} control_socket = {{ unix_path or '' }}
# If set, use this as the control port password:
control_pass = {{ env.get('TOR_CONTROL_PASSWORD', '') }} control_pass = {{ env.get('TOR_CONTROL_PASSWORD', '') }}
state_file = {{ env.get('VANGUARDS_STATE_FILE', '/run/tor/data/vanguards.state') }}
{% if 'VANGUARDS_EXTRA_OPTIONS' in env %}
{% set extra_conf = ConfigParser().read_string(env['VANGUARDS_EXTRA_OPTIONS']) %}
{% if 'Global' in extra_conf %}
{% for key, val in extra_conf['Global'].items() %}
{{key}} = {{val}}
{% endfor %}
{% set _ = extra_conf.pop('Global') %}
{% endif %}
{{ extra_conf.to_string() }}
{% endif %}
{#
## Example vanguards configuration file
#
# All values below are default values and won't appear in final config file
# Original here: https://github.com/mikeperry-tor/vanguards/blob/master/vanguards-example.conf
#
# Enable/disable active vanguard update of layer2 and layer3 guards # Enable/disable active vanguard update of layer2 and layer3 guards
enable_vanguards = True enable_vanguards = True
@ -33,7 +44,7 @@ enable_vanguards = True
enable_bandguards = True enable_bandguards = True
# Enable/disable circuit build timeout analysis (informational only): # Enable/disable circuit build timeout analysis (informational only):
enable_cbtverify = True enable_cbtverify = False
# Enable/disable checks on Rendezvous Point overuse attacks: # Enable/disable checks on Rendezvous Point overuse attacks:
enable_rendguard = True enable_rendguard = True
@ -51,10 +62,6 @@ loglevel = NOTICE
# If specified, log to this file instead of stdout: # If specified, log to this file instead of stdout:
logfile = logfile =
# Name of state file (with absolute path, or relative to current directory):
state_file = {{ env.get('VANGUARDS_STATE_FILE', '/run/tor/data/vanguards.state') }}
## Vanguards: layer1, layer2, and layer3 rotation params. ## Vanguards: layer1, layer2, and layer3 rotation params.
[Vanguards] [Vanguards]
@ -135,3 +142,4 @@ rend_use_relay_start_count = 100
# Divide all relay counts by two once the total circuit count hits this many: # Divide all relay counts by two once the total circuit count hits this many:
rend_use_scale_at_count = 20000 rend_use_scale_at_count = 20000
#}

@ -12,6 +12,12 @@ services:
# Set controle port password (optionnal) # Set controle port password (optionnal)
TOR_CONTROL_PASSWORD: something_secret TOR_CONTROL_PASSWORD: something_secret
# You can change any options here, excepted control_* ones and state_file
VANGUARDS_EXTRA_OPTIONS: |
[Global]
enable_cbtverify = True
loglevel = DEBUG
HELLO_TOR_SERVICE_HOSTS: '80:hello:80' HELLO_TOR_SERVICE_HOSTS: '80:hello:80'
HELLO_TOR_SERVICE_VERSION: '3' HELLO_TOR_SERVICE_VERSION: '3'

@ -6,7 +6,15 @@ services:
tor: tor:
image: goldy/tor-hidden-service:$CUR_TAG image: goldy/tor-hidden-service:$CUR_TAG
environment: environment:
# Enable Vanguards like this
TOR_ENABLE_VANGUARDS: 'true' TOR_ENABLE_VANGUARDS: 'true'
# You can change any options here, excepted control_* ones
VANGUARDS_EXTRA_OPTIONS: |
[Global]
enable_cbtverify = True
loglevel = DEBUG
HELLO_TOR_SERVICE_HOSTS: '80:hello:80' HELLO_TOR_SERVICE_HOSTS: '80:hello:80'
HELLO_TOR_SERVICE_VERSION: '3' HELLO_TOR_SERVICE_VERSION: '3'

@ -14,6 +14,7 @@ from jinja2 import Environment
from jinja2 import FileSystemLoader from jinja2 import FileSystemLoader
from pyentrypoint import DockerLinks from pyentrypoint import DockerLinks
from pyentrypoint.config import envtobool from pyentrypoint.config import envtobool
from pyentrypoint.configparser import ConfigParser
from .Service import Service from .Service import Service
from .Service import ServicesGroup from .Service import ServicesGroup
@ -64,7 +65,7 @@ class Setup(object):
control_port = os.environ['TOR_CONTROL_PORT'] control_port = os.environ['TOR_CONTROL_PORT']
try: try:
if control_port.startswith('unix:'): if control_port.startswith('unix:'):
_, self.control_socket = control_port.split(':') self.control_socket = control_port
return return
self.control_socket = None self.control_socket = None
if ':' in control_port: if ':' in control_port:
@ -97,7 +98,7 @@ class Setup(object):
return return
self.enable_control_port = True self.enable_control_port = True
self.enable_vanguards = True self.enable_vanguards = True
os.environ['TOR_CONTROL_PORT'] = self.control_socket os.environ.setdefault('TOR_CONTROL_PORT', self.control_socket)
self.kill_tor_on_vanguard_exit = envtobool( self.kill_tor_on_vanguard_exit = envtobool(
'VANGUARD_KILL_TOR_ON_EXIT', 'VANGUARD_KILL_TOR_ON_EXIT',
True True
@ -300,6 +301,7 @@ class Setup(object):
temp = env.get_template(self.vanguards_template) temp = env.get_template(self.vanguards_template)
with open(self.vanguards_conf, mode='w') as f: with open(self.vanguards_conf, mode='w') as f:
f.write(temp.render(env=os.environ, f.write(temp.render(env=os.environ,
ConfigParser=ConfigParser,
envtobool=envtobool)) envtobool=envtobool))
def run_vanguards(self): def run_vanguards(self):

93
poetry.lock generated

@ -12,7 +12,7 @@ description = "An abstract syntax tree for Python with inference support."
name = "astroid" name = "astroid"
optional = false optional = false
python-versions = ">=3.5" python-versions = ">=3.5"
version = "2.4.1" version = "2.4.2"
[package.dependencies] [package.dependencies]
lazy-object-proxy = ">=1.4.0,<1.5.0" lazy-object-proxy = ">=1.4.0,<1.5.0"
@ -275,7 +275,7 @@ description = "More routines for operating on iterables, beyond itertools"
name = "more-itertools" name = "more-itertools"
optional = false optional = false
python-versions = ">=3.5" python-versions = ">=3.5"
version = "8.3.0" version = "8.4.0"
[[package]] [[package]]
category = "dev" category = "dev"
@ -346,7 +346,7 @@ description = "A framework for managing and maintaining multi-language pre-commi
name = "pre-commit" name = "pre-commit"
optional = false optional = false
python-versions = ">=3.6.1" python-versions = ">=3.6.1"
version = "2.4.0" version = "2.5.1"
[package.dependencies] [package.dependencies]
cfgv = ">=2.0.0" cfgv = ">=2.0.0"
@ -426,13 +426,14 @@ description = "pyentrypoint manages entrypoints in Docker containers."
name = "pyentrypoint" name = "pyentrypoint"
optional = false optional = false
python-versions = ">=3.6.1,<4.0.0" python-versions = ">=3.6.1,<4.0.0"
version = "0.7.3" version = "0.7.4"
[package.dependencies] [package.dependencies]
colorlog = ">=4.1,<5.0" colorlog = ">=4.1,<5.0"
jinja2 = ">=2.11,<3.0" jinja2 = ">=2.11,<3.0"
pyyaml = ">=5.3,<6.0" pyyaml = ">=5.3,<6.0"
six = ">=1.14,<2.0" six = ">=1.14,<2.0"
toml = ">=0.10.1,<0.11.0"
watchdog = ">=0.10,<0.11" watchdog = ">=0.10,<0.11"
[[package]] [[package]]
@ -457,7 +458,7 @@ description = "python code static checker"
name = "pylint" name = "pylint"
optional = false optional = false
python-versions = ">=3.5.*" python-versions = ">=3.5.*"
version = "2.5.2" version = "2.5.3"
[package.dependencies] [package.dependencies]
astroid = ">=2.4.0,<=2.5" astroid = ">=2.4.0,<=2.5"
@ -525,7 +526,7 @@ description = "Alternative regular expression module, to replace re."
name = "regex" name = "regex"
optional = false optional = false
python-versions = "*" python-versions = "*"
version = "2020.6.7" version = "2020.6.8"
[[package]] [[package]]
category = "main" category = "main"
@ -544,7 +545,7 @@ python-versions = "*"
version = "1.8.0" version = "1.8.0"
[[package]] [[package]]
category = "dev" category = "main"
description = "Python Library for Tom's Obvious, Minimal Language" description = "Python Library for Tom's Obvious, Minimal Language"
name = "toml" name = "toml"
optional = false optional = false
@ -604,7 +605,7 @@ description = "Virtual Python Environment builder"
name = "virtualenv" name = "virtualenv"
optional = false optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
version = "20.0.21" version = "20.0.23"
[package.dependencies] [package.dependencies]
appdirs = ">=1.4.3,<2" appdirs = ">=1.4.3,<2"
@ -618,7 +619,7 @@ version = ">=0.12,<2"
[package.extras] [package.extras]
docs = ["sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)", "proselint (>=0.10.2)"] docs = ["sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)", "proselint (>=0.10.2)"]
testing = ["pytest (>=4)", "coverage (>=5)", "coverage-enable-subprocess (>=1)", "pytest-xdist (>=1.31.0)", "pytest-mock (>=2)", "pytest-env (>=0.6.2)", "pytest-randomly (>=1)", "pytest-timeout", "packaging (>=20.0)", "xonsh (>=0.9.16)"] testing = ["pytest (>=4)", "coverage (>=5)", "coverage-enable-subprocess (>=1)", "pytest-xdist (>=1.31.0)", "pytest-mock (>=2)", "pytest-env (>=0.6.2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "flaky (>=3)", "packaging (>=20.0)", "xonsh (>=0.9.16)"]
[[package]] [[package]]
category = "main" category = "main"
@ -640,7 +641,7 @@ description = "Measures the displayed width of unicode strings in a terminal"
name = "wcwidth" name = "wcwidth"
optional = false optional = false
python-versions = "*" python-versions = "*"
version = "0.2.3" version = "0.2.4"
[[package]] [[package]]
category = "dev" category = "dev"
@ -663,7 +664,7 @@ docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
testing = ["jaraco.itertools", "func-timeout"] testing = ["jaraco.itertools", "func-timeout"]
[metadata] [metadata]
content-hash = "097415d9c723c691882ffa440af8e248746a278f758745d2ce75ffab1bdac90d" content-hash = "044c9aa2965d6dc97970237a0a1e5e02fdd37609ff58cf58f2e68b0a5edecf2a"
python-versions = ">= 3.7, < 3.8" python-versions = ">= 3.7, < 3.8"
[metadata.files] [metadata.files]
@ -672,8 +673,8 @@ appdirs = [
{file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"},
] ]
astroid = [ astroid = [
{file = "astroid-2.4.1-py3-none-any.whl", hash = "sha256:d8506842a3faf734b81599c8b98dcc423de863adcc1999248480b18bd31a0f38"}, {file = "astroid-2.4.2-py3-none-any.whl", hash = "sha256:bc58d83eb610252fd8de6363e39d4f1d0619c894b0ed24603b881c02e64c7386"},
{file = "astroid-2.4.1.tar.gz", hash = "sha256:4c17cea3e592c21b6e222f673868961bad77e1f985cb1694ed077475a89229c1"}, {file = "astroid-2.4.2.tar.gz", hash = "sha256:2f4078c2a41bf377eea06d71c9d2ba4eb8f6b1af2135bec27bbbb7d8f12bb703"},
] ]
atomicwrites = [ atomicwrites = [
{file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
@ -854,8 +855,8 @@ mccabe = [
{file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
] ]
more-itertools = [ more-itertools = [
{file = "more-itertools-8.3.0.tar.gz", hash = "sha256:558bb897a2232f5e4f8e2399089e35aecb746e1f9191b6584a151647e89267be"}, {file = "more-itertools-8.4.0.tar.gz", hash = "sha256:68c70cc7167bdf5c7c9d8f6954a7837089c6a36bf565383919bb595efb8a17e5"},
{file = "more_itertools-8.3.0-py3-none-any.whl", hash = "sha256:7818f596b1e87be009031c7653d01acc46ed422e6656b394b0f765ce66ed4982"}, {file = "more_itertools-8.4.0-py3-none-any.whl", hash = "sha256:b78134b2063dd214000685165d81c154522c3ee0a1c0d4d113c80361c234c5a2"},
] ]
nodeenv = [ nodeenv = [
{file = "nodeenv-1.4.0-py2.py3-none-any.whl", hash = "sha256:4b0b77afa3ba9b54f4b6396e60b0c83f59eaeb2d63dc3cc7a70f7f4af96c82bc"}, {file = "nodeenv-1.4.0-py2.py3-none-any.whl", hash = "sha256:4b0b77afa3ba9b54f4b6396e60b0c83f59eaeb2d63dc3cc7a70f7f4af96c82bc"},
@ -880,8 +881,8 @@ pluggy = [
{file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
] ]
pre-commit = [ pre-commit = [
{file = "pre_commit-2.4.0-py2.py3-none-any.whl", hash = "sha256:5559e09afcac7808933951ffaf4ff9aac524f31efbc3f24d021540b6c579813c"}, {file = "pre_commit-2.5.1-py2.py3-none-any.whl", hash = "sha256:c5c8fd4d0e1c363723aaf0a8f9cba0f434c160b48c4028f4bae6d219177945b3"},
{file = "pre_commit-2.4.0.tar.gz", hash = "sha256:703e2e34cbe0eedb0d319eff9f7b83e2022bb5a3ab5289a6a8841441076514d0"}, {file = "pre_commit-2.5.1.tar.gz", hash = "sha256:da463cf8f0e257f9af49047ba514f6b90dbd9b4f92f4c8847a3ccd36834874c7"},
] ]
prompt-toolkit = [ prompt-toolkit = [
{file = "prompt_toolkit-3.0.5-py3-none-any.whl", hash = "sha256:df7e9e63aea609b1da3a65641ceaf5bc7d05e0a04de5bd45d05dbeffbabf9e04"}, {file = "prompt_toolkit-3.0.5-py3-none-any.whl", hash = "sha256:df7e9e63aea609b1da3a65641ceaf5bc7d05e0a04de5bd45d05dbeffbabf9e04"},
@ -938,8 +939,8 @@ pycryptodome = [
{file = "pycryptodome-3.9.4.tar.gz", hash = "sha256:a168e73879619b467072509a223282a02c8047d932a48b74fbd498f27224aa04"}, {file = "pycryptodome-3.9.4.tar.gz", hash = "sha256:a168e73879619b467072509a223282a02c8047d932a48b74fbd498f27224aa04"},
] ]
pyentrypoint = [ pyentrypoint = [
{file = "pyentrypoint-0.7.3-py3-none-any.whl", hash = "sha256:aa4b3016466b398d379a974e01c363ed12618652adbe6a193ced43ed0fcefacc"}, {file = "pyentrypoint-0.7.4-py3-none-any.whl", hash = "sha256:90dd03052f8e2a7fe4cf7781b6a16711d9ad247607e02d861c5870eff917ad58"},
{file = "pyentrypoint-0.7.3.tar.gz", hash = "sha256:59c02957ec82e9ca53997e66f75d0f375f1a1b39373074d790307d6a159a1e06"}, {file = "pyentrypoint-0.7.4.tar.gz", hash = "sha256:ec1d974dc7ca9cc77ffde31937121c04830060825081a9cfbf25712459c844d9"},
] ]
pyfakefs = [ pyfakefs = [
{file = "pyfakefs-4.0.2-py3-none-any.whl", hash = "sha256:42cf165adc821fc9e205d3fc14033d45e0b8224e1d2fea4f67b487c6b7b3230e"}, {file = "pyfakefs-4.0.2-py3-none-any.whl", hash = "sha256:42cf165adc821fc9e205d3fc14033d45e0b8224e1d2fea4f67b487c6b7b3230e"},
@ -950,8 +951,8 @@ pygments = [
{file = "Pygments-2.6.1.tar.gz", hash = "sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44"}, {file = "Pygments-2.6.1.tar.gz", hash = "sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44"},
] ]
pylint = [ pylint = [
{file = "pylint-2.5.2-py3-none-any.whl", hash = "sha256:dd506acce0427e9e08fb87274bcaa953d38b50a58207170dbf5b36cf3e16957b"}, {file = "pylint-2.5.3-py3-none-any.whl", hash = "sha256:d0ece7d223fe422088b0e8f13fa0a1e8eb745ebffcb8ed53d3e95394b6101a1c"},
{file = "pylint-2.5.2.tar.gz", hash = "sha256:b95e31850f3af163c2283ed40432f053acbc8fc6eba6a069cb518d9dbf71848c"}, {file = "pylint-2.5.3.tar.gz", hash = "sha256:7dd78437f2d8d019717dbf287772d0b2dbdfd13fc016aa7faa08d67bccc46adc"},
] ]
pyparsing = [ pyparsing = [
{file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
@ -978,27 +979,27 @@ pyyaml = [
{file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"},
] ]
regex = [ regex = [
{file = "regex-2020.6.7-cp27-cp27m-win32.whl", hash = "sha256:8d9bb2d90e23c51aacbc58c1a11320f49b335cd67a91986cdbebcc3e843e4de8"}, {file = "regex-2020.6.8-cp27-cp27m-win32.whl", hash = "sha256:fbff901c54c22425a5b809b914a3bfaf4b9570eee0e5ce8186ac71eb2025191c"},
{file = "regex-2020.6.7-cp27-cp27m-win_amd64.whl", hash = "sha256:dcda6d4e1bbfc939b177c237aee41c9678eaaf71df482688f8986e8251e12345"}, {file = "regex-2020.6.8-cp27-cp27m-win_amd64.whl", hash = "sha256:112e34adf95e45158c597feea65d06a8124898bdeac975c9087fe71b572bd938"},
{file = "regex-2020.6.7-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:af7209b2fcc79ee2b0ad4ea080d70bb748450ec4f282cc9e864861e469b1072e"}, {file = "regex-2020.6.8-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:92d8a043a4241a710c1cf7593f5577fbb832cf6c3a00ff3fc1ff2052aff5dd89"},
{file = "regex-2020.6.7-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:5735f26cacdb50b3d6d35ebf8fdeb504bd8b381e2d079d2d9f12ce534fc14ecd"}, {file = "regex-2020.6.8-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:bae83f2a56ab30d5353b47f9b2a33e4aac4de9401fb582b55c42b132a8ac3868"},
{file = "regex-2020.6.7-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f6c8c3f56fef719180464855346e6e80971b86dfd9e5a0e356664b5baca53072"}, {file = "regex-2020.6.8-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:b2ba0f78b3ef375114856cbdaa30559914d081c416b431f2437f83ce4f8b7f2f"},
{file = "regex-2020.6.7-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:21fc17cb868c4264f0813f992f46f9ae6fc8c309d4741091de4153bd1f6a6176"}, {file = "regex-2020.6.8-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:95fa7726d073c87141f7bbfb04c284901f8328e2d430eeb71b8ffdd5742a5ded"},
{file = "regex-2020.6.7-cp36-cp36m-win32.whl", hash = "sha256:150125da109fccdcc8fec3b0b386b2a5d6ca7cff076f8b622486d1ca868b0c10"}, {file = "regex-2020.6.8-cp36-cp36m-win32.whl", hash = "sha256:e3cdc9423808f7e1bb9c2e0bdb1c9dc37b0607b30d646ff6faf0d4e41ee8fee3"},
{file = "regex-2020.6.7-cp36-cp36m-win_amd64.whl", hash = "sha256:c0849b0864ff451f04c8afb5fc28e9ed592262e03debdd227cf0f53e04a55dcd"}, {file = "regex-2020.6.8-cp36-cp36m-win_amd64.whl", hash = "sha256:c78e66a922de1c95a208e4ec02e2e5cf0bb83a36ceececc10a72841e53fbf2bd"},
{file = "regex-2020.6.7-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:8d1ee3796795e609ef7a3a5a35eaf4728038d986aa12c06b3fd1b92ee81911f4"}, {file = "regex-2020.6.8-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:08997a37b221a3e27d68ffb601e45abfb0093d39ee770e4257bd2f5115e8cb0a"},
{file = "regex-2020.6.7-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:7606dba82435429641efe4fbc580574942f89cf2b9c5c1f8bc1eab2bacbf7e8b"}, {file = "regex-2020.6.8-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:2f6f211633ee8d3f7706953e9d3edc7ce63a1d6aad0be5dcee1ece127eea13ae"},
{file = "regex-2020.6.7-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:6edc5c190248d3b612f2cca45448cf8ebc3621d41afcd1c5708853cbb1dbb3b3"}, {file = "regex-2020.6.8-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:55b4c25cbb3b29f8d5e63aeed27b49fa0f8476b0d4e1b3171d85db891938cc3a"},
{file = "regex-2020.6.7-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:2c928bc8e0c453d73dffa3193a6e37ee752ea36df0dd4601e21024d98274dfad"}, {file = "regex-2020.6.8-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:89cda1a5d3e33ec9e231ece7307afc101b5217523d55ef4dc7fb2abd6de71ba3"},
{file = "regex-2020.6.7-cp37-cp37m-win32.whl", hash = "sha256:97d414c41f19fd2362e493810caa8445c05e0a2d63a14081c972aad66284a8d2"}, {file = "regex-2020.6.8-cp37-cp37m-win32.whl", hash = "sha256:690f858d9a94d903cf5cada62ce069b5d93b313d7d05456dbcd99420856562d9"},
{file = "regex-2020.6.7-cp37-cp37m-win_amd64.whl", hash = "sha256:9e37502817225ee99d91d8418f5119e98c380b00e772d06915690c05290f32ee"}, {file = "regex-2020.6.8-cp37-cp37m-win_amd64.whl", hash = "sha256:1700419d8a18c26ff396b3b06ace315b5f2a6e780dad387e4c48717a12a22c29"},
{file = "regex-2020.6.7-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c4ac9215650688e78dea29b46adbdafb7b85058eebe92ef6ea848e14466c915f"}, {file = "regex-2020.6.8-cp38-cp38-manylinux1_i686.whl", hash = "sha256:654cb773b2792e50151f0e22be0f2b6e1c3a04c5328ff1d9d59c0398d37ef610"},
{file = "regex-2020.6.7-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:20c513893ff80bdbe4b4ce11ea2e93d49481f05b270595d82af69ffc402010a6"}, {file = "regex-2020.6.8-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:52e1b4bef02f4040b2fd547357a170fc1146e60ab310cdbdd098db86e929b387"},
{file = "regex-2020.6.7-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:163bc0805e46acfa098dfc8c0b07f371577d505f603e48afc425ff475cdac3a5"}, {file = "regex-2020.6.8-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:cf59bbf282b627130f5ba68b7fa3abdb96372b24b66bdf72a4920e8153fc7910"},
{file = "regex-2020.6.7-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:2d9beca70e36f9c60d679e108c5fe49f3d4da79d13a13f91e5e759443bd954f9"}, {file = "regex-2020.6.8-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:5aaa5928b039ae440d775acea11d01e42ff26e1561c0ffcd3d805750973c6baf"},
{file = "regex-2020.6.7-cp38-cp38-win32.whl", hash = "sha256:ec0e509ed1877ff1cbc6f0864689bb60384a303502c4d72d9a635f8a4676fd3f"}, {file = "regex-2020.6.8-cp38-cp38-win32.whl", hash = "sha256:97712e0d0af05febd8ab63d2ef0ab2d0cd9deddf4476f7aa153f76feef4b2754"},
{file = "regex-2020.6.7-cp38-cp38-win_amd64.whl", hash = "sha256:dd8501b8d9ea1aba53c4bc7d47bc72933f9b4213d534cf400f16c1431f51c8ba"}, {file = "regex-2020.6.8-cp38-cp38-win_amd64.whl", hash = "sha256:6ad8663c17db4c5ef438141f99e291c4d4edfeaacc0ce28b5bba2b0bf273d9b5"},
{file = "regex-2020.6.7.tar.gz", hash = "sha256:ffd4f80602490a309064cf2b203e220d581c51660e01055c64bf5da450485ee6"}, {file = "regex-2020.6.8.tar.gz", hash = "sha256:e9b64e609d37438f7d6e68c2546d2cb8062f3adb27e6336bc129b51be20773ac"},
] ]
six = [ six = [
{file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"},
@ -1043,15 +1044,15 @@ vanguards = [
{file = "vanguards-0.3.1.tar.gz", hash = "sha256:04049fafd433bb747fbe27b404413ce09b441d5e0e6cc5d81debaac2192567b7"}, {file = "vanguards-0.3.1.tar.gz", hash = "sha256:04049fafd433bb747fbe27b404413ce09b441d5e0e6cc5d81debaac2192567b7"},
] ]
virtualenv = [ virtualenv = [
{file = "virtualenv-20.0.21-py2.py3-none-any.whl", hash = "sha256:a730548b27366c5e6cbdf6f97406d861cccece2e22275e8e1a757aeff5e00c70"}, {file = "virtualenv-20.0.23-py2.py3-none-any.whl", hash = "sha256:ccfb8e1e05a1174f7bd4c163700277ba730496094fe1a58bea9d4ac140a207c8"},
{file = "virtualenv-20.0.21.tar.gz", hash = "sha256:a116629d4e7f4d03433b8afa27f43deba09d48bc48f5ecefa4f015a178efb6cf"}, {file = "virtualenv-20.0.23.tar.gz", hash = "sha256:5102fbf1ec57e80671ef40ed98a84e980a71194cedf30c87c2b25c3a9e0b0107"},
] ]
watchdog = [ watchdog = [
{file = "watchdog-0.10.2.tar.gz", hash = "sha256:c560efb643faed5ef28784b2245cf8874f939569717a4a12826a173ac644456b"}, {file = "watchdog-0.10.2.tar.gz", hash = "sha256:c560efb643faed5ef28784b2245cf8874f939569717a4a12826a173ac644456b"},
] ]
wcwidth = [ wcwidth = [
{file = "wcwidth-0.2.3-py2.py3-none-any.whl", hash = "sha256:980fbf4f3c196c0f329cdcd1e84c554d6a211f18e252e525a0cf4223154a41d6"}, {file = "wcwidth-0.2.4-py2.py3-none-any.whl", hash = "sha256:79375666b9954d4a1a10739315816324c3e73110af9d0e102d906fdb0aec009f"},
{file = "wcwidth-0.2.3.tar.gz", hash = "sha256:edbc2b718b4db6cdf393eefe3a420183947d6aa312505ce6754516f458ff8830"}, {file = "wcwidth-0.2.4.tar.gz", hash = "sha256:8c6b5b6ee1360b842645f336d9e5d68c55817c26d3050f46b235ef2bc650e48f"},
] ]
wrapt = [ wrapt = [
{file = "wrapt-1.12.1.tar.gz", hash = "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"}, {file = "wrapt-1.12.1.tar.gz", hash = "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"},

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "docker-tor-hidden-service" name = "docker-tor-hidden-service"
version = "0.6.0" version = "0.6.1"
description = "Display onion sites hosted" description = "Display onion sites hosted"
authors = ["Christophe Mehay <cmehay@nospam.student.42.fr>"] authors = ["Christophe Mehay <cmehay@nospam.student.42.fr>"]
license = "WTFPL" license = "WTFPL"
@ -26,7 +26,7 @@ onions = "onions:main"
python = ">= 3.7, < 3.8" python = ">= 3.7, < 3.8"
pytor = "^0.1.5" pytor = "^0.1.5"
Jinja2 = "^2.10" Jinja2 = "^2.10"
pyentrypoint = "^0.7.3" pyentrypoint = "^0.7.4"
importlib_metadata = "^1.6.0" importlib_metadata = "^1.6.0"
vanguards = "^0.3.1" vanguards = "^0.3.1"
ipy = "^1.00" ipy = "^1.00"

@ -1,3 +1,4 @@
import configparser
import json import json
import os import os
import re import re
@ -13,7 +14,9 @@ from onions import Onions
def get_key_and_onion(version=2): def get_key_and_onion(version=2):
key = {} key = {}
key[2] = ''' key[
2
] = """
-----BEGIN RSA PRIVATE KEY----- -----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCsMP4gl6g1Q313miPhb1GnDr56ZxIWGsO2PwHM1infkbhlBakR MIICXAIBAAKBgQCsMP4gl6g1Q313miPhb1GnDr56ZxIWGsO2PwHM1infkbhlBakR
6DGQfpE31L1ZKTUxY0OexKbW088v8qCOfjD9Zk1i80JP4xzfWQcwFZ5yM/0fkhm3 6DGQfpE31L1ZKTUxY0OexKbW088v8qCOfjD9Zk1i80JP4xzfWQcwFZ5yM/0fkhm3
@ -29,36 +32,41 @@ l5MQPWBkRKK2pc2Hfj8cdIMi8kJ/1CyCwE6c5l8etR3sbIMRTtZ76nAbXRFkmsRv
La/7Syrnobngsh/vX90CQB+PSSBqiPSsK2yPz6Gsd6OLCQ9sdy2oRwFTasH8sZyl La/7Syrnobngsh/vX90CQB+PSSBqiPSsK2yPz6Gsd6OLCQ9sdy2oRwFTasH8sZyl
bhJ3M9WzP/EMkAzyW8mVs1moFp3hRcfQlZHl6g1U9D8= bhJ3M9WzP/EMkAzyW8mVs1moFp3hRcfQlZHl6g1U9D8=
-----END RSA PRIVATE KEY----- -----END RSA PRIVATE KEY-----
''' """
onion = {} onion = {}
pub = {} pub = {}
onion[2] = b32encode( onion[2] = (
sha1( b32encode(
RSA.importKey( sha1(
key[2].strip() RSA.importKey(key[2].strip()).publickey().exportKey("DER")[22:]
).publickey().exportKey( ).digest()[:10]
"DER" )
)[22:] .decode()
).digest()[:10] .lower()
).decode().lower() + '.onion' + ".onion"
)
key[3] = '''
key[
3
] = """
PT0gZWQyNTUxOXYxLXNlY3JldDogdHlwZTAgPT0AAACArobDQYyZAWXei4QZwr++j96H1X/gq14N PT0gZWQyNTUxOXYxLXNlY3JldDogdHlwZTAgPT0AAACArobDQYyZAWXei4QZwr++j96H1X/gq14N
wLRZ2O5DXuL0EzYKkdhZSILY85q+kfwZH8z4ceqe7u1F+0pQi/sM wLRZ2O5DXuL0EzYKkdhZSILY85q+kfwZH8z4ceqe7u1F+0pQi/sM
''' """
pub[3] = ''' pub[
3
] = """
PT0gZWQyNTUxOXYxLXB1YmxpYzogdHlwZTAgPT0AAAC9kzftiea/kb+TWlCEVNpfUJLVk+rFIoMG PT0gZWQyNTUxOXYxLXB1YmxpYzogdHlwZTAgPT0AAAC9kzftiea/kb+TWlCEVNpfUJLVk+rFIoMG
m9/hW13isA== m9/hW13isA==
''' """
onion[3] = 'xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion' onion[3] = "xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion"
return key[version].strip(), onion[version] return key[version].strip(), onion[version]
def get_torrc_template(): def get_torrc_template():
return r''' return r"""
{% for service_group in onion.services %} {% for service_group in onion.services %}
HiddenServiceDir {{service_group.hidden_service_dir}} HiddenServiceDir {{service_group.hidden_service_dir}}
{% if service_group.version == 3 %} {% if service_group.version == 3 %}
@ -90,7 +98,7 @@ ExitRelay 0
{% if onion.enable_control_port %} {% if onion.enable_control_port %}
{% if onion.control_socket %} {% if onion.control_socket %}
ControlPort unix:{{onion.control_socket}} ControlPort {{onion.control_socket}}
{% endif %} {% endif %}
{% if not onion.control_socket %} {% if not onion.control_socket %}
{% if onion.control_ip_binding.version() == 4 %} {% if onion.control_ip_binding.version() == 4 %}
@ -111,17 +119,20 @@ HashedControlPassword {{ onion.control_hashed_password }}
{% endif %} {% endif %}
# useless line for Jinja bug # useless line for Jinja bug
'''.strip()
# useless line for Jinja bug
""".strip()
def test_ports(monkeypatch): def test_ports(monkeypatch):
env = { env = {
'SERVICE1_PORTS': '80:80', "SERVICE1_PORTS": "80:80",
'SERVICE2_PORTS': '80:80,81:8000', "SERVICE2_PORTS": "80:80,81:8000",
'SERVICE3_PORTS': '80:unix://unix.socket', "SERVICE3_PORTS": "80:unix://unix.socket",
} }
monkeypatch.setattr(os, 'environ', env) monkeypatch.setattr(os, "environ", env)
onion = Onions() onion = Onions()
onion._get_setup_from_env() onion._get_setup_from_env()
@ -131,24 +142,24 @@ def test_ports(monkeypatch):
for service_group in onion.services: for service_group in onion.services:
assert len(service_group.services) == 1 assert len(service_group.services) == 1
service = service_group.services[0] service = service_group.services[0]
if service.host == 'service1': if service.host == "service1":
check += 1 check += 1
assert len(service.ports) == 1 assert len(service.ports) == 1
assert service.ports[0].port_from == 80 assert service.ports[0].port_from == 80
assert service.ports[0].dest == 80 assert service.ports[0].dest == 80
assert not service.ports[0].is_socket assert not service.ports[0].is_socket
if service.host == 'service2': if service.host == "service2":
check += 3 check += 3
assert len(service.ports) == 2 assert len(service.ports) == 2
assert service.ports[0].port_from == 80 assert service.ports[0].port_from == 80
assert service.ports[0].dest == 80 assert service.ports[0].dest == 80
assert service.ports[1].port_from == 81 assert service.ports[1].port_from == 81
assert service.ports[1].dest == 8000 assert service.ports[1].dest == 8000
if service.host == 'service3': if service.host == "service3":
check += 6 check += 6
assert len(service.ports) == 1 assert len(service.ports) == 1
assert service.ports[0].port_from == 80 assert service.ports[0].port_from == 80
assert service.ports[0].dest == 'unix://unix.socket' assert service.ports[0].dest == "unix://unix.socket"
assert service.ports[0].is_socket assert service.ports[0].is_socket
assert check == 10 assert check == 10
@ -157,40 +168,40 @@ def test_ports(monkeypatch):
def test_docker_links(fs, monkeypatch): def test_docker_links(fs, monkeypatch):
env = { env = {
'HOSTNAME': 'test_env', "HOSTNAME": "test_env",
'COMPOSE_SERVICE1_1_PORT': 'tcp://172.17.0.2:80', "COMPOSE_SERVICE1_1_PORT": "tcp://172.17.0.2:80",
'COMPOSE_SERVICE1_1_PORT_80_TCP': 'tcp://172.17.0.2:80', "COMPOSE_SERVICE1_1_PORT_80_TCP": "tcp://172.17.0.2:80",
'COMPOSE_SERVICE1_1_PORT_80_TCP_ADDR': '172.17.0.2', "COMPOSE_SERVICE1_1_PORT_80_TCP_ADDR": "172.17.0.2",
'COMPOSE_SERVICE1_1_PORT_80_TCP_PORT': '80', "COMPOSE_SERVICE1_1_PORT_80_TCP_PORT": "80",
'COMPOSE_SERVICE1_1_PORT_80_TCP_PROTO': 'tcp', "COMPOSE_SERVICE1_1_PORT_80_TCP_PROTO": "tcp",
'COMPOSE_SERVICE1_1_PORT_8000_TCP': 'tcp://172.17.0.2:8000', "COMPOSE_SERVICE1_1_PORT_8000_TCP": "tcp://172.17.0.2:8000",
'COMPOSE_SERVICE1_1_PORT_8000_TCP_ADDR': '172.17.0.2', "COMPOSE_SERVICE1_1_PORT_8000_TCP_ADDR": "172.17.0.2",
'COMPOSE_SERVICE1_1_PORT_8000_TCP_PORT': '8000', "COMPOSE_SERVICE1_1_PORT_8000_TCP_PORT": "8000",
'COMPOSE_SERVICE1_1_PORT_8000_TCP_PROTO': 'tcp', "COMPOSE_SERVICE1_1_PORT_8000_TCP_PROTO": "tcp",
'COMPOSE_SERVICE1_1_NAME': '/compose_env_1/compose_service1_1', "COMPOSE_SERVICE1_1_NAME": "/compose_env_1/compose_service1_1",
'SERVICE1_PORT': 'tcp://172.17.0.2:80', "SERVICE1_PORT": "tcp://172.17.0.2:80",
'SERVICE1_PORT_80_TCP': 'tcp://172.17.0.2:80', "SERVICE1_PORT_80_TCP": "tcp://172.17.0.2:80",
'SERVICE1_PORT_80_TCP_ADDR': '172.17.0.2', "SERVICE1_PORT_80_TCP_ADDR": "172.17.0.2",
'SERVICE1_PORT_80_TCP_PORT': '80', "SERVICE1_PORT_80_TCP_PORT": "80",
'SERVICE1_PORT_80_TCP_PROTO': 'tcp', "SERVICE1_PORT_80_TCP_PROTO": "tcp",
'SERVICE1_PORT_8000_TCP': 'tcp://172.17.0.2:8000', "SERVICE1_PORT_8000_TCP": "tcp://172.17.0.2:8000",
'SERVICE1_PORT_8000_TCP_ADDR': '172.17.0.2', "SERVICE1_PORT_8000_TCP_ADDR": "172.17.0.2",
'SERVICE1_PORT_8000_TCP_PORT': '8000', "SERVICE1_PORT_8000_TCP_PORT": "8000",
'SERVICE1_PORT_8000_TCP_PROTO': 'tcp', "SERVICE1_PORT_8000_TCP_PROTO": "tcp",
'SERVICE1_NAME': '/compose_env_1/service1', "SERVICE1_NAME": "/compose_env_1/service1",
'SERVICE1_1_PORT': 'tcp://172.17.0.2:80', "SERVICE1_1_PORT": "tcp://172.17.0.2:80",
'SERVICE1_1_PORT_80_TCP': 'tcp://172.17.0.2:80', "SERVICE1_1_PORT_80_TCP": "tcp://172.17.0.2:80",
'SERVICE1_1_PORT_80_TCP_ADDR': '172.17.0.2', "SERVICE1_1_PORT_80_TCP_ADDR": "172.17.0.2",
'SERVICE1_1_PORT_80_TCP_PORT': '80', "SERVICE1_1_PORT_80_TCP_PORT": "80",
'SERVICE1_1_PORT_80_TCP_PROTO': 'tcp', "SERVICE1_1_PORT_80_TCP_PROTO": "tcp",
'SERVICE1_1_PORT_8000_TCP': 'tcp://172.17.0.2:8000', "SERVICE1_1_PORT_8000_TCP": "tcp://172.17.0.2:8000",
'SERVICE1_1_PORT_8000_TCP_ADDR': '172.17.0.2', "SERVICE1_1_PORT_8000_TCP_ADDR": "172.17.0.2",
'SERVICE1_1_PORT_8000_TCP_PORT': '8000', "SERVICE1_1_PORT_8000_TCP_PORT": "8000",
'SERVICE1_1_PORT_8000_TCP_PROTO': 'tcp', "SERVICE1_1_PORT_8000_TCP_PROTO": "tcp",
'SERVICE1_1_NAME': '/compose_env_1/service1_1', "SERVICE1_1_NAME": "/compose_env_1/service1_1",
} }
etc_host = ''' etc_host = """
127.0.0.1 localhost 127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback ::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet fe00::0 ip6-localnet
@ -200,11 +211,11 @@ ff02::2 ip6-allrouters
172.17.0.2 service1 bf447f22cdba compose_service1_1 172.17.0.2 service1 bf447f22cdba compose_service1_1
172.17.0.2 service1_1 bf447f22cdba compose_service1_1 172.17.0.2 service1_1 bf447f22cdba compose_service1_1
172.17.0.2 compose_service1_1 bf447f22cdba 172.17.0.2 compose_service1_1 bf447f22cdba
'''.strip() """.strip()
fs.create_file('/etc/hosts', contents=etc_host) fs.create_file("/etc/hosts", contents=etc_host)
monkeypatch.setattr(os, 'environ', env) monkeypatch.setattr(os, "environ", env)
onion = Onions() onion = Onions()
onion._get_setup_from_links() onion._get_setup_from_links()
@ -214,19 +225,17 @@ ff02::2 ip6-allrouters
assert len(group.services) == 1 assert len(group.services) == 1
service = group.services[0] service = group.services[0]
assert len(service.ports) == 2 assert len(service.ports) == 2
assert set( assert set((port.port_from, port.dest) for port in service.ports) == set(
(port.port_from, port.dest) for port in service.ports [(80, 80), (8000, 8000)]
) == set([(80, 80), (8000, 8000)]) )
def test_key(monkeypatch): def test_key(monkeypatch):
key, onion_url = get_key_and_onion() key, onion_url = get_key_and_onion()
env = { env = {"SERVICE1_KEY": key}
'SERVICE1_KEY': key
}
monkeypatch.setattr(os, 'environ', env) monkeypatch.setattr(os, "environ", env)
onion = Onions() onion = Onions()
onion._get_setup_from_env() onion._get_setup_from_env()
@ -239,17 +248,20 @@ def test_key(monkeypatch):
def test_key_v2(monkeypatch): def test_key_v2(monkeypatch):
key, onion_url = get_key_and_onion(version=2) key, onion_url = get_key_and_onion(version=2)
envs = [{ envs = [
'GROUP1_TOR_SERVICE_HOSTS': '80:service1:80,81:service2:80', {
'GROUP1_TOR_SERVICE_VERSION': '2', "GROUP1_TOR_SERVICE_HOSTS": "80:service1:80,81:service2:80",
'GROUP1_TOR_SERVICE_KEY': key, "GROUP1_TOR_SERVICE_VERSION": "2",
}, { "GROUP1_TOR_SERVICE_KEY": key,
'GROUP1_TOR_SERVICE_HOSTS': '80:service1:80,81:service2:80', },
'GROUP1_TOR_SERVICE_KEY': key, {
}] "GROUP1_TOR_SERVICE_HOSTS": "80:service1:80,81:service2:80",
"GROUP1_TOR_SERVICE_KEY": key,
},
]
for env in envs: for env in envs:
monkeypatch.setattr(os, 'environ', env) monkeypatch.setattr(os, "environ", env)
onion = Onions() onion = Onions()
onion._get_setup_from_env() onion._get_setup_from_env()
@ -264,12 +276,12 @@ def test_key_v2(monkeypatch):
def test_key_v3(monkeypatch): def test_key_v3(monkeypatch):
key, onion_url = get_key_and_onion(version=3) key, onion_url = get_key_and_onion(version=3)
env = { env = {
'GROUP1_TOR_SERVICE_HOSTS': '80:service1:80,81:service2:80', "GROUP1_TOR_SERVICE_HOSTS": "80:service1:80,81:service2:80",
'GROUP1_TOR_SERVICE_VERSION': '3', "GROUP1_TOR_SERVICE_VERSION": "3",
'GROUP1_TOR_SERVICE_KEY': key, "GROUP1_TOR_SERVICE_KEY": key,
} }
monkeypatch.setattr(os, 'environ', env) monkeypatch.setattr(os, "environ", env)
onion = Onions() onion = Onions()
onion._get_setup_from_env() onion._get_setup_from_env()
@ -283,27 +295,27 @@ def test_key_v3(monkeypatch):
def test_key_in_secret(fs, monkeypatch): def test_key_in_secret(fs, monkeypatch):
env = { env = {
'GROUP1_TOR_SERVICE_HOSTS': '80:service1:80', "GROUP1_TOR_SERVICE_HOSTS": "80:service1:80",
'GROUP2_TOR_SERVICE_HOSTS': '80:service2:80', "GROUP2_TOR_SERVICE_HOSTS": "80:service2:80",
'GROUP3_TOR_SERVICE_HOSTS': '80:service3:80', "GROUP3_TOR_SERVICE_HOSTS": "80:service3:80",
'GROUP3_TOR_SERVICE_VERSION': '3', "GROUP3_TOR_SERVICE_VERSION": "3",
} }
monkeypatch.setattr(os, 'environ', env) monkeypatch.setattr(os, "environ", env)
key_v2, onion_url_v2 = get_key_and_onion() key_v2, onion_url_v2 = get_key_and_onion()
key_v3, onion_url_v3 = get_key_and_onion(version=3) key_v3, onion_url_v3 = get_key_and_onion(version=3)
fs.create_file('/run/secrets/group1', contents=key_v2) fs.create_file("/run/secrets/group1", contents=key_v2)
fs.create_file('/run/secrets/group3', contents=b64decode(key_v3)) fs.create_file("/run/secrets/group3", contents=b64decode(key_v3))
onion = Onions() onion = Onions()
onion._get_setup_from_env() onion._get_setup_from_env()
onion._load_keys_in_services() onion._load_keys_in_services()
group1 = onion.find_group_by_name('group1') group1 = onion.find_group_by_name("group1")
group2 = onion.find_group_by_name('group2') group2 = onion.find_group_by_name("group2")
group3 = onion.find_group_by_name('group3') group3 = onion.find_group_by_name("group3")
assert group1.onion_url == onion_url_v2 assert group1.onion_url == onion_url_v2
assert group2.onion_url not in [onion_url_v2, onion_url_v3] assert group2.onion_url not in [onion_url_v2, onion_url_v3]
@ -311,37 +323,37 @@ def test_key_in_secret(fs, monkeypatch):
def test_configuration(fs, monkeypatch, tmpdir): def test_configuration(fs, monkeypatch, tmpdir):
extra_options = ''' extra_options = """
HiddenServiceNonAnonymousMode 1 HiddenServiceNonAnonymousMode 1
HiddenServiceSingleHopMode 1 HiddenServiceSingleHopMode 1
'''.strip() """.strip()
env = { env = {
'SERVICE1_SERVICE_NAME': 'group1', "SERVICE1_SERVICE_NAME": "group1",
'SERVICE2_SERVICE_NAME': 'group1', "SERVICE2_SERVICE_NAME": "group1",
'SERVICE3_SERVICE_NAME': 'group2', "SERVICE3_SERVICE_NAME": "group2",
'SERVICE1_PORTS': '80:80', "SERVICE1_PORTS": "80:80",
'SERVICE2_PORTS': '81:80,82:8000', "SERVICE2_PORTS": "81:80,82:8000",
'SERVICE3_PORTS': '80:unix://unix.socket', "SERVICE3_PORTS": "80:unix://unix.socket",
'GROUP3_TOR_SERVICE_VERSION': '2', "GROUP3_TOR_SERVICE_VERSION": "2",
'GROUP3_TOR_SERVICE_HOSTS': '80:service4:888,81:service5:8080', "GROUP3_TOR_SERVICE_HOSTS": "80:service4:888,81:service5:8080",
'GROUP4_TOR_SERVICE_VERSION': '3', "GROUP4_TOR_SERVICE_VERSION": "3",
'GROUP4_TOR_SERVICE_HOSTS': '81:unix://unix2.sock', "GROUP4_TOR_SERVICE_HOSTS": "81:unix://unix2.sock",
'GROUP3V3_TOR_SERVICE_VERSION': '3', "GROUP3V3_TOR_SERVICE_VERSION": "3",
'GROUP3V3_TOR_SERVICE_HOSTS': '80:service4:888,81:service5:8080', "GROUP3V3_TOR_SERVICE_HOSTS": "80:service4:888,81:service5:8080",
'SERVICE5_TOR_SERVICE_HOSTS': '80:service5:80', "SERVICE5_TOR_SERVICE_HOSTS": "80:service5:80",
'TOR_EXTRA_OPTIONS': extra_options, "TOR_EXTRA_OPTIONS": extra_options,
} }
hidden_dir = '/var/lib/tor/hidden_service' hidden_dir = "/var/lib/tor/hidden_service"
monkeypatch.setattr(os, 'environ', env) monkeypatch.setattr(os, "environ", env)
monkeypatch.setattr(os, 'fchmod', lambda x, y: None) monkeypatch.setattr(os, "fchmod", lambda x, y: None)
torrc_tpl = get_torrc_template() torrc_tpl = get_torrc_template()
fs.create_file('/var/local/tor/torrc.tpl', contents=torrc_tpl) fs.create_file("/var/local/tor/torrc.tpl", contents=torrc_tpl)
fs.create_file('/etc/tor/torrc') fs.create_file("/etc/tor/torrc")
fs.create_dir(hidden_dir) fs.create_dir(hidden_dir)
onion = Onions() onion = Onions()
@ -351,30 +363,31 @@ HiddenServiceSingleHopMode 1
onions_urls = {} onions_urls = {}
for dir in os.listdir(hidden_dir): for dir in os.listdir(hidden_dir):
with open(os.path.join(hidden_dir, dir, 'hostname'), 'r') as f: with open(os.path.join(hidden_dir, dir, "hostname"), "r") as f:
onions_urls[dir] = f.read().strip() onions_urls[dir] = f.read().strip()
with open('/etc/tor/torrc', 'r') as f: with open("/etc/tor/torrc", "r") as f:
torrc = f.read() torrc = f.read()
print(torrc) print(torrc)
assert 'HiddenServiceDir /var/lib/tor/hidden_service/group1' in torrc assert "HiddenServiceDir /var/lib/tor/hidden_service/group1" in torrc
assert 'HiddenServicePort 80 service1:80' in torrc assert "HiddenServicePort 80 service1:80" in torrc
assert 'HiddenServicePort 81 service2:80' in torrc assert "HiddenServicePort 81 service2:80" in torrc
assert 'HiddenServicePort 82 service2:8000' in torrc assert "HiddenServicePort 82 service2:8000" in torrc
assert 'HiddenServiceDir /var/lib/tor/hidden_service/group2' in torrc assert "HiddenServiceDir /var/lib/tor/hidden_service/group2" in torrc
assert 'HiddenServicePort 80 unix://unix.socket' in torrc assert "HiddenServicePort 80 unix://unix.socket" in torrc
assert 'HiddenServiceDir /var/lib/tor/hidden_service/group3' in torrc assert "HiddenServiceDir /var/lib/tor/hidden_service/group3" in torrc
assert 'HiddenServiceDir /var/lib/tor/hidden_service/group4' in torrc assert "HiddenServiceDir /var/lib/tor/hidden_service/group4" in torrc
assert 'HiddenServiceDir /var/lib/tor/hidden_service/group3v3' in torrc assert "HiddenServiceDir /var/lib/tor/hidden_service/group3v3" in torrc
assert 'HiddenServiceDir /var/lib/tor/hidden_service/service5' in torrc assert "HiddenServiceDir /var/lib/tor/hidden_service/service5" in torrc
assert torrc.count('HiddenServicePort 80 service4:888') == 2 assert torrc.count("HiddenServicePort 80 service4:888") == 2
assert torrc.count('HiddenServicePort 81 service5:8080') == 2 assert torrc.count("HiddenServicePort 81 service5:8080") == 2
assert torrc.count('HiddenServicePort 80 service5:80') == 1 assert torrc.count("HiddenServicePort 80 service5:80") == 1
assert torrc.count('HiddenServicePort 81 unix://unix2.sock') == 1 assert torrc.count("HiddenServicePort 81 unix://unix2.sock") == 1
assert torrc.count('HiddenServiceVersion 3') == 2 assert torrc.count("HiddenServiceVersion 3") == 2
assert 'HiddenServiceNonAnonymousMode 1\n' in torrc assert "HiddenServiceNonAnonymousMode 1\n" in torrc
assert 'HiddenServiceSingleHopMode 1\n' in torrc assert "HiddenServiceSingleHopMode 1\n" in torrc
assert "ControlPort" not in torrc
# Check parser # Check parser
onion2 = Onions() onion2 = Onions()
@ -383,141 +396,184 @@ HiddenServiceSingleHopMode 1
assert len(onion2.services) == 6 assert len(onion2.services) == 6
assert set( assert set(
group.name for group in onion2.services group.name
for group in onion2.services
# ) == set(['group1', 'group2']) # ) == set(['group1', 'group2'])
) == set(['group1', 'group2', 'group3', 'group4', 'group3v3', 'service5']) ) == set(["group1", "group2", "group3", "group4", "group3v3", "service5"])
for group in onion2.services: for group in onion2.services:
if group.name == 'group1': if group.name == "group1":
assert len(group.services) == 2 assert len(group.services) == 2
assert group.version == 2 assert group.version == 2
assert group.onion_url == onions_urls[group.name] assert group.onion_url == onions_urls[group.name]
assert set( assert set(service.host for service in group.services) == set(
service.host for service in group.services ["service1", "service2"]
) == set(['service1', 'service2']) )
for service in group.services: for service in group.services:
if service.host == 'service1': if service.host == "service1":
assert len(service.ports) == 1 assert len(service.ports) == 1
assert set( assert set(
(port.port_from, port.dest) for port in service.ports (port.port_from, port.dest) for port in service.ports
) == set([(80, 80)]) ) == set([(80, 80)])
if service.host == 'service2': if service.host == "service2":
assert len(service.ports) == 2 assert len(service.ports) == 2
assert set( assert set(
(port.port_from, port.dest) for port in service.ports (port.port_from, port.dest) for port in service.ports
) == set([(81, 80), (82, 8000)]) ) == set([(81, 80), (82, 8000)])
if group.name == 'group2': if group.name == "group2":
assert len(group.services) == 1 assert len(group.services) == 1
assert group.version == 2 assert group.version == 2
assert group.onion_url == onions_urls[group.name] assert group.onion_url == onions_urls[group.name]
assert set( assert set(service.host for service in group.services) == set(
service.host for service in group.services ["group2"]
) == set(['group2']) )
service = group.services[0] service = group.services[0]
assert len(service.ports) == 1 assert len(service.ports) == 1
assert set( assert set(
(port.port_from, port.dest) for port in service.ports (port.port_from, port.dest) for port in service.ports
) == set([(80, 'unix://unix.socket')]) ) == set([(80, "unix://unix.socket")])
if group.name in ['group3', 'group3v3']: if group.name in ["group3", "group3v3"]:
assert len(group.services) == 2 assert len(group.services) == 2
assert group.version == 2 if group.name == 'group3' else 3 assert group.version == 2 if group.name == "group3" else 3
assert group.onion_url == onions_urls[group.name] assert group.onion_url == onions_urls[group.name]
assert set( assert set(service.host for service in group.services) == set(
service.host for service in group.services ["service4", "service5"]
) == set(['service4', 'service5']) )
for service in group.services: for service in group.services:
if service.host == 'service4': if service.host == "service4":
assert len(service.ports) == 1 assert len(service.ports) == 1
assert set( assert set(
(port.port_from, port.dest) for port in service.ports (port.port_from, port.dest) for port in service.ports
) == set([(80, 888)]) ) == set([(80, 888)])
if service.host == 'service5': if service.host == "service5":
assert len(service.ports) == 1 assert len(service.ports) == 1
assert set( assert set(
(port.port_from, port.dest) for port in service.ports (port.port_from, port.dest) for port in service.ports
) == set([(81, 8080)]) ) == set([(81, 8080)])
if group.name == 'group4': if group.name == "group4":
assert len(group.services) == 1 assert len(group.services) == 1
assert group.version == 3 assert group.version == 3
assert group.onion_url == onions_urls[group.name] assert group.onion_url == onions_urls[group.name]
assert set( assert set(service.host for service in group.services) == set(
service.host for service in group.services ["group4"]
) == set(['group4']) )
for service in group.services: for service in group.services:
assert service.host == 'group4' assert service.host == "group4"
assert len(service.ports) == 1 assert len(service.ports) == 1
assert set( assert set(
(port.port_from, port.dest) for port in service.ports (port.port_from, port.dest) for port in service.ports
) == set([(81, 'unix://unix2.sock')]) ) == set([(81, "unix://unix2.sock")])
if group.name == 'service5': if group.name == "service5":
assert len(group.services) == 1 assert len(group.services) == 1
assert group.version == 2 assert group.version == 2
assert group.onion_url == onions_urls[group.name] assert group.onion_url == onions_urls[group.name]
assert set( assert set(service.host for service in group.services) == set(
service.host for service in group.services ["service5"]
) == set(['service5']) )
for service in group.services: for service in group.services:
assert service.host == 'service5' assert service.host == "service5"
assert len(service.ports) == 1 assert len(service.ports) == 1
assert set( assert set(
(port.port_from, port.dest) for port in service.ports (port.port_from, port.dest) for port in service.ports
) == set([(80, 80)]) ) == set([(80, 80)])
# bug with fakefs, test everything in the same function
env = {
"TOR_CONTROL_PORT": "172.0.1.0:7867",
"TOR_CONTROL_PASSWORD": "secret",
}
def mock_hash(self, password):
self.control_hashed_password = "myhashedpassword"
monkeypatch.setattr(os, "environ", env)
monkeypatch.setattr(Onions, "_hash_control_port_password", mock_hash)
onion = Onions()
onion._setup_control_port()
onion.apply_conf()
with open("/etc/tor/torrc", "r") as f:
torrc = f.read()
print(torrc)
assert "ControlPort 172.0.1.0:7867" in torrc
assert f"HashedControlPassword {onion.control_hashed_password}" in torrc
env = {
"TOR_CONTROL_PORT": "unix:/path/to.socket",
}
monkeypatch.setattr(os, "environ", env)
torrc_tpl = get_torrc_template()
onion = Onions()
onion._setup_control_port()
onion.apply_conf()
with open("/etc/tor/torrc", "r") as f:
torrc = f.read()
print(torrc)
assert "ControlPort unix:/path/to.socket" in torrc
def test_groups(monkeypatch): def test_groups(monkeypatch):
env = { env = {
'SERVICE1_SERVICE_NAME': 'group1', "SERVICE1_SERVICE_NAME": "group1",
'SERVICE2_SERVICE_NAME': 'group1', "SERVICE2_SERVICE_NAME": "group1",
'SERVICE3_SERVICE_NAME': 'group2', "SERVICE3_SERVICE_NAME": "group2",
'SERVICE1_PORTS': '80:80', "SERVICE1_PORTS": "80:80",
'SERVICE2_PORTS': '81:80,82:8000', "SERVICE2_PORTS": "81:80,82:8000",
'SERVICE3_PORTS': '80:unix://unix.socket', "SERVICE3_PORTS": "80:unix://unix.socket",
} }
monkeypatch.setattr(os, 'environ', env) monkeypatch.setattr(os, "environ", env)
onion = Onions() onion = Onions()
onion._get_setup_from_env() onion._get_setup_from_env()
onion_match = r'^[a-z2-7]{16}.onion$' onion_match = r"^[a-z2-7]{16}.onion$"
assert len(os.environ) == 6 assert len(os.environ) == 6
assert len(onion.services) == 2 assert len(onion.services) == 2
assert set( assert set(group.name for group in onion.services) == set(
group.name for group in onion.services ["group1", "group2"]
) == set(['group1', 'group2']) )
for group in onion.services: for group in onion.services:
if group.name == 'group1': if group.name == "group1":
assert len(group.services) == 2 assert len(group.services) == 2
assert set( assert set(service.host for service in group.services) == set(
service.host for service in group.services ["service1", "service2"]
) == set(['service1', 'service2']) )
if group.name == 'group2': if group.name == "group2":
assert len(group.services) == 1 assert len(group.services) == 1
assert set( assert set(service.host for service in group.services) == set(
service.host for service in group.services ["service3"]
) == set(['service3']) )
assert re.match(onion_match, group.onion_url) assert re.match(onion_match, group.onion_url)
def test_json(monkeypatch): def test_json(monkeypatch):
env = { env = {
'SERVICE1_SERVICE_NAME': 'group1', "SERVICE1_SERVICE_NAME": "group1",
'SERVICE2_SERVICE_NAME': 'group1', "SERVICE2_SERVICE_NAME": "group1",
'SERVICE3_SERVICE_NAME': 'group2', "SERVICE3_SERVICE_NAME": "group2",
'SERVICE1_PORTS': '80:80', "SERVICE1_PORTS": "80:80",
'SERVICE2_PORTS': '81:80,82:8000', "SERVICE2_PORTS": "81:80,82:8000",
'SERVICE3_PORTS': '80:unix://unix.socket', "SERVICE3_PORTS": "80:unix://unix.socket",
} }
monkeypatch.setattr(os, 'environ', env) monkeypatch.setattr(os, "environ", env)
onion = Onions() onion = Onions()
onion._get_setup_from_env() onion._get_setup_from_env()
@ -526,61 +582,188 @@ def test_json(monkeypatch):
jsn = json.loads(onion.to_json()) jsn = json.loads(onion.to_json())
assert len(jsn) == 2 assert len(jsn) == 2
assert len(jsn['group1']) == 3 assert len(jsn["group1"]) == 3
assert len(jsn['group2']) == 1 assert len(jsn["group2"]) == 1
def test_output(monkeypatch): def test_output(monkeypatch):
env = { env = {
'SERVICE1_SERVICE_NAME': 'group1', "SERVICE1_SERVICE_NAME": "group1",
'SERVICE2_SERVICE_NAME': 'group1', "SERVICE2_SERVICE_NAME": "group1",
'SERVICE3_SERVICE_NAME': 'group2', "SERVICE3_SERVICE_NAME": "group2",
'SERVICE1_PORTS': '80:80', "SERVICE1_PORTS": "80:80",
'SERVICE2_PORTS': '81:80,82:8000', "SERVICE2_PORTS": "81:80,82:8000",
'SERVICE3_PORTS': '80:unix://unix.socket', "SERVICE3_PORTS": "80:unix://unix.socket",
} }
monkeypatch.setattr(os, 'environ', env) monkeypatch.setattr(os, "environ", env)
onion = Onions() onion = Onions()
onion._get_setup_from_env() onion._get_setup_from_env()
for item in ['group1', 'group2', '.onion', ',']: for item in ["group1", "group2", ".onion", ","]:
assert item in str(onion) assert item in str(onion)
def test_not_valid_share_port(monkeypatch): def test_not_valid_share_port(monkeypatch):
env = { env = {
'SERVICE1_SERVICE_NAME': 'group1', "SERVICE1_SERVICE_NAME": "group1",
'SERVICE2_SERVICE_NAME': 'group1', "SERVICE2_SERVICE_NAME": "group1",
'SERVICE3_SERVICE_NAME': 'group2', "SERVICE3_SERVICE_NAME": "group2",
'SERVICE1_PORTS': '80:80', "SERVICE1_PORTS": "80:80",
'SERVICE2_PORTS': '80:80,82:8000', "SERVICE2_PORTS": "80:80,82:8000",
'SERVICE3_PORTS': '80:unix://unix.socket', "SERVICE3_PORTS": "80:unix://unix.socket",
} }
monkeypatch.setattr(os, 'environ', env) monkeypatch.setattr(os, "environ", env)
onion = Onions() onion = Onions()
onion._get_setup_from_env() onion._get_setup_from_env()
with pytest.raises(Exception) as excinfo: with pytest.raises(Exception) as excinfo:
onion.check_services() onion.check_services()
assert 'Same port for multiple services' in str(excinfo.value) assert "Same port for multiple services" in str(excinfo.value)
def test_not_valid_no_services(monkeypatch): def test_not_valid_no_services(monkeypatch):
env = { env = {
'SERVICE1_SERVICE_NAME': 'group1', "SERVICE1_SERVICE_NAME": "group1",
'SERVICE2_SERVICE_NAME': 'group1', "SERVICE2_SERVICE_NAME": "group1",
'SERVICE3_SERVICE_NAME': 'group2', "SERVICE3_SERVICE_NAME": "group2",
} }
monkeypatch.setattr(os, 'environ', env) monkeypatch.setattr(os, "environ", env)
onion = Onions() onion = Onions()
onion._get_setup_from_env() onion._get_setup_from_env()
with pytest.raises(Exception) as excinfo: with pytest.raises(Exception) as excinfo:
onion.check_services() onion.check_services()
assert 'has not ports set' in str(excinfo.value) assert "has not ports set" in str(excinfo.value)
def get_vanguards_template():
return r"""
## Global options
[Global]
{% if env.get('TOR_CONTROL_PORT', '').startswith('unix:') %}
{% set _, unix_path = env['TOR_CONTROL_PORT'].split(':', 1) %}
{% elif ':' in env.get('TOR_CONTROL_PORT', '') %}
{% set host, port = env['TOR_CONTROL_PORT'].split(':', 1) %}
{% else %}
{% set host = env.get('TOR_CONTROL_PORT') %}
{% endif %}
control_ip = {{ host or '' }}
control_port = {{ port or 9051 }}
control_socket = {{ unix_path or '' }}
control_pass = {{ env.get('TOR_CONTROL_PASSWORD', '') }}
state_file = {{ env.get('VANGUARDS_STATE_FILE', '/run/tor/data/vanguards.state') }}
{% if 'VANGUARDS_EXTRA_OPTIONS' in env %}
{% set extra_conf = ConfigParser().read_string(env['VANGUARDS_EXTRA_OPTIONS']) %}
{% if 'Global' in extra_conf %}
{% for key, val in extra_conf['Global'].items() %}
{{key}} = {{val}}
{% endfor %}
{% set _ = extra_conf.pop('Global') %}
{% endif %}
{{ extra_conf.to_string() }}
{% endif %}
""".strip() # noqa
def test_vanguards_configuration_sock(fs, monkeypatch):
extra_options = """
[Global]
enable_cbtverify = True
loglevel = DEBUG
[Rendguard]
rend_use_max_use_to_bw_ratio = 4.0
""".strip()
env = {
"TOR_ENABLE_VANGUARDS": "true",
"TOR_CONTROL_PORT": "unix:/path/to/sock",
"VANGUARDS_EXTRA_OPTIONS": extra_options,
}
monkeypatch.setattr(os, "environ", env)
monkeypatch.setattr(os, "fchmod", lambda x, y: None)
torrc_tpl = get_vanguards_template()
fs.create_file("/var/local/tor/vanguards.conf.tpl", contents=torrc_tpl)
fs.create_file("/etc/tor/vanguards.conf")
onion = Onions()
onion.resolve_control_port()
onion._setup_vanguards()
onion._write_vanguards_conf()
vanguard_conf = configparser.ConfigParser()
with open("/etc/tor/vanguards.conf", "r") as f:
print(f.read())
vanguard_conf.read("/etc/tor/vanguards.conf")
assert vanguard_conf["Global"]
assert not vanguard_conf["Global"]["control_ip"]
assert vanguard_conf["Global"]["control_port"] == "9051"
assert vanguard_conf["Global"]["control_socket"] == "/path/to/sock"
assert not vanguard_conf["Global"]["control_pass"]
assert (
vanguard_conf["Global"]["state_file"]
== "/run/tor/data/vanguards.state"
)
assert vanguard_conf["Global"]["enable_cbtverify"]
assert vanguard_conf["Global"]["loglevel"] == "DEBUG"
assert vanguard_conf["Rendguard"]["rend_use_max_use_to_bw_ratio"] == "4.0"
def test_vanguards_configuration_ip(fs, monkeypatch):
env = {
"TOR_ENABLE_VANGUARDS": "true",
"TOR_CONTROL_PORT": "127.0.0.1:7864",
"TOR_CONTROL_PASSWORD": "secret",
}
monkeypatch.setattr(os, "environ", env)
monkeypatch.setattr(os, "fchmod", lambda x, y: None)
torrc_tpl = get_vanguards_template()
fs.create_file("/var/local/tor/vanguards.conf.tpl", contents=torrc_tpl)
fs.create_file("/etc/tor/vanguards.conf")
onion = Onions()
onion.resolve_control_port()
onion._setup_vanguards()
onion._write_vanguards_conf()
vanguard_conf = configparser.ConfigParser()
with open("/etc/tor/vanguards.conf", "r") as f:
print(f.read())
vanguard_conf.read("/etc/tor/vanguards.conf")
assert vanguard_conf["Global"]
assert vanguard_conf["Global"]["control_ip"] == "127.0.0.1"
assert vanguard_conf["Global"]["control_port"] == "7864"
assert not vanguard_conf["Global"]["control_socket"]
assert vanguard_conf["Global"]["control_pass"] == "secret"
assert (
vanguard_conf["Global"]["state_file"]
== "/run/tor/data/vanguards.state"
)

Loading…
Cancel
Save