stable 1.0.0
This commit is contained in:
parent
88d63072ce
commit
e075e900cf
3 changed files with 100 additions and 184 deletions
231
README.md
231
README.md
|
|
@ -1,196 +1,77 @@
|
||||||
# docker-tor-hidden-service
|
# Docker Tor Hidden Service (Modernized)
|
||||||
|
|
||||||
[](https://travis-ci.org/cmehay/docker-tor-hidden-service)
|
A secure, lightweight, and modern Docker image for running Tor Hidden Services (Onion Services) with Vanguards protection.
|
||||||
|
|
||||||
## Changelog
|
## Features
|
||||||
|
* **Lightweight**: Built on `python:3.11-alpine` (latest stable).
|
||||||
|
* **Secure**: "Fail-fast" entrypoint script that validates all configuration before starting.
|
||||||
|
* **Vanguards Ready**: Includes [Vanguards](https://github.com/mikeperry-tor/vanguards) for active defense against deanonymization attacks.
|
||||||
|
* **No Magic**: dynamic configuration via standard `entrypoint.sh` — no opaque Python wrappers.
|
||||||
|
* **Multi-Arch**: Supports `amd64` and `arm64`.
|
||||||
|
|
||||||
* 26 jul 2022
|
## Usage
|
||||||
* Update `onions` tool to v0.7.1:
|
|
||||||
* Fix an issue when restarting a container with control port enabled
|
|
||||||
* Updated to python 3.10
|
|
||||||
* Fix a typo in `docker-compose.vanguards-network.yml`, it works now
|
|
||||||
* Update `tor` to `0.4.7.8`
|
|
||||||
|
|
||||||
* 23 dec 2021
|
### Quick Start (Docker Compose)
|
||||||
* 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 hosts
|
|
||||||
|
|
||||||
From 2019, new conf to handle tor v3 address has been added. Here an example with `docker-compose` v2+:
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: "2"
|
version: '3.8'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
tor:
|
tor:
|
||||||
image: goldy/tor-hidden-service:0.3.5.8
|
build: .
|
||||||
links:
|
|
||||||
- hello
|
|
||||||
- world
|
|
||||||
- again
|
|
||||||
environment:
|
environment:
|
||||||
|
# Format: ExternalPort:ContainerName:InternalPort
|
||||||
|
- HIDDEN_SERVICE_HOSTS=80:my-web-server:80
|
||||||
|
- TOR_CONTROL_PASSWORD=secure_password
|
||||||
|
volumes:
|
||||||
|
- tor-data:/var/lib/tor/
|
||||||
|
depends_on:
|
||||||
|
- web
|
||||||
|
|
||||||
# hello and again will share the same onion v3 address
|
# Example Web Server
|
||||||
SERVICE1_TOR_SERVICE_HOSTS: 88:hello:80,8000:world:80
|
web:
|
||||||
# Optional as tor version 2 is not supported anymore
|
image: nginx:alpine
|
||||||
SERVICE1_TOR_SERVICE_VERSION: '3'
|
container_name: my-web-server
|
||||||
# tor v3 address private key base 64 encoded
|
|
||||||
SERVICE1_TOR_SERVICE_KEY: |
|
|
||||||
PT0gZWQyNTUxOXYxLXNlY3JldDogdHlwZTAgPT0AAACArobDQYyZAWXei4QZwr++
|
|
||||||
j96H1X/gq14NwLRZ2O5DXuL0EzYKkdhZSILY85q+kfwZH8z4ceqe7u1F+0pQi/sM
|
|
||||||
|
|
||||||
world:
|
# Vanguards Sidecar (Optional but Recommended)
|
||||||
image: tutum/hello-world
|
vanguards:
|
||||||
hostname: world
|
build: .
|
||||||
|
command: vanguards --control_ip tor-service --control_port 9051 --control_pass secure_password
|
||||||
|
volumes:
|
||||||
|
- tor-data:/var/lib/tor/
|
||||||
|
depends_on:
|
||||||
|
- tor
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
hello:
|
volumes:
|
||||||
image: tutum/hello-world
|
tor-data:
|
||||||
hostname: hello
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This configuration will output:
|
### Environment Variables
|
||||||
|
|
||||||
```
|
| Variable | Description | Example |
|
||||||
service1: xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion:88, xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion:8000
|
| :--- | :--- | :--- |
|
||||||
|
| `HIDDEN_SERVICE_HOSTS` | Space-separated list of services to expose. Format: `ExtPort:Host:IntPort` | `80:web:80 22:ssh:22` |
|
||||||
|
| `TOR_CONTROL_PASSWORD` | Password for the Tor Control Port (9051). Automatically hashed. | `my_secret_password` |
|
||||||
|
| `TOR_DATA_DIR` | Location of Tor data (keys, state). Default: `/var/lib/tor` | `/var/lib/tor` |
|
||||||
|
|
||||||
|
### Getting your Onion Address
|
||||||
|
Once running, the Tor service generates your keys automatically.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec <container_name> cat /var/lib/tor/hidden_service/hostname
|
||||||
```
|
```
|
||||||
|
|
||||||
`xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion:88` will hit `again:80`.
|
### Checking Vanguards
|
||||||
`xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion:8000` will hit `wold:80`.
|
Verify that Vanguards is connected and pinning your guards:
|
||||||
|
|
||||||
|
```bash
|
||||||
#### Environment variables
|
docker logs vanguards-sidecar
|
||||||
|
docker exec vanguards-sidecar cat /vanguards.state
|
||||||
##### `{SERVICE}_TOR_SERVICE_HOSTS`
|
|
||||||
|
|
||||||
The config patern for this variable is: `{exposed_port}:{hostname}:{port}}`
|
|
||||||
|
|
||||||
For example `80:hello:8080` will expose an onion service on port 80 to the port 8080 of hello hostname.
|
|
||||||
|
|
||||||
Unix sockets are supported too, `80:unix://path/to/socket.sock` will expose an onion service on port 80 to the socket `/path/to/socket.sock`. See `docker-compose.v2.socket.yml` for an example.
|
|
||||||
|
|
||||||
You can concatenate services using comas.
|
|
||||||
|
|
||||||
> **WARNING**: Using sockets and ports in the same service group can lead to issues
|
|
||||||
|
|
||||||
##### `{SERVICE}_TOR_SERVICE_VERSION`
|
|
||||||
|
|
||||||
Optionnal now, can only be `3`. Set the tor address type.
|
|
||||||
|
|
||||||
> **WARNING**: Version 2 is not supported anymore by tor network
|
|
||||||
|
|
||||||
`2` was giving short addresses `5azvyr7dvvr4cldn.onion` and `3` gives long addresses `xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion`
|
|
||||||
|
|
||||||
|
|
||||||
##### `{SERVICE}_TOR_SERVICE_KEY`
|
|
||||||
|
|
||||||
You can set the private key for the current service.
|
|
||||||
|
|
||||||
Tor v3 addresses uses ed25519 binary keys. It should be base64 encoded:
|
|
||||||
```
|
|
||||||
PT0gZWQyNTUxOXYxLXNlY3JldDogdHlwZTAgPT0AAACArobDQYyZAWXei4QZwr++j96H1X/gq14NwLRZ2O5DXuL0EzYKkdhZSILY85q+kfwZH8z4ceqe7u1F+0pQi/sM
|
|
||||||
```
|
|
||||||
##### `TOR_SOCKS_PORT`
|
|
||||||
|
|
||||||
Set tor sock5 proxy port for this tor instance. (Use this if you need to connect to tor network with your service)
|
|
||||||
|
|
||||||
##### `TOR_EXTRA_OPTIONS`
|
|
||||||
|
|
||||||
Add any options in the `torrc` file.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
services:
|
|
||||||
tor:
|
|
||||||
environment:
|
|
||||||
# Add any option you need
|
|
||||||
TOR_EXTRA_OPTIONS: |
|
|
||||||
HiddenServiceNonAnonymousMode 1
|
|
||||||
HiddenServiceSingleHopMode 1
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Security Notes
|
||||||
|
* **User**: Tor runs as the `root` user in the container by default in this minimal setup, but drops privileges where possible. (Note: Production setups might refine this to use the `tor` user exclusively).
|
||||||
|
* **Filesystem**: The `entrypoint.sh` enforces `chmod 700` on the hidden service directory to satisfy Tor's security checks.
|
||||||
|
|
||||||
#### Secrets
|
## Credits
|
||||||
|
Based on the original work by [cmehay](https://github.com/cmehay/docker-tor-hidden-service), but fully refactored to remove dependencies on `pyentrypoint`, `pytor`, and `onions` in favor of standard shell scripts and official binaries.
|
||||||
Secret key can be set through docker `secrets`, see `docker-compose.v3.yml` for example.
|
|
||||||
|
|
||||||
|
|
||||||
### Tools
|
|
||||||
|
|
||||||
A command line tool `onions` is available in container to get `.onion` url when container is running.
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# Get services
|
|
||||||
$ docker exec -ti torhiddenproxy_tor_1 onions
|
|
||||||
hello: xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion:80
|
|
||||||
world: ootceq7skq7qpvvwf2tajeboxovalco7z3ka44vxbtfdr2tfvx5ld7ad.onion:80
|
|
||||||
|
|
||||||
# Get json
|
|
||||||
$ docker exec -ti torhiddenproxy_tor_1 onions --json
|
|
||||||
{"hello": ["xwjtp3mj427zdp4tljiiivg2l5ijfvmt5lcsfaygtpp6cw254kykvpyd.onion:80"], "world": ["ootceq7skq7qpvvwf2tajeboxovalco7z3ka44vxbtfdr2tfvx5ld7ad.onion:80"]}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Auto reload
|
|
||||||
|
|
||||||
Changing `/etc/tor/torrc` file triggers a `SIGHUP` signal to `tor` to reload configuration.
|
|
||||||
|
|
||||||
To disable this behavior, add `ENTRYPOINT_DISABLE_RELOAD` in environment.
|
|
||||||
|
|
||||||
### Versions
|
|
||||||
|
|
||||||
Container version will follow tor release versions.
|
|
||||||
|
|
||||||
### pyentrypoint
|
|
||||||
|
|
||||||
This container uses [`pyentrypoint`](https://github.com/cmehay/pyentrypoint) to generate its setup.
|
|
||||||
|
|
||||||
### pytor
|
|
||||||
|
|
||||||
This containner uses [`pytor`](https://github.com/cmehay/pytor) to mannages tor cryptography, generate keys and compute onion urls.
|
|
||||||
|
|
||||||
## Control port
|
|
||||||
|
|
||||||
Use these environment variables to enable control port
|
|
||||||
* `TOR_CONTROL_PORT`: enable and set control port binding (`ip`, `ip:port` or `unix:/path/to/socket.sock`) (default port is 9051)
|
|
||||||
* `TOR_CONTROL_PASSWORD`: set control port password (in clear, not hashed)
|
|
||||||
* `TOR_DATA_DIRECTORY`: set data directory (default `/run/tor/data`)
|
|
||||||
|
|
||||||
## Vanguards
|
|
||||||
|
|
||||||
For critical hidden services, it's possible to increase security with [`Vanguards`](https://github.com/mikeperry-tor/vanguards) tool.
|
|
||||||
|
|
||||||
|
|
||||||
### Run in the same container
|
|
||||||
|
|
||||||
Check out [`docker-compose.vanguards.yml`](docker-compose.vanguards.yml) for example.
|
|
||||||
|
|
||||||
Add environment variable `TOR_ENABLE_VANGUARDS` to `true` to start `vanguards` daemon beside `tor` process. `Vanguards` logs will be displayed to stdout using `pyentrypoint` logging, if you need raw output, set `ENTRYPOINT_RAW` to `true` in environment.
|
|
||||||
|
|
||||||
In this mode, if `vanguards` exits, sigint is sent to `tor` process to terminate it. If you want to disable this behavior, set `VANGUARD_KILL_TOR_ON_EXIT` to `false` in environment.
|
|
||||||
|
|
||||||
### Run in separate containers
|
|
||||||
Check out[`docker-compose.vanguards-network.yml`](docker-compose.vanguards-network.yml) for an example of increased security setup using docker networks.
|
|
||||||
|
|
||||||
#### settings
|
|
||||||
|
|
||||||
Use the same environment variable as `tor` to configure `vangards` (see upper).
|
|
||||||
* `TOR_CONTROL_PORT`
|
|
||||||
* `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`
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# Tor Service - Runs Tor with Strict Validation
|
# Tor Service - Runs Tor with Strict Validation
|
||||||
tor:
|
tor:
|
||||||
|
|
@ -9,32 +7,30 @@ services:
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
# Format: ExternalPort:ContainerName:InternalPort
|
# Format: ExternalPort:ContainerName:InternalPort
|
||||||
# Pointing to the new 'web' service below
|
|
||||||
- HIDDEN_SERVICE_HOSTS=80:web:80
|
- HIDDEN_SERVICE_HOSTS=80:web:80
|
||||||
- TOR_CONTROL_PASSWORD=secure_password
|
- TOR_CONTROL_PASSWORD=secure_password
|
||||||
ports:
|
ports:
|
||||||
- "9051:9051" # Expose control port
|
- "9051:9051"
|
||||||
|
- "9050:9050"
|
||||||
volumes:
|
volumes:
|
||||||
- tor-data:/var/lib/tor/
|
- tor-data:/var/lib/tor/
|
||||||
depends_on:
|
depends_on:
|
||||||
- web
|
- web
|
||||||
|
|
||||||
# Demo Web Service (So Tor has something to host)
|
# Demo Web Service
|
||||||
web:
|
web:
|
||||||
image: nginx:alpine
|
image: nginx:alpine
|
||||||
container_name: my-website
|
container_name: my-website
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
# Vanguards Service - Runs Vanguards only (Sidecar)
|
# Vanguards Service - Sidecar
|
||||||
vanguards:
|
vanguards:
|
||||||
build: .
|
build: .
|
||||||
image: docker-tor-hidden-service:latest
|
image: docker-tor-hidden-service:latest
|
||||||
container_name: vanguards-sidecar
|
container_name: vanguards-sidecar
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
# The 'vanguards' first word triggers the logic in your entrypoint.sh
|
||||||
command: vanguards --control_ip tor-service --control_port 9051 --control_pass secure_password
|
command: vanguards --control_ip tor-service --control_port 9051 --control_pass secure_password
|
||||||
environment:
|
|
||||||
# Placeholder to ensure no tor starts here
|
|
||||||
- HIDDEN_SERVICE_HOSTS=""
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- tor
|
- tor
|
||||||
volumes:
|
volumes:
|
||||||
|
|
|
||||||
39
docker-compose.yml.bak
Normal file
39
docker-compose.yml.bak
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
services:
|
||||||
|
# Tor Service - Runs Tor with Strict Validation
|
||||||
|
tor:
|
||||||
|
build: .
|
||||||
|
image: docker-tor-hidden-service:latest
|
||||||
|
container_name: tor-service
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
# Format: ExternalPort:ContainerName:InternalPort
|
||||||
|
- HIDDEN_SERVICE_HOSTS=80:web:80
|
||||||
|
- TOR_CONTROL_PASSWORD=secure_password
|
||||||
|
ports:
|
||||||
|
- "9051:9051"
|
||||||
|
volumes:
|
||||||
|
- tor-data:/var/lib/tor/
|
||||||
|
depends_on:
|
||||||
|
- web
|
||||||
|
|
||||||
|
# Demo Web Service
|
||||||
|
web:
|
||||||
|
image: nginx:alpine
|
||||||
|
container_name: my-website
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
# Vanguards Service - Sidecar
|
||||||
|
vanguards:
|
||||||
|
build: .
|
||||||
|
image: docker-tor-hidden-service:latest
|
||||||
|
container_name: vanguards-sidecar
|
||||||
|
restart: unless-stopped
|
||||||
|
# The 'vanguards' first word triggers the logic in your entrypoint.sh
|
||||||
|
command: vanguards --control_ip tor-service --control_port 9051 --control_pass secure_password
|
||||||
|
depends_on:
|
||||||
|
- tor
|
||||||
|
volumes:
|
||||||
|
- tor-data:/var/lib/tor/
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
tor-data:
|
||||||
Loading…
Add table
Add a link
Reference in a new issue