Drop support for onion addresses v2

* Update `onions` tool to v0.7.0
 * Update `tor` to `0.4.6.9`
pull/82/head
Chirstophe Mehay 2 years ago committed by Christophe Mehay
parent d0dd28733d
commit 2fc3b6eb84

@ -34,8 +34,6 @@ rebuild:
docker-compose -f docker-compose.build.yml build --no-cache --pull docker-compose -f docker-compose.build.yml build --no-cache --pull
run: build run: build
docker-compose -f docker-compose.v1.yml up --force-recreate
run-v2: build
docker-compose -f docker-compose.v2.yml up --force-recreate docker-compose -f docker-compose.v2.yml up --force-recreate
run-v2-socket: build run-v2-socket: build

@ -2,6 +2,13 @@
[![Build Status](https://travis-ci.org/cmehay/docker-tor-hidden-service.svg?branch=master)](https://travis-ci.org/cmehay/docker-tor-hidden-service) [![Build Status](https://travis-ci.org/cmehay/docker-tor-hidden-service.svg?branch=master)](https://travis-ci.org/cmehay/docker-tor-hidden-service)
## Changelog
* 23 dec 2021
* Update `onions` tool to v0.7.0:
* Drop support of onion v2 adresses as tor network does not accept them anymore
* Update `tor` to `0.4.6.9`
## Setup ## Setup
### Setup hosts ### Setup hosts
@ -19,60 +26,34 @@ services:
- world - world
- again - again
environment: environment:
# Set mapping ports
SERVICE1_TOR_SERVICE_HOSTS: 80:hello:80,800:hello:80,8888:hello:80
# Set private key
SERVICE1_TOR_SERVICE_KEY: |
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDR8TdQF9fDlGhy1SMgfhMBi9TaFeD12/FK27TZE/tYGhxXvs1C
NmFJy1hjVxspF5unmUsCk0yEsvEdcAdp17Vynz6W41VdinETU9yXHlUJ6NyI32AH
dnFnHEcsllSEqD1hPAAvMUWwSMJaNmBEFtl8DUMS9tPX5fWGX4w5Xx8dZwIDAQAB
AoGBAMb20jMHxaZHWg2qTRYYJa8LdHgS0BZxkWYefnBUbZn7dOz7mM+tddpX6raK
8OSqyQu3Tc1tB9GjPLtnVr9KfVwhUVM7YXC/wOZo+u72bv9+4OMrEK/R8xy30XWj
GePXEu95yArE4NucYphxBLWMMu2E4RodjyJpczsl0Lohcn4BAkEA+XPaEKnNA3AL
1DXRpSpaa0ukGUY/zM7HNUFMW3UP00nxNCpWLSBmrQ56Suy7iSy91oa6HWkDD/4C
k0HslnMW5wJBANdz4ehByMJZmJu/b5y8wnFSqep2jmJ1InMvd18BfVoBTQJwGMAr
+qwSwNXXK2YYl9VJmCPCfgN0o7h1AEzvdYECQAM5UxUqDKNBvHVmqKn4zShb1ugY
t1RfS8XNbT41WhoB96MT9P8qTwlniX8UZiwUrvNp1Ffy9n4raz8Z+APNwvsCQQC9
AuaOsReEmMFu8VTjNh2G+TQjgvqKmaQtVNjuOgpUKYv7tYehH3P7/T+62dcy7CRX
cwbLaFbQhUUUD2DCHdkBAkB6CbB+qhu67oE4nnBCXllI9EXktXgFyXv/cScNvM9Y
FDzzNAAfVc5Nmbmx28Nw+0w6pnpe/3m0Tudbq3nHdHfQ
-----END RSA PRIVATE KEY-----
# hello and again will share the same onion v3 address # hello and again will share the same onion v3 address
SERVICE2_TOR_SERVICE_HOSTS: 88:again:80,8000:world:80 SERVICE1_TOR_SERVICE_HOSTS: 88:hello:80,8000:world:80
SERVICE2_TOR_SERVICE_VERSION: '3' # Optional as tor version 2 is not supported anymore
SERVICE1_TOR_SERVICE_VERSION: '3'
# tor v3 address private key base 64 encoded # tor v3 address private key base 64 encoded
SERVICE2_TOR_SERVICE_KEY: | SERVICE1_TOR_SERVICE_KEY: |
PT0gZWQyNTUxOXYxLXNlY3JldDogdHlwZTAgPT0AAACArobDQYyZAWXei4QZwr++ PT0gZWQyNTUxOXYxLXNlY3JldDogdHlwZTAgPT0AAACArobDQYyZAWXei4QZwr++
j96H1X/gq14NwLRZ2O5DXuL0EzYKkdhZSILY85q+kfwZH8z4ceqe7u1F+0pQi/sM j96H1X/gq14NwLRZ2O5DXuL0EzYKkdhZSILY85q+kfwZH8z4ceqe7u1F+0pQi/sM
hello:
image: tutum/hello-world
hostname: hello
world: world:
image: tutum/hello-world image: tutum/hello-world
hostname: world hostname: world
again: hello:
image: tutum/hello-world image: tutum/hello-world
hostname: again hostname: hello
``` ```
This configuration will output: This configuration will output:
``` ```
service2: xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion:88, xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion:8000 service1: xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion:88, xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion:8000
service1: 5azvyr7dvvr4cldn.onion:80, 5azvyr7dvvr4cldn.onion:800, 5azvyr7dvvr4cldn.onion:8888
``` ```
`xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion:88` will hit `again:80`. `xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion:88` will hit `again:80`.
`xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion:8000` will hit `wold:80`. `xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion:8000` will hit `wold:80`.
`5azvyr7dvvr4cldn.onion:80` will hit `hello:80`.
`5azvyr7dvvr4cldn.onion:800` will hit `hello:80` too.
`5azvyr7dvvr4cldn.onion:8888` will hit `hello:80` again.
#### Environment variables #### Environment variables
@ -90,34 +71,17 @@ You can concatenate services using comas.
##### `{SERVICE}_TOR_SERVICE_VERSION` ##### `{SERVICE}_TOR_SERVICE_VERSION`
Can be `2` or `3`. Set the tor address type. Optionnal now, can only be `3`. Set the tor address type.
> **WARNING**: Version 2 is not supported anymore by tor network
`2` gives short addresses `5azvyr7dvvr4cldn.onion` and `3` long addresses `xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion` `2` was giving short addresses `5azvyr7dvvr4cldn.onion` and `3` gives long addresses `xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion`
##### `{SERVICE}_TOR_SERVICE_KEY` ##### `{SERVICE}_TOR_SERVICE_KEY`
You can set the private key for the current service. You can set the private key for the current service.
Tor v2 addresses uses RSA PEM keys like:
```
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDR8TdQF9fDlGhy1SMgfhMBi9TaFeD12/FK27TZE/tYGhxXvs1C
NmFJy1hjVxspF5unmUsCk0yEsvEdcAdp17Vynz6W41VdinETU9yXHlUJ6NyI32AH
dnFnHEcsllSEqD1hPAAvMUWwSMJaNmBEFtl8DUMS9tPX5fWGX4w5Xx8dZwIDAQAB
AoGBAMb20jMHxaZHWg2qTRYYJa8LdHgS0BZxkWYefnBUbZn7dOz7mM+tddpX6raK
8OSqyQu3Tc1tB9GjPLtnVr9KfVwhUVM7YXC/wOZo+u72bv9+4OMrEK/R8xy30XWj
GePXEu95yArE4NucYphxBLWMMu2E4RodjyJpczsl0Lohcn4BAkEA+XPaEKnNA3AL
1DXRpSpaa0ukGUY/zM7HNUFMW3UP00nxNCpWLSBmrQ56Suy7iSy91oa6HWkDD/4C
k0HslnMW5wJBANdz4ehByMJZmJu/b5y8wnFSqep2jmJ1InMvd18BfVoBTQJwGMAr
+qwSwNXXK2YYl9VJmCPCfgN0o7h1AEzvdYECQAM5UxUqDKNBvHVmqKn4zShb1ugY
t1RfS8XNbT41WhoB96MT9P8qTwlniX8UZiwUrvNp1Ffy9n4raz8Z+APNwvsCQQC9
AuaOsReEmMFu8VTjNh2G+TQjgvqKmaQtVNjuOgpUKYv7tYehH3P7/T+62dcy7CRX
cwbLaFbQhUUUD2DCHdkBAkB6CbB+qhu67oE4nnBCXllI9EXktXgFyXv/cScNvM9Y
FDzzNAAfVc5Nmbmx28Nw+0w6pnpe/3m0Tudbq3nHdHfQ
-----END RSA PRIVATE KEY-----
```
Tor v3 addresses uses ed25519 binary keys. It should be base64 encoded: Tor v3 addresses uses ed25519 binary keys. It should be base64 encoded:
``` ```
PT0gZWQyNTUxOXYxLXNlY3JldDogdHlwZTAgPT0AAACArobDQYyZAWXei4QZwr++j96H1X/gq14NwLRZ2O5DXuL0EzYKkdhZSILY85q+kfwZH8z4ceqe7u1F+0pQi/sM PT0gZWQyNTUxOXYxLXNlY3JldDogdHlwZTAgPT0AAACArobDQYyZAWXei4QZwr++j96H1X/gq14NwLRZ2O5DXuL0EzYKkdhZSILY85q+kfwZH8z4ceqe7u1F+0pQi/sM
@ -153,12 +117,12 @@ A command line tool `onions` is available in container to get `.onion` url when
```sh ```sh
# Get services # Get services
$ docker exec -ti torhiddenproxy_tor_1 onions $ docker exec -ti torhiddenproxy_tor_1 onions
hello: vegm3d7q64gutl75.onion:80 hello: xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion:80
world: b2sflntvdne63amj.onion:80 world: .onion:80
# Get json # Get json
$ docker exec -ti torhiddenproxy_tor_1 onions --json $ docker exec -ti torhiddenproxy_tor_1 onions --json
{"hello": ["b2sflntvdne63amj.onion:80"], "world": ["vegm3d7q64gutl75.onion:80"]} {"hello": ["xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion:80"], "world": ["ootceq7skq7qpvvwf2tajeboxovalco7z3ka44vxbtfdr2tfvx5ld7ad.onion:80"]}
``` ```
### Auto reload ### Auto reload
@ -175,8 +139,6 @@ Container version will follow tor release versions.
This container uses [`pyentrypoint`](https://github.com/cmehay/pyentrypoint) to generate its setup. This container uses [`pyentrypoint`](https://github.com/cmehay/pyentrypoint) to generate its setup.
If you need to use the legacy version, please checkout the `legacy` branch or pull `goldy/tor-hidden-service:legacy`.
### pytor ### pytor
This containner uses [`pytor`](https://github.com/cmehay/pytor) to mannages tor cryptography, generate keys and compute onion urls. This containner uses [`pytor`](https://github.com/cmehay/pytor) to mannages tor cryptography, generate keys and compute onion urls.
@ -225,131 +187,3 @@ The following settings cannot me changer with this variable:
- use `TOR_CONTROL_PASSWORD` - use `TOR_CONTROL_PASSWORD`
- `state_file`: - `state_file`:
- use `VANGUARDS_STATE_FILE` - use `VANGUARDS_STATE_FILE`
# 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.
### Create a tor hidden service with a link
```sh
# run a container with a network application
$ docker run -d --name hello_world tutum/hello-world
# and just link it to this container
$ docker run -ti --link hello_world goldy/tor-hidden-service
```
The .onion URLs are displayed to stdout at startup.
To keep onion keys, just mount volume `/var/lib/tor/hidden_service/`
```sh
$ docker run -ti --link something --volume /path/to/keys:/var/lib/tor/hidden_service/ goldy/tor-hidden-service
```
Look at the `docker-compose.yml` file to see how to use it.
### Set private key
Private key is settable by environment or by copying file in `hostname/private_key` in docker volume (`hostname` is the link name).
It's easier to pass key in environment with `docker-compose`.
```yaml
links:
- hello
- world
environment:
# Set private key
HELLO_KEY: |
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDR8TdQF9fDlGhy1SMgfhMBi9TaFeD12/FK27TZE/tYGhxXvs1C
NmFJy1hjVxspF5unmUsCk0yEsvEdcAdp17Vynz6W41VdinETU9yXHlUJ6NyI32AH
dnFnHEcsllSEqD1hPAAvMUWwSMJaNmBEFtl8DUMS9tPX5fWGX4w5Xx8dZwIDAQAB
AoGBAMb20jMHxaZHWg2qTRYYJa8LdHgS0BZxkWYefnBUbZn7dOz7mM+tddpX6raK
8OSqyQu3Tc1tB9GjPLtnVr9KfVwhUVM7YXC/wOZo+u72bv9+4OMrEK/R8xy30XWj
GePXEu95yArE4NucYphxBLWMMu2E4RodjyJpczsl0Lohcn4BAkEA+XPaEKnNA3AL
1DXRpSpaa0ukGUY/zM7HNUFMW3UP00nxNCpWLSBmrQ56Suy7iSy91oa6HWkDD/4C
k0HslnMW5wJBANdz4ehByMJZmJu/b5y8wnFSqep2jmJ1InMvd18BfVoBTQJwGMAr
+qwSwNXXK2YYl9VJmCPCfgN0o7h1AEzvdYECQAM5UxUqDKNBvHVmqKn4zShb1ugY
t1RfS8XNbT41WhoB96MT9P8qTwlniX8UZiwUrvNp1Ffy9n4raz8Z+APNwvsCQQC9
AuaOsReEmMFu8VTjNh2G+TQjgvqKmaQtVNjuOgpUKYv7tYehH3P7/T+62dcy7CRX
cwbLaFbQhUUUD2DCHdkBAkB6CbB+qhu67oE4nnBCXllI9EXktXgFyXv/cScNvM9Y
FDzzNAAfVc5Nmbmx28Nw+0w6pnpe/3m0Tudbq3nHdHfQ
-----END RSA PRIVATE KEY-----
```
Options are set using the following pattern: `LINKNAME_KEY`
### Setup port
__Caution__: Using `PORT_MAP` with multiple ports on single service will cause `tor` to fail.
Use link setting in environment with the following pattern: `LINKNAME_PORTS`.
Like docker, first port is exposed port and the second one is service internal port.
```yaml
links:
- hello
- world
- hey
environment:
# Set mapping ports
HELLO_PORTS: 80:80
# Multiple ports can be coma separated
WORLD_PORTS: 8000:80,8888:80,22:22
# Socket mapping is supported
HEY_PORTS: 80:unix:/var/run/socket.sock
```
__DEPRECATED:__
By default, ports are the same as linked containers, but a default port can be mapped using `PORT_MAP` environment variable.
#### Socket
To increase security, it's possible to setup your service through socket between containers and turn off network in your app container. See `docker-compose.v2.sock.yml` for an example.
__Warning__: Due to a bug in `tor` configuration parser, it's not possible to mix network link and socket link in the same `tor` configuration.
### Group services
Multiple services can be hosted behind the same onion address.
```yaml
links:
- hello
- world
- hey
environment:
# Set mapping ports
HELLO_PORTS: 80:80
# Multiple ports can be coma separated
WORLD_PORTS: 8000:80,8888:80,22:22
# Socket mapping is supported
HEY_PORTS: 80:unix:/var/run/socket.sock
# hello and world will share the same onion address
# Service name can be any string as long there is not special char
HELLO_SERVICE_NAME: foo
WORLD_SERVICE_NAME: foo
```
__Warning__: Be carefull to not use the same exposed ports for grouped services.
### Compose v2 support
Links setting are required when using docker-compose v2. See `docker-compose.v2.yml` for example.
### Copose v3 support and secrets
Links setting are required when using docker-compose v3. See `docker-compose.v3.yml` for example.

@ -1 +1 @@
0.4.6.7 0.4.6.9

@ -1,21 +0,0 @@
# docker-compose.yml example
# LEGACY CONFIGURATION
# SEE README FOR INFORMATIONS
tor:
image: goldy/tor-hidden-service:$CUR_TAG
links:
- hello
- world
environment:
PORT_MAP: 80 # Map port to detected service
volumes:
- ./keys:/var/lib/tor/hidden_service/
hello:
image: tutum/hello-world
hostname: hello
world:
image: tutum/hello-world
hostname: world

@ -1,59 +0,0 @@
# docker version 2 example
version: "2"
services:
tor:
image: goldy/tor-hidden-service:$CUR_TAG
links:
- hello
- world
- again
environment:
# Set mapping ports
HELLO_PORTS: 80:80,800:80,8888:80
# Set private key
HELLO_KEY: |
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDR8TdQF9fDlGhy1SMgfhMBi9TaFeD12/FK27TZE/tYGhxXvs1C
NmFJy1hjVxspF5unmUsCk0yEsvEdcAdp17Vynz6W41VdinETU9yXHlUJ6NyI32AH
dnFnHEcsllSEqD1hPAAvMUWwSMJaNmBEFtl8DUMS9tPX5fWGX4w5Xx8dZwIDAQAB
AoGBAMb20jMHxaZHWg2qTRYYJa8LdHgS0BZxkWYefnBUbZn7dOz7mM+tddpX6raK
8OSqyQu3Tc1tB9GjPLtnVr9KfVwhUVM7YXC/wOZo+u72bv9+4OMrEK/R8xy30XWj
GePXEu95yArE4NucYphxBLWMMu2E4RodjyJpczsl0Lohcn4BAkEA+XPaEKnNA3AL
1DXRpSpaa0ukGUY/zM7HNUFMW3UP00nxNCpWLSBmrQ56Suy7iSy91oa6HWkDD/4C
k0HslnMW5wJBANdz4ehByMJZmJu/b5y8wnFSqep2jmJ1InMvd18BfVoBTQJwGMAr
+qwSwNXXK2YYl9VJmCPCfgN0o7h1AEzvdYECQAM5UxUqDKNBvHVmqKn4zShb1ugY
t1RfS8XNbT41WhoB96MT9P8qTwlniX8UZiwUrvNp1Ffy9n4raz8Z+APNwvsCQQC9
AuaOsReEmMFu8VTjNh2G+TQjgvqKmaQtVNjuOgpUKYv7tYehH3P7/T+62dcy7CRX
cwbLaFbQhUUUD2DCHdkBAkB6CbB+qhu67oE4nnBCXllI9EXktXgFyXv/cScNvM9Y
FDzzNAAfVc5Nmbmx28Nw+0w6pnpe/3m0Tudbq3nHdHfQ
-----END RSA PRIVATE KEY-----
WORLD_PORTS: 8000:80
AGAIN_PORTS: 88:80
# hello and again will share the same onion_adress
AGAIN_SERVICE_NAME: foo
HELLO_SERVICE_NAME: foo
# Keep keys in volumes
volumes:
- tor-keys:/var/lib/tor/hidden_service/
hello:
image: tutum/hello-world
hostname: hello
world:
image: tutum/hello-world
hostname: world
again:
image: tutum/hello-world
hostname: again
volumes:
tor-keys:
driver: local

@ -10,29 +10,31 @@ services:
- world - world
- again - again
environment: environment:
# Set mapping ports ######################################################################
HELLO_TOR_SERVICE_HOSTS: 80:hello:80,800:hello:80,8888:hello:80 ### TOR ADDRESSES VERSION 2 ARE NOT SUPPORTED ANYMORE ###
# Set private key ######################################################################
HELLO_TOR_SERVICE_KEY: | # # Set mapping ports
-----BEGIN RSA PRIVATE KEY----- # HELLO_TOR_SERVICE_HOSTS: 80:hello:80,800:hello:80,8888:hello:80
MIICXQIBAAKBgQDR8TdQF9fDlGhy1SMgfhMBi9TaFeD12/FK27TZE/tYGhxXvs1C # # Set private key
NmFJy1hjVxspF5unmUsCk0yEsvEdcAdp17Vynz6W41VdinETU9yXHlUJ6NyI32AH # HELLO_TOR_SERVICE_KEY: |
dnFnHEcsllSEqD1hPAAvMUWwSMJaNmBEFtl8DUMS9tPX5fWGX4w5Xx8dZwIDAQAB # -----BEGIN RSA PRIVATE KEY-----
AoGBAMb20jMHxaZHWg2qTRYYJa8LdHgS0BZxkWYefnBUbZn7dOz7mM+tddpX6raK # MIICXQIBAAKBgQDR8TdQF9fDlGhy1SMgfhMBi9TaFeD12/FK27TZE/tYGhxXvs1C
8OSqyQu3Tc1tB9GjPLtnVr9KfVwhUVM7YXC/wOZo+u72bv9+4OMrEK/R8xy30XWj # NmFJy1hjVxspF5unmUsCk0yEsvEdcAdp17Vynz6W41VdinETU9yXHlUJ6NyI32AH
GePXEu95yArE4NucYphxBLWMMu2E4RodjyJpczsl0Lohcn4BAkEA+XPaEKnNA3AL # dnFnHEcsllSEqD1hPAAvMUWwSMJaNmBEFtl8DUMS9tPX5fWGX4w5Xx8dZwIDAQAB
1DXRpSpaa0ukGUY/zM7HNUFMW3UP00nxNCpWLSBmrQ56Suy7iSy91oa6HWkDD/4C # AoGBAMb20jMHxaZHWg2qTRYYJa8LdHgS0BZxkWYefnBUbZn7dOz7mM+tddpX6raK
k0HslnMW5wJBANdz4ehByMJZmJu/b5y8wnFSqep2jmJ1InMvd18BfVoBTQJwGMAr # 8OSqyQu3Tc1tB9GjPLtnVr9KfVwhUVM7YXC/wOZo+u72bv9+4OMrEK/R8xy30XWj
+qwSwNXXK2YYl9VJmCPCfgN0o7h1AEzvdYECQAM5UxUqDKNBvHVmqKn4zShb1ugY # GePXEu95yArE4NucYphxBLWMMu2E4RodjyJpczsl0Lohcn4BAkEA+XPaEKnNA3AL
t1RfS8XNbT41WhoB96MT9P8qTwlniX8UZiwUrvNp1Ffy9n4raz8Z+APNwvsCQQC9 # 1DXRpSpaa0ukGUY/zM7HNUFMW3UP00nxNCpWLSBmrQ56Suy7iSy91oa6HWkDD/4C
AuaOsReEmMFu8VTjNh2G+TQjgvqKmaQtVNjuOgpUKYv7tYehH3P7/T+62dcy7CRX # k0HslnMW5wJBANdz4ehByMJZmJu/b5y8wnFSqep2jmJ1InMvd18BfVoBTQJwGMAr
cwbLaFbQhUUUD2DCHdkBAkB6CbB+qhu67oE4nnBCXllI9EXktXgFyXv/cScNvM9Y # +qwSwNXXK2YYl9VJmCPCfgN0o7h1AEzvdYECQAM5UxUqDKNBvHVmqKn4zShb1ugY
FDzzNAAfVc5Nmbmx28Nw+0w6pnpe/3m0Tudbq3nHdHfQ # t1RfS8XNbT41WhoB96MT9P8qTwlniX8UZiwUrvNp1Ffy9n4raz8Z+APNwvsCQQC9
-----END RSA PRIVATE KEY----- # AuaOsReEmMFu8VTjNh2G+TQjgvqKmaQtVNjuOgpUKYv7tYehH3P7/T+62dcy7CRX
# cwbLaFbQhUUUD2DCHdkBAkB6CbB+qhu67oE4nnBCXllI9EXktXgFyXv/cScNvM9Y
# FDzzNAAfVc5Nmbmx28Nw+0w6pnpe/3m0Tudbq3nHdHfQ
# -----END RSA PRIVATE KEY-----
# hello and again will share the same onion_adress # hello and again will share the same onion_adress
FOO_TOR_SERVICE_HOSTS: 88:again:80,8000:world:80 FOO_TOR_SERVICE_HOSTS: 88:again:80,8000:world:80
FOO_TOR_SERVICE_VERSION: '3'
# tor v3 address private key base 64 encoded # tor v3 address private key base 64 encoded
FOO_TOR_SERVICE_KEY: | FOO_TOR_SERVICE_KEY: |
PT0gZWQyNTUxOXYxLXNlY3JldDogdHlwZTAgPT0AAABYZRzL3zScTEqA8/5wfvHw PT0gZWQyNTUxOXYxLXNlY3JldDogdHlwZTAgPT0AAABYZRzL3zScTEqA8/5wfvHw

@ -12,9 +12,10 @@ services:
environment: environment:
# Set version 3 on BAR group # Set version 3 on BAR group
BAR_TOR_SERVICE_HOSTS: '80:hello:80,88:world:80' BAR_TOR_SERVICE_HOSTS: '80:hello:80,88:world:80'
# This is now optional as v2 are not supported anymore by tor network
BAR_TOR_SERVICE_VERSION: '3' BAR_TOR_SERVICE_VERSION: '3'
# hello and again will share the same v2 onion_adress # hello and again will share the same onion_adress
FOO_TOR_SERVICE_HOSTS: '88:again:80,80:hello:80,800:hello:80,8888:hello:80' FOO_TOR_SERVICE_HOSTS: '88:again:80,80:hello:80,800:hello:80,8888:hello:80'
@ -49,6 +50,6 @@ volumes:
secrets: secrets:
foo: foo:
file: ./private_key_foo_v2 file: ./private_key_foo_v3
bar: bar:
file: ./private_key_bar_v3 file: ./private_key_bar_v3

@ -12,9 +12,10 @@ services:
environment: environment:
# Set version 3 on BAR group # Set version 3 on BAR group
BAR_TOR_SERVICE_HOSTS: '80:hello:80,88:world:80' BAR_TOR_SERVICE_HOSTS: '80:hello:80,88:world:80'
# This is now optional as v2 are not supported anymore by tor network
BAR_TOR_SERVICE_VERSION: '3' BAR_TOR_SERVICE_VERSION: '3'
# hello and again will share the same v2 onion_adress # hello and again will share the same onion_adress
FOO_TOR_SERVICE_HOSTS: '88:again:80,80:hello:80,800:hello:80,8888:hello:80' FOO_TOR_SERVICE_HOSTS: '88:again:80,80:hello:80,800:hello:80,8888:hello:80'
@ -45,6 +46,6 @@ volumes:
secrets: secrets:
foo: foo:
file: ./private_key_foo_v2 file: ./private_key_foo_v3
bar: bar:
file: ./private_key_bar_v3 file: ./private_key_bar_v3

@ -427,7 +427,7 @@ class Onions(Setup):
def setup_services(): def setup_services():
for name, setup in self.torrc_dict.items(): for name, setup in self.torrc_dict.items():
version = setup.get('version', 2) version = setup.get('version', 3)
group = (self.find_group_by_name(name) group = (self.find_group_by_name(name)
or self.add_empty_group(name, version=version)) or self.add_empty_group(name, version=version))
for service_dict in setup.get('services', []): for service_dict in setup.get('services', []):

@ -4,7 +4,6 @@ import os
import pathlib import pathlib
import re import re
from pytor import OnionV2
from pytor import OnionV3 from pytor import OnionV3
from pytor.onion import EmptyDirException from pytor.onion import EmptyDirException
@ -14,7 +13,7 @@ class ServicesGroup(object):
name = None name = None
version = None version = None
imported_key = False imported_key = False
_default_version = 2 _default_version = 3
_onion = None _onion = None
_hidden_service_dir = "/var/lib/tor/hidden_service/" _hidden_service_dir = "/var/lib/tor/hidden_service/"
@ -27,7 +26,6 @@ class ServicesGroup(object):
name_regex = r'^[a-zA-Z0-9-_]+$' name_regex = r'^[a-zA-Z0-9-_]+$'
self.onion_map = { self.onion_map = {
2: OnionV2,
3: OnionV3, 3: OnionV3,
} }

897
poetry.lock generated

File diff suppressed because it is too large Load Diff

@ -1,15 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDR8TdQF9fDlGhy1SMgfhMBi9TaFeD12/FK27TZE/tYGhxXvs1C
NmFJy1hjVxspF5unmUsCk0yEsvEdcAdp17Vynz6W41VdinETU9yXHlUJ6NyI32AH
dnFnHEcsllSEqD1hPAAvMUWwSMJaNmBEFtl8DUMS9tPX5fWGX4w5Xx8dZwIDAQAB
AoGBAMb20jMHxaZHWg2qTRYYJa8LdHgS0BZxkWYefnBUbZn7dOz7mM+tddpX6raK
8OSqyQu3Tc1tB9GjPLtnVr9KfVwhUVM7YXC/wOZo+u72bv9+4OMrEK/R8xy30XWj
GePXEu95yArE4NucYphxBLWMMu2E4RodjyJpczsl0Lohcn4BAkEA+XPaEKnNA3AL
1DXRpSpaa0ukGUY/zM7HNUFMW3UP00nxNCpWLSBmrQ56Suy7iSy91oa6HWkDD/4C
k0HslnMW5wJBANdz4ehByMJZmJu/b5y8wnFSqep2jmJ1InMvd18BfVoBTQJwGMAr
+qwSwNXXK2YYl9VJmCPCfgN0o7h1AEzvdYECQAM5UxUqDKNBvHVmqKn4zShb1ugY
t1RfS8XNbT41WhoB96MT9P8qTwlniX8UZiwUrvNp1Ffy9n4raz8Z+APNwvsCQQC9
AuaOsReEmMFu8VTjNh2G+TQjgvqKmaQtVNjuOgpUKYv7tYehH3P7/T+62dcy7CRX
cwbLaFbQhUUUD2DCHdkBAkB6CbB+qhu67oE4nnBCXllI9EXktXgFyXv/cScNvM9Y
FDzzNAAfVc5Nmbmx28Nw+0w6pnpe/3m0Tudbq3nHdHfQ
-----END RSA PRIVATE KEY-----

Binary file not shown.

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "docker-tor-hidden-service" name = "docker-tor-hidden-service"
version = "0.6.1" version = "0.7.0"
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"
@ -23,8 +23,8 @@ packages = [
onions = "onions:main" onions = "onions:main"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = ">= 3.8, < 3.9" python = ">=3.8,<3.10"
pytor = "^0.1.5" pytor = "^0.1.7"
Jinja2 = "^2.10" Jinja2 = "^2.10"
pyentrypoint = "^0.7.4" pyentrypoint = "^0.7.4"
importlib_metadata = "^1.6.0" importlib_metadata = "^1.6.0"

@ -6,45 +6,14 @@ from base64 import b32encode
from base64 import b64decode from base64 import b64decode
from hashlib import sha1 from hashlib import sha1
import pytest
from Crypto.PublicKey import RSA
from onions import Onions from onions import Onions
def get_key_and_onion(version=2): def get_key_and_onion(version=3):
key = {} key = {}
key[
2
] = """
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCsMP4gl6g1Q313miPhb1GnDr56ZxIWGsO2PwHM1infkbhlBakR
6DGQfpE31L1ZKTUxY0OexKbW088v8qCOfjD9Zk1i80JP4xzfWQcwFZ5yM/0fkhm3
zLXqXdEahvRthmFsS8OWusRs/04U247ryTm4k5S0Ch5OTBuvMLzQ8W0yDwIDAQAB
AoGAAZr3U5B2ZgC6E7phKUHjbf5KMlPxrDkVqAZQWvuIKmhuYqq518vlYmZ7rhyS
o1kqAMrfH4TP1WLmJJlLe+ibRk2aonR4e0GbW4x151wcJdT1V3vdWAsVSzG3+dqX
PiGT//DIe0OPSH6ecI8ftFRLODd6f5iGkF4gsUSTcVzAFgkCQQDTY67dRpOD9Ozw
oYH48xe0B9NQCw7g4NSH85jPurJXnpn6lZ6bcl8x8ioAdgLyomR7fO/dJFYLw6uV
LZLqZsVbAkEA0Iei3QcpsJnYgcQG7l5I26Sq3LwoiGRDFKRI6k0e+en9JQJgA3Ay
tsLpyCHv9jQ762F6AVXFru5DmZX40F6AXQJBAIHoKac8Xx1h4FaEuo4WPkPZ50ey
dANIx/OAhTFrp3vnMPNpDV60K8JS8vLzkx4vJBcrkXDSirqSFhkIN9grLi8CQEO2
l5MQPWBkRKK2pc2Hfj8cdIMi8kJ/1CyCwE6c5l8etR3sbIMRTtZ76nAbXRFkmsRv
La/7Syrnobngsh/vX90CQB+PSSBqiPSsK2yPz6Gsd6OLCQ9sdy2oRwFTasH8sZyl
bhJ3M9WzP/EMkAzyW8mVs1moFp3hRcfQlZHl6g1U9D8=
-----END RSA PRIVATE KEY-----
"""
onion = {} onion = {}
pub = {} pub = {}
onion[2] = (
b32encode(
sha1(
RSA.importKey(key[2].strip()).publickey().exportKey("DER")[22:]
).digest()[:10]
)
.decode()
.lower()
+ ".onion"
)
key[ key[
3 3
@ -230,48 +199,6 @@ ff02::2 ip6-allrouters
) )
def test_key(monkeypatch):
key, onion_url = get_key_and_onion()
env = {"SERVICE1_KEY": key}
monkeypatch.setattr(os, "environ", env)
onion = Onions()
onion._get_setup_from_env()
assert len(os.environ) == 1
assert len(onion.services) == 1
assert onion.services[0].onion_url == onion_url
def test_key_v2(monkeypatch):
key, onion_url = get_key_and_onion(version=2)
envs = [
{
"GROUP1_TOR_SERVICE_HOSTS": "80:service1:80,81:service2:80",
"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,
},
]
for env in envs:
monkeypatch.setattr(os, "environ", env)
onion = Onions()
onion._get_setup_from_env()
onion._load_keys_in_services()
assert len(os.environ) == len(env)
assert len(onion.services) == 1
assert onion.services[0].onion_url == onion_url
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)
@ -295,7 +222,7 @@ 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",
@ -303,22 +230,21 @@ def test_key_in_secret(fs, monkeypatch):
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/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 != onion_url_v3
assert group3.onion_url == onion_url_v3 assert group3.onion_url == onion_url_v3
@ -335,7 +261,6 @@ HiddenServiceSingleHopMode 1
"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_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",
@ -384,7 +309,7 @@ HiddenServiceSingleHopMode 1
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") == 6
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 assert "ControlPort" not in torrc
@ -404,7 +329,7 @@ HiddenServiceSingleHopMode 1
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 == 3
assert group.onion_url == onions_urls[group.name] assert group.onion_url == onions_urls[group.name]
assert set(service.host for service in group.services) == set( assert set(service.host for service in group.services) == set(
["service1", "service2"] ["service1", "service2"]
@ -422,7 +347,7 @@ HiddenServiceSingleHopMode 1
) == 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 == 3
assert group.onion_url == onions_urls[group.name] assert group.onion_url == onions_urls[group.name]
assert set(service.host for service in group.services) == set( assert set(service.host for service in group.services) == set(
["group2"] ["group2"]
@ -435,7 +360,7 @@ HiddenServiceSingleHopMode 1
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 == 3
assert group.onion_url == onions_urls[group.name] assert group.onion_url == onions_urls[group.name]
assert set(service.host for service in group.services) == set( assert set(service.host for service in group.services) == set(
["service4", "service5"] ["service4", "service5"]
@ -468,7 +393,7 @@ HiddenServiceSingleHopMode 1
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 == 3
assert group.onion_url == onions_urls[group.name] assert group.onion_url == onions_urls[group.name]
assert set(service.host for service in group.services) == set( assert set(service.host for service in group.services) == set(
["service5"] ["service5"]
@ -538,7 +463,7 @@ def test_groups(monkeypatch):
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]{56}.onion$"
assert len(os.environ) == 6 assert len(os.environ) == 6
assert len(onion.services) == 2 assert len(onion.services) == 2

@ -1,6 +1,6 @@
[tox] [tox]
isolated_build = true isolated_build = true
envlist = py38 envlist = py39
[testenv] [testenv]
whitelist_externals = poetry whitelist_externals = poetry

Loading…
Cancel
Save