/OnionsFarmer

Onion Farmer for planting onions. A python class to manage multiple instances of Tor.

Primary LanguagePython

Onions Farmer

A powerful utility for managing multiple Tor instances

OnionFarmer Intro

About OnionsFarmer

OnionsFarmer empowers users to cultivate "Onions" — a playful metaphor for independent Tor network instances. This sophisticated Python utility facilitates the simultaneous management of multiple Tor processes. For optimal functionality, it requires the Tor software installation on the user's system and proper user permissions. OnionsFarmer streamlines the initiation and supervision of Tor network connections, enhancing both security and usability.

Key Features

  • Create Tor Instances: With the plantOnion method, users can seed new, individually manageable Tor instances.
  • Independent Operation: Each Onion instance operates independently, providing detailed control over its respective Tor process.
  • Graceful Shutdown: For orderly Tor process termination, employing the Onion.stop() method is advised before exiting the application.
  • Direct Control and Termination: The plantOnion method returns an Onion instance along with an external stop event, enabling straightforward control and shutdown operations.
  • Persistent Configuration: OnionsFarmer auto-generates a "ONIONS" directory for storing logs, configuration, and Tor library files. Reutilizing the same Tor instance names can speed up subsequent startups by leveraging existing files.
  • OnionsBag - Bulk Management: A convenient feature for handling multiple Tor instances collectively. It allows for the swift creation and management of several Onions, simplifying the orchestration of numerous Tor connections.

Contents

Requirements  |  Install  |  Onion Farmer Methods  | 
Onion  |  Onions Bag  |  Examples  | 

Requirements

To ensure the proper functioning of Onions Farmer, the following requirements must be met:

  • Tor Software Installed - Onions Farmer relies on direct interactions with the Tor network, requiring the Tor software to be installed on the user's system.
  • Python 3.11 or Newer - Utilizes features and syntax introduced in Python 3.11, necessitating this or a newer version of Python.
  • Python 'socks' Library - This dependency is crucial for managing SOCKS protocol interactions, allowing Onions Farmer to communicate over Tor network connections effectively.

Installation

OnionsFarmer is versatile and can function both as a standalone application or as an imported module in your projects. The choice of how you wish to use it is yours.

Downloading OnionsFarmer:

To get started with OnionsFarmer, clone the repository using Git:

git clone https://github.com/LittleAtariXE/OnionsFarmer.git

Installing Dependencies:

After cloning the repository, navigate to the OnionsFarmer directory and install the necessary Python libraries by running:

pip install -r requirements.txt

Onions Farmer Methods

Onions Market

OnionsFarmer.plantOnion() Method

The plantOnion() method, literally "plant an onion", is responsible for creating a new Onion object, which represents an instance of Tor. This method offers a variety of parameters for customization:

  • name: An optional parameter that assigns a reference name to the Onion instance. This name can be used later with the getOnion() method to retrieve the object. If not provided, a default name is generated.
  • local_socks_port: Specifies the local port for the Tor SOCKS proxy. This parameter determines on which local port the SOCKS proxy will be created.
  • outside_socks_ip: Indicates the IP address and port (in the format "192.168.0.23:8000") to be used for creating a Tor SOCKS proxy accessible from other machines.
  • torrc: An optional parameter that allows specifying a path to a custom torrc file. If this parameter is omitted, a new torrc file will be generated automatically.
  • print_log: Enables direct printing of Tor logs to the console. This is not recommended for multiple instances due to potential text flooding on the screen. Note: Each Onion object maintains its own log file.
  • http_bridge: Creates a special HTTP Proxy server linked to the Tor SOCKS proxy. This parameter accepts three types of values:
    • A specific IP and port (e.g., "192.168.0.22:5000") will create an HTTP -> SOCKS bridge on the specified port, accessible from other machines.
    • A port number only (e.g., "5000") will create the HTTP proxy on the local port 5000.
    • The value "random" will establish the HTTP proxy on a randomly selected port.
  • config: A dictionary that may contain additional optional parameters, which will be detailed further in this documentation.

This method allows for flexible creation and management of Tor instances, catering to a wide range of use cases and preferences.

Optimizing Tor Connection Initialization

When selecting names for Onion instances, either through plantOnion() or makeOnionsBag(), consistently using the same names can lead to faster connection and configuration times with the Tor network. This efficiency gain is due to the Tor library files already being downloaded. The difference becomes noticeable when rerunning the same script. The initial startup always takes the longest, as Tor needs to download all necessary files, descriptors, etc.

OnionsFarmer.getOnion() Method

The getOnion() method retrieves an Onion object previously created by the OnionsFarmer. This method facilitates access to individual Onion instances for management and interaction:

  • name: The name of the previously created Onion instance. Providing this name as a parameter allows for the retrieval of the specific Onion object. If this parameter is omitted, a dict object containing all Onion objects managed by OnionsFarmer is returned.

Onion objects are typically assigned to variables for easy access. OnionsFarmer internally stores every Onion object created, enabling efficient management and retrieval of these instances as needed.

OnionsFarmer.stopOnion() Method

The stopOnion() method is designed to halt a specified Onion instance. It serves as a convenient way to terminate Tor processes directly from the OnionsFarmer, complementing the individual stop methods within each Onion object:

  • name: The name of the Onion object to be stopped. When this parameter is provided, OnionsFarmer will attempt to stop the specified Onion instance. If the name parameter is omitted, OnionsFarmer will proceed to stop all Onion instances it manages.

REMEMBER: It is crucial to stop all running Onion instances before exiting your script or application. This ensures a proper shutdown of the Tor processes and prevents any potential resource leaks or orphaned processes.

OnionsFarmer.makeOnionsBag() Method

The makeOnionsBag() method facilitates the creation of an OnionsBag object, which is a collection containing multiple Onion objects. This method is ideal for quickly generating and managing numerous Tor instances:

  • count: Specifies the number of Onion objects to be created. The default value is 1.
  • name: Optionally provides a base name for the Onion instances. The farmer will append a unique ID to each name, based on the total number of Onions.
  • local_sock_port_num_start: Optionally sets the starting port number. Subsequent Tor SOCKS will be placed on increasing port numbers from this starting point.
  • out_proxy_ip: Optionally specifies an external proxy IP address that can be connected to from another machine. The script will assign the port.
  • torrc: Optionally allows specifying a path to a custom torrc file to be used as a template.
  • print_log: Optionally enables the printing of logs to the console for each Onion object. Be cautious as this can lead to extensive output on the console, especially with many instances!
  • http_bridge: For each Onion, an HTTP Proxy connected to Tor's SOCKS will be created, with the port assigned by the script.

Remember: Each created Onion object has its configuration, which you can inspect. This includes SOCKS addresses, HTTP Bridge addresses and ports, among other settings.


Onion Object

Onion Linux

The Onion Object

The Onion object embodies an individual Tor instance within the OnionsFarmer framework. It encapsulates the configuration and management of a Tor process, offering a variety of properties and methods for interaction:

Properties

  • Onion.conf: Returns a dictionary object containing the Onion's configuration, including SOCKS addresses, HTTP Bridge details, etc.
  • Onion.isTorConn: Returns True if the Onion has successfully connected to the Tor network.
  • Onion.IP: Retrieves the IP address of the Exit Node. If the address cannot be obtained, it returns None.

Methods

  • Onion.start(): Initiates the connection to the Tor network. This method begins the Tor process associated with the Onion instance.
  • Onion.stop(): Terminates the Onion's Tor process. Important: Always close each Tor connection with this method before ending your program to prevent errors and orphaned processes.
  • Onion.sendCMD(): Sends a command through the Tor Control Socket and returns the response. This method allows for direct interaction with the Tor process.
  • Onion.newCircuit(): Generates a new circuit for the Onion, potentially altering the exit node and IP address.
  • Onion.status(): Displays the current status of the Onion object, which can be "ready to start", "working", or "terminated".
  • Onion.infoConf(): Prints a readable configuration of the Onion object to the screen, detailing its current setup and parameters.

Onions Bag

The OnionsBag Object

The OnionsBag object, or "Bag of Onions," represents a collection of multiple Tor instances (Onion objects). It allows for efficient and quick management of all contained Onions simultaneously.

Properties

  • OnionsBag.len: Returns the number of Onion objects contained within the bag.
  • OnionsBag.isTorConn: Checks if all Onion objects have successfully established a full connection to the Tor network. Returns False if at least one Onion is not connected, and True if all are connected.

Methods

  • OnionsBag.start(): Initiates the Tor connection process for all Onion objects within the bag.
  • OnionsBag.stop(): Terminates the Tor processes for all Onion objects, effectively stopping all connections.
  • OnionsBag.openBag(): Returns a list object that contains all the Onion objects within the bag.
  • OnionsBag.getIP(): Begins the process of obtaining the Exit Node IP addresses for all contained Onion objects.
  • OnionsBag.newCircuit(): Instructs all Onion objects to start the process of creating a new circuit, potentially changing their exit nodes and IP addresses.
  • OnionsBag.__str__(): Displays a tabular overview of the basic configuration for all Onion objects, including SOCKS addresses, HTTP Bridge statuses, connection statuses, and more. This method provides a quick and readable summary of the entire OnionsBag state.


Examples

Below are examples illustrating how to use the OnionsFarmer utility to manage Tor instances.

Basic Usage

Here's how to initialize OnionsFarmer, create Onion instances, and manage their Tor connections:

from time import sleep
from onions_farmer import OnionsFarmer

# Initialize the OnionsFarmer instance.
farmer = OnionsFarmer()

# Create and configure a random Onion instance with default settings.
my_onion = farmer.plantOnion()

# Create and configure a specific Onion instance to listen on local port 4444 and enable console logging.
my_onion2 = farmer.plantOnion(local_socks_port=4444, print_log=True)

# Start the Onion instance's thread, initiating the Tor process.
my_onion2.start()

# Loop until the Onion instance establishes a connection with the Tor network.
while not my_onion2.isTorConn:
    sleep(0.5)
print("TOR Works !!!")

# Retrieve and print the Exit Node IP address for the Onion instance.
print("Exit Node IP: ", my_onion2.IP)

# Wait for user input and then display the Onion instance's configuration.
input("Press ENTER to display Onion configuration.")
my_onion2.infoConf()

# Wait for user input again before stopping the Onion instance's thread.
input("Press ENTER to stop the Onion.")
my_onion2.stop()

# Ensure the Onion instance has time to shut down properly.
sleep(2)

# Final user prompt before exiting the script.
input("Press ENTER to EXIT")

Advanced Example: Managing Multiple Onions

This example demonstrates creating, starting, and managing multiple Onion instances simultaneously, including renewing their circuits for new identities:

from time import sleep
from onions_farmer import OnionsFarmer

# Initialize the OnionsFarmer.
farmer = OnionsFarmer()

# Create two Onion instances with specified local SOCKS ports and enable logging.
my_onion1 = farmer.plantOnion(local_socks_port=4000, print_log=True)
my_onion2 = farmer.plantOnion(local_socks_port=5000, print_log=True)

# Start both Onion instances' threads, launching the Tor processes.
my_onion1.start()
my_onion2.start()

# Wait until both Onion instances have established connections to the Tor network.
while not my_onion1.isTorConn or not my_onion2.isTorConn:
    sleep(0.5)

print("Tor Works !!")
sleep(1)

# Display the initial Exit Node IP addresses for both Onion instances.
print("my_onion1 IP: ", my_onion1.IP)
print("my_onion2 IP: ", my_onion2.IP)

# Wait for user input before requesting new circuits for both Onion instances.
input("Press ENTER to renew circuits.")
my_onion1.newCircuit()
my_onion2.newCircuit()

# Wait until both Onion instances have re-established connections with the new circuits.
while not my_onion1.isTorConn or not my_onion2.isTorConn:
    sleep(0.5)

# Confirm that new circuits have been established and display the new Exit Node IP addresses.
print("New Circuit")
print("my_onion1 IP: ", my_onion1.IP)
print("my_onion2 IP: ", my_onion2.IP)

# Wait for user input before stopping both Onion instances.
input("Press ENTER to stop Onions.")
farmer.stopOnion()

# Ensure there's enough time for both Onion instances to shut down properly.
sleep(2)

# Final input to exit the script, ensuring a graceful termination.
input("Press ENTER to exit.")

Example 3: Utilizing OnionsBag for Bulk Management

This example demonstrates how to use an OnionsBag to efficiently manage multiple Onion instances simultaneously, including creating, starting, renewing circuits, and stopping all instances in bulk:

# OnionsBag example

from time import sleep
from onions_farmer import OnionsFarmer

# Initialize OnionsFarmer
Farmer = OnionsFarmer()

# Create an OnionsBag with 10 Onion instances.
# The first creation might take longer due to initial Tor network connections and configurations.
bag = Farmer.makeOnionsBag(10)

# Start all Onion instances within the bag.
# This initiates the Tor connections for each Onion.
bag.start()

# Wait for user input to continue. This is a good moment to ensure all Onions have connected to the Tor network.
input("All Onions are starting. Press Enter after they've connected...")

# Print the current state of all Onion instances in the bag.
# This displays basic configurations like SOCKS and HTTP Bridge addresses, and their connection statuses.
print(bag)

input("Press Enter to make a new circuit for all Onions.")

# Request new circuits for all Onion instances in the bag.
# This can help refresh the network paths and potentially result in new Exit Node IPs.
bag.newCircuit()

input("Press Enter to check the Exit Node IPs for all Onions.")

# Trigger the process to obtain and print the Exit Node IP addresses for all Onion instances.
bag.getIP()

input("Waiting for all Onions to obtain new IP addresses...")

# Print the updated state of all Onion instances in the bag, including their new Exit Node IP addresses.
print(bag)

input("Press Enter to stop all Onions.")

# Stop all Onion instances within the bag.
# This ensures a graceful shutdown of all Tor connections.
bag.stop()

# Pause to allow time for all Onion instances to shut down properly.
sleep(2)

# Final input prompt to exit the script.
input("Press Enter to Exit. All Onions have been stopped.")