Skip to main content

TorRunner is designed to facilitate the deployment of Tor hidden services.

Project description

🧅 𝙏𝙤𝙧𝙍𝙪𝙣𝙣𝙚𝙧

TorRunner is a Python package designed to facilitate the deployment of Tor hidden services. It simplifies the process by allowing you to set up and run a hidden service that listens on a specified port. This package automates the installation and configuration of the Tor software, removing the need for manual setup and making it easier to get started.

Github PyPI Libraries.io


Special thanks

This project uses the Vanguards implementation of mikeperry-tor at mikeperry-tor/vanguards under MIT license found here, the socks implementation of Anorov at Anorov/PySocks under BSD License found here and the win_inet_pton implementation of hickeroar at hickeroar/win_inet_pton under Public Domain License found here.

📌 Planned for the future

  • Vanguards
  • Auto Bridge Updates
  • Multi Threads
  • Tor version check & auto update
  • Proxy mode [only for urllib implemented]
    ❌ (not feasible) Tor preinstalled

🚀 Installation

Make sure you have the latest version of Python and Pip installed.

  1. Create an virtual env with python3 -m venv .venv and source .venv/bin/activate
  2. Install TorRunner with pip pip install tor-runner or manually via git clone https://github.com/tn3w/TorRunner or download the zip here.
  3. If you installed it manually, run pip install . in the downloaded and extracted folder.
  4. [Optional] Install stem with pip install stem if you want to use Vanguards.

Quick command (Linux / macOS):

python -m venv .venv; source .venv/bin/activate; pip install tor-runner

Quick command (Windows):

python -m venv .venv; .venv/Scripts/activate.bat; pip install tor-runner

Examples

TorProxy

TorRunner has the ability to route your urllib requests through Tor.

Example:

import time
import urllib.request
import urllib.error
from tor_runner import TorProxy

proxy = TorProxy()
proxy.start()
print("SocksPort running on 127.0.0.1:" + str(proxy.socks_port))

with proxy.urllib():
    start_time = time.time()
    url = "https://check.torproject.org/?lang=en_US"

    try:
        response = urllib.request.urlopen(url)
        content = response.read().decode('utf-8')

        if "Congratulations" in content:
            print("Connected to Tor!")

        elif "Sorry" in content:
            print("Not connected to Tor")

    except urllib.error.URLError as e:
        print(f"Error connecting to {url}: {e}")
    except Exception as e:
        print(f"Unexpected error: {e}")

    first_byte_time = time.time() - start_time
    print(f"Time to first byte: {first_byte_time:.4f} seconds")

On the command line

tor_runner --help

Output:

usage: tor_runner [-h] [-p PORT] [-l [LISTENER ...]] [-t THREADS] [-d [HIDDEN_SERVICE_DIRS ...]] [-b [BRIDGES ...]] [-s SOCKS_PORT] [-v [VANGUARDS]] [--bridge-quantity BRIDGE_QUANTITY]
                  [--default-bridge-type DEFAULT_BRIDGE_TYPE] [--direct] [--delete] [--quiet]

Run as a Tor hidden service, allowing configuration of listeners, hidden service directories, and bridges.

options:
  -h, --help            show this help message and exit
  -p PORT, --port PORT  HTTP port for the hidden service to listen on.
  -l [LISTENER ...], --listener [LISTENER ...]
                        List of listeners in the format 'tor_port,listen_port'.
  -t THREADS, --threads THREADS
                        How many times Tor should start. (default: 1)
  -d [HIDDEN_SERVICE_DIRS ...], --hidden-service-dirs [HIDDEN_SERVICE_DIRS ...]
                        Directories for storing hidden service keys and hostname files.
  -b [BRIDGES ...], --bridges [BRIDGES ...]
                        List of bridges to use for connecting to the Tor network.
  -s SOCKS_PORT, --socks-port SOCKS_PORT
                        SOCKS port for Tor connections.
  -v [VANGUARDS], --vanguards [VANGUARDS]
                        Enables Vanguards with an optional thread count to protect against guard discovery and related traffic analysis attacks.
  --bridge-quantity BRIDGE_QUANTITY
                        Number of bridges to use for connecting to the Tor network.
  --default-bridge-type DEFAULT_BRIDGE_TYPE
                        Default bridge type to use when connecting to Tor.
  --direct              Executes your command directly via Tor.
  --delete              Delete all data associated with tor_runner.
  --quiet               Run the script in quiet mode with no output.

Without an App

from tor_runner import TorRunner

# Uses 11 default obfs4 bridges to connect
runner = TorRunner(
    hs_dirs = ["/path/to/hs"], bridges = [],
    default_bridge_type = "obfs4", bridge_quantity = 11
)

if __name__ == '__main__':
    # Forwards 5000 -> 80 and 22 -> 22
    runner.run([(5000, 80), (22, 22)], socks_port = 9050, quite = False, wait = True)

For Flask

from flask import Flask
from tor_runner import TorRunner

app = Flask(__name__)

# Uses 11 default obfs4 bridges to connect
runner = TorRunner(default_bridge_type = "obfs4", bridge_quantity = 11)

@app.route('/')
def index():
    """
    Route accessible via the Tor network
    """

    return 'Hello, Anonymous!🖐️'

if __name__ == '__main__':
    runner.flask_run(app, host = '127.0.0.1', port = 9000)

For Sanic

from sanic import Sanic, HTTPResponse
from sanic.response import text
from tor_runner import TorRunner

app = Sanic(__name__)

# Uses 11 default obfs4 bridges to connect
runner = TorRunner(default_bridge_type = "obfs4", bridge_quantity = 11)

@app.route('/')
async def index(request) -> HTTPResponse:
    """
    Route accessible via the Tor network
    """

    return text('Hello, Anonymous!🖐️')

if __name__ == '__main__':
    runner.sanic_run(app, host = '127.0.0.1', port = 8000, workers = 16)

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tor_runner-1.5.tar.gz (58.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tor_runner-1.5-py3-none-any.whl (63.1 kB view details)

Uploaded Python 3

File details

Details for the file tor_runner-1.5.tar.gz.

File metadata

  • Download URL: tor_runner-1.5.tar.gz
  • Upload date:
  • Size: 58.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for tor_runner-1.5.tar.gz
Algorithm Hash digest
SHA256 a82d985979d7dda8bfbe898ae0dc0030c0092c65c90e69d55ae0aa6a89ea61d3
MD5 a98f758a6e061548772c6d201ec1314c
BLAKE2b-256 9da721cae9c93137931f971c803b595ce54435de632211eb716b6a0fffc557bb

See more details on using hashes here.

File details

Details for the file tor_runner-1.5-py3-none-any.whl.

File metadata

  • Download URL: tor_runner-1.5-py3-none-any.whl
  • Upload date:
  • Size: 63.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for tor_runner-1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 b465b98a597f104b4bf6907b828bdc7d381bfb64ee4a8d32297154ebe69fb624
MD5 ad47f98b7b202c29abf6f31a02d2a987
BLAKE2b-256 d5ac8b197b08650c17e63804e8ce7c029bac80df6d74dddbbe3a247118f3a050

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page