mirror of
https://github.com/cmehay/docker-tor-hidden-service.git
synced 2025-05-27 04:07:13 +00:00
Add tor v3 addresses support
This commit is contained in:
parent
8d562ed2e6
commit
d3252e276e
24 changed files with 1086 additions and 225 deletions
|
@ -2,6 +2,7 @@ import json
|
|||
import os
|
||||
import re
|
||||
from base64 import b32encode
|
||||
from base64 import b64decode
|
||||
from hashlib import sha1
|
||||
|
||||
import pytest
|
||||
|
@ -9,8 +10,9 @@ from Crypto.PublicKey import RSA
|
|||
from onions import Onions
|
||||
|
||||
|
||||
def get_key_and_onion():
|
||||
key = '''
|
||||
def get_key_and_onion(version=2):
|
||||
key = {}
|
||||
key[2] = '''
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQCsMP4gl6g1Q313miPhb1GnDr56ZxIWGsO2PwHM1infkbhlBakR
|
||||
6DGQfpE31L1ZKTUxY0OexKbW088v8qCOfjD9Zk1i80JP4xzfWQcwFZ5yM/0fkhm3
|
||||
|
@ -27,24 +29,40 @@ La/7Syrnobngsh/vX90CQB+PSSBqiPSsK2yPz6Gsd6OLCQ9sdy2oRwFTasH8sZyl
|
|||
bhJ3M9WzP/EMkAzyW8mVs1moFp3hRcfQlZHl6g1U9D8=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
'''
|
||||
|
||||
onion = b32encode(
|
||||
onion = {}
|
||||
pub = {}
|
||||
onion[2] = b32encode(
|
||||
sha1(
|
||||
RSA.importKey(
|
||||
key.strip()
|
||||
key[2].strip()
|
||||
).publickey().exportKey(
|
||||
"DER"
|
||||
)[22:]
|
||||
).digest()[:10]
|
||||
).decode().lower() + '.onion'
|
||||
|
||||
return key.strip(), onion
|
||||
key[3] = '''
|
||||
PT0gZWQyNTUxOXYxLXNlY3JldDogdHlwZTAgPT0AAACArobDQYyZAWXei4QZwr++j96H1X/gq14N
|
||||
wLRZ2O5DXuL0EzYKkdhZSILY85q+kfwZH8z4ceqe7u1F+0pQi/sM
|
||||
'''
|
||||
|
||||
pub[3] = '''
|
||||
PT0gZWQyNTUxOXYxLXB1YmxpYzogdHlwZTAgPT0AAAC9kzftiea/kb+TWlCEVNpfUJLVk+rFIoMG
|
||||
m9/hW13isA==
|
||||
'''
|
||||
|
||||
onion[3] = 'xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion'
|
||||
|
||||
return key[version].strip(), onion[version]
|
||||
|
||||
|
||||
def get_torrc_template():
|
||||
return r'''
|
||||
{% for service_group in services %}
|
||||
HiddenServiceDir /var/lib/tor/hidden_service/{{service_group.name}}
|
||||
HiddenServiceDir {{service_group.hidden_service_dir}}
|
||||
{% if service_group.version == 3 %}
|
||||
HiddenServiceVersion 3
|
||||
{% endif %}
|
||||
{% for service in service_group.services %}
|
||||
{% for port in service.ports %}
|
||||
{% if port.is_socket %}
|
||||
|
@ -155,7 +173,7 @@ ff02::2 ip6-allrouters
|
|||
172.17.0.2 compose_service1_1 bf447f22cdba
|
||||
'''.strip()
|
||||
|
||||
fs.CreateFile('/etc/hosts', contents=etc_host)
|
||||
fs.create_file('/etc/hosts', contents=etc_host)
|
||||
|
||||
monkeypatch.setattr(os, 'environ', env)
|
||||
|
||||
|
@ -190,34 +208,57 @@ def test_key(monkeypatch):
|
|||
assert onion.services[0].onion_url == onion_url
|
||||
|
||||
|
||||
def test_key_in_secret(fs, monkeypatch):
|
||||
def test_key_v3(monkeypatch):
|
||||
key, onion_url = get_key_and_onion(version=3)
|
||||
env = {
|
||||
'SERVICE1_SERVICE_NAME': 'group1',
|
||||
'SERVICE2_SERVICE_NAME': 'group1',
|
||||
'SERVICE3_SERVICE_NAME': 'group2',
|
||||
'SERVICE1_PORTS': '80:80',
|
||||
'SERVICE2_PORTS': '81:80,82:8000',
|
||||
'SERVICE3_PORTS': '80:unix://unix.socket',
|
||||
'GROUP1_TOR_SERVICE_HOSTS': '80:service1:80,81:service2:80',
|
||||
'GROUP1_TOR_SERVICE_VERSION': '3',
|
||||
'GROUP1_TOR_SERVICE_KEY': key,
|
||||
}
|
||||
|
||||
monkeypatch.setattr(os, 'environ', env)
|
||||
|
||||
key, onion_url = get_key_and_onion()
|
||||
onion = Onions()
|
||||
onion._get_setup_from_env()
|
||||
onion._load_keys_in_services()
|
||||
|
||||
fs.CreateFile('/run/secrets/group1', contents=key)
|
||||
assert len(os.environ) == 3
|
||||
assert len(onion.services) == 1
|
||||
|
||||
assert onion.services[0].onion_url == onion_url
|
||||
|
||||
|
||||
def test_key_in_secret(fs, monkeypatch):
|
||||
env = {
|
||||
'GROUP1_TOR_SERVICE_HOSTS': '80:service1:80',
|
||||
'GROUP2_TOR_SERVICE_HOSTS': '80:service2:80',
|
||||
'GROUP3_TOR_SERVICE_HOSTS': '80:service3:80',
|
||||
'GROUP3_TOR_SERVICE_VERSION': '3',
|
||||
}
|
||||
|
||||
monkeypatch.setattr(os, 'environ', env)
|
||||
|
||||
key_v2, onion_url_v2 = get_key_and_onion()
|
||||
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/group3', contents=b64decode(key_v3))
|
||||
|
||||
onion = Onions()
|
||||
onion._get_setup_from_env()
|
||||
onion._load_keys_in_services()
|
||||
|
||||
group1 = onion.find_group_by_name('group1')
|
||||
group2 = onion.find_group_by_name('group2')
|
||||
group3 = onion.find_group_by_name('group3')
|
||||
|
||||
# assert group._priv_key == key
|
||||
assert group1.onion_url == onion_url
|
||||
assert group2.onion_url != onion_url
|
||||
assert group1.onion_url == onion_url_v2
|
||||
assert group2.onion_url not in [onion_url_v2, onion_url_v3]
|
||||
assert group3.onion_url == onion_url_v3
|
||||
|
||||
|
||||
def test_configuration(fs, monkeypatch):
|
||||
def test_configuration(fs, monkeypatch, tmpdir):
|
||||
|
||||
env = {
|
||||
'SERVICE1_SERVICE_NAME': 'group1',
|
||||
'SERVICE2_SERVICE_NAME': 'group1',
|
||||
|
@ -225,44 +266,72 @@ def test_configuration(fs, monkeypatch):
|
|||
'SERVICE1_PORTS': '80:80',
|
||||
'SERVICE2_PORTS': '81:80,82:8000',
|
||||
'SERVICE3_PORTS': '80:unix://unix.socket',
|
||||
'GROUP3_TOR_SERVICE_VERSION': '2',
|
||||
'GROUP3_TOR_SERVICE_HOSTS': '80:service4:888,81:service5:8080',
|
||||
'GROUP4_TOR_SERVICE_VERSION': '3',
|
||||
'GROUP4_TOR_SERVICE_HOSTS': '81:unix://unix2.sock',
|
||||
'GROUP3V3_TOR_SERVICE_VERSION': '3',
|
||||
'GROUP3V3_TOR_SERVICE_HOSTS': '80:service4:888,81:service5:8080',
|
||||
'SERVICE5_TOR_SERVICE_HOSTS': '80:service5:80'
|
||||
}
|
||||
|
||||
hidden_dir = '/var/lib/tor/hidden_service'
|
||||
|
||||
monkeypatch.setattr(os, 'environ', env)
|
||||
monkeypatch.setattr(os, 'fchmod', lambda x, y: None)
|
||||
|
||||
key, onion_url = get_key_and_onion()
|
||||
torrc_tpl = get_torrc_template()
|
||||
|
||||
fs.CreateFile('/var/local/tor/torrc.tpl', contents=torrc_tpl)
|
||||
fs.CreateFile('/etc/tor/torrc')
|
||||
fs.create_file('/var/local/tor/torrc.tpl', contents=torrc_tpl)
|
||||
fs.create_file('/etc/tor/torrc')
|
||||
fs.create_dir(hidden_dir)
|
||||
|
||||
onion = Onions()
|
||||
onion._get_setup_from_env()
|
||||
onion._load_keys_in_services()
|
||||
onion.apply_conf()
|
||||
|
||||
onions_urls = {}
|
||||
for dir in os.listdir(hidden_dir):
|
||||
with open(os.path.join(hidden_dir, dir, 'hostname'), 'r') as f:
|
||||
onions_urls[dir] = f.read().strip()
|
||||
|
||||
with open('/etc/tor/torrc', 'r') as f:
|
||||
torrc = f.read()
|
||||
|
||||
print(torrc)
|
||||
assert 'HiddenServiceDir /var/lib/tor/hidden_service/group1' in torrc
|
||||
assert 'HiddenServicePort 80 service1:80' in torrc
|
||||
assert 'HiddenServicePort 81 service2:80' in torrc
|
||||
assert 'HiddenServicePort 82 service2:8000' in torrc
|
||||
assert 'HiddenServiceDir /var/lib/tor/hidden_service/group2' 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/group4' in torrc
|
||||
assert 'HiddenServiceDir /var/lib/tor/hidden_service/group3v3' in torrc
|
||||
assert 'HiddenServiceDir /var/lib/tor/hidden_service/service5' in torrc
|
||||
assert torrc.count('HiddenServicePort 80 service4:888') == 2
|
||||
assert torrc.count('HiddenServicePort 81 service5:8080') == 2
|
||||
assert torrc.count('HiddenServicePort 80 service5:80') == 1
|
||||
assert torrc.count('HiddenServicePort 81 unix://unix2.sock') == 1
|
||||
assert torrc.count('HiddenServiceVersion 3') == 2
|
||||
|
||||
# Check parser
|
||||
onion2 = Onions()
|
||||
onion2.torrc_parser()
|
||||
|
||||
assert len(onion2.services) == 2
|
||||
assert len(onion2.services) == 6
|
||||
|
||||
assert set(
|
||||
group.name for group in onion2.services
|
||||
) == set(['group1', 'group2'])
|
||||
# ) == set(['group1', 'group2'])
|
||||
) == set(['group1', 'group2', 'group3', 'group4', 'group3v3', 'service5'])
|
||||
|
||||
for group in onion2.services:
|
||||
if group.name == 'group1':
|
||||
assert len(group.services) == 2
|
||||
assert group.version == 2
|
||||
assert group.onion_url == onions_urls[group.name]
|
||||
assert set(
|
||||
service.host for service in group.services
|
||||
) == set(['service1', 'service2'])
|
||||
|
@ -279,6 +348,8 @@ def test_configuration(fs, monkeypatch):
|
|||
) == set([(81, 80), (82, 8000)])
|
||||
if group.name == 'group2':
|
||||
assert len(group.services) == 1
|
||||
assert group.version == 2
|
||||
assert group.onion_url == onions_urls[group.name]
|
||||
assert set(
|
||||
service.host for service in group.services
|
||||
) == set(['group2'])
|
||||
|
@ -288,6 +359,53 @@ def test_configuration(fs, monkeypatch):
|
|||
(port.port_from, port.dest) for port in service.ports
|
||||
) == set([(80, 'unix://unix.socket')])
|
||||
|
||||
if group.name in ['group3', 'group3v3']:
|
||||
assert len(group.services) == 2
|
||||
assert group.version == 2 if group.name == 'group3' else 3
|
||||
assert group.onion_url == onions_urls[group.name]
|
||||
assert set(
|
||||
service.host for service in group.services
|
||||
) == set(['service4', 'service5'])
|
||||
for service in group.services:
|
||||
if service.host == 'service4':
|
||||
assert len(service.ports) == 1
|
||||
assert set(
|
||||
(port.port_from, port.dest) for port in service.ports
|
||||
) == set([(80, 888)])
|
||||
if service.host == 'service5':
|
||||
assert len(service.ports) == 1
|
||||
assert set(
|
||||
(port.port_from, port.dest) for port in service.ports
|
||||
) == set([(81, 8080)])
|
||||
|
||||
if group.name == 'group4':
|
||||
assert len(group.services) == 1
|
||||
assert group.version == 3
|
||||
assert group.onion_url == onions_urls[group.name]
|
||||
assert set(
|
||||
service.host for service in group.services
|
||||
) == set(['group4'])
|
||||
for service in group.services:
|
||||
assert service.host == 'group4'
|
||||
assert len(service.ports) == 1
|
||||
assert set(
|
||||
(port.port_from, port.dest) for port in service.ports
|
||||
) == set([(81, 'unix://unix2.sock')])
|
||||
|
||||
if group.name == 'service5':
|
||||
assert len(group.services) == 1
|
||||
assert group.version == 2
|
||||
assert group.onion_url == onions_urls[group.name]
|
||||
assert set(
|
||||
service.host for service in group.services
|
||||
) == set(['service5'])
|
||||
for service in group.services:
|
||||
assert service.host == 'service5'
|
||||
assert len(service.ports) == 1
|
||||
assert set(
|
||||
(port.port_from, port.dest) for port in service.ports
|
||||
) == set([(80, 80)])
|
||||
|
||||
|
||||
def test_groups(monkeypatch):
|
||||
env = {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue