Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Torcontrol Bundle Laravel Package

dunglas/torcontrol-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require dunglas/torcontrol-bundle
    

    Register the bundle in config/bundles.php:

    return [
        // ...
        Dunglas\TorControlBundle\DunglasTorControlBundle::class => ['all' => true],
    ];
    
  2. Basic Configuration (config/packages/dunglas_tor_control.yaml):

    dunglas_tor_control:
        hostname: "127.0.0.1"  # Default: localhost
        port: 9051              # Default: 9051
        authmethod: "null"      # Default: autodetect
    
  3. First Use Case: Inject the TorControl service into a controller or command to manage Tor:

    use Dunglas\TorControlBundle\Service\TorControl;
    
    class MyController extends AbstractController
    {
        public function __construct(private TorControl $torControl)
        {}
    
        public function index()
        {
            $this->torControl->getVersion(); // Example: Fetch Tor version
            // ...
        }
    }
    

Implementation Patterns

Common Workflows

  1. Dynamic Tor Configuration: Use the service to programmatically adjust Tor settings (e.g., reload config after changes):

    $this->torControl->setConf("SocksPort", "9150");
    $this->torControl->signal("HUP"); // Reload Tor config
    
  2. Circuit Management: Create/extend circuits for hidden services or testing:

    $circuit = $this->torControl->newCircuit();
    $circuit->build(3); // Build with 3 hops
    $circuit->extend(); // Extend the circuit
    
  3. Hidden Service Management: Generate/manage .onion addresses:

    $hsdir = sys_get_temp_dir() . '/tor_hs';
    $this->torControl->setConf("HiddenServiceDir", $hsdir);
    $this->torControl->setConf("HiddenServicePort", "80 127.0.0.1:8080");
    $this->torControl->signal("HUP");
    $address = file_get_contents($hsdir . "/hostname"); // Fetch .onion address
    
  4. Event-Driven Actions: Listen for Tor events (e.g., circuit status changes) via Symfony events:

    # config/services.yaml
    services:
        App\EventListener\TorListener:
            tags:
                - { name: kernel.event_listener, event: tor.control.event, method: onTorEvent }
    
  5. Command-Line Integration: Use the service in console commands for admin tasks:

    namespace App\Command;
    
    use Dunglas\TorControlBundle\Service\TorControl;
    use Symfony\Component\Console\Command\Command;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    
    class TorStatusCommand extends Command
    {
        protected static $defaultName = 'app:tor:status';
    
        public function __construct(private TorControl $torControl)
        {}
    
        protected function execute(InputInterface $input, OutputInterface $output): int
        {
            $output->writeln('Tor Version: ' . $this->torControl->getVersion());
            return Command::SUCCESS;
        }
    }
    

Integration Tips

  1. Dependency Injection: Prefer constructor injection for TorControl to ensure testability:

    public function __construct(private TorControl $torControl) {}
    
  2. Error Handling: Wrap Tor operations in try-catch blocks (e.g., TorControlException):

    try {
        $this->torControl->getInfo("traffic/read");
    } catch (\Exception $e) {
        $this->logger->error("Tor error: {$e->getMessage()}");
    }
    
  3. Configuration Validation: Use Symfony’s validator to validate Tor config before applying:

    # config/validator/constraints/TorConfig.yaml
    Dunglas\TorControlBundle\Validator\Constraints\TorConfig:
        hostname: "127.0.0.1"
        port: 9051
    
  4. Environment-Specific Configs: Override config per environment (e.g., config/packages/dev/dunglas_tor_control.yaml):

    dunglas_tor_control:
        authmethod: "password"
        password: "%env(TOR_PASSWORD)%"
    
  5. Logging: Enable debug logging for Tor events in config/packages/monolog.yaml:

    handlers:
        tor:
            type: stream
            path: "%kernel.logs_dir%/tor.log"
            level: debug
            channels: ["tor"]
    

Gotchas and Tips

Pitfalls

  1. Authentication Issues:

    • If authmethod is misconfigured, TorControl will fail silently. Use null for no auth or explicitly set password/cookie.
    • Fix: Verify Tor’s control.authenticate setting in torrc matches the bundle config.
  2. Port Conflicts:

    • Default port 9051 may be blocked or in use. Ensure Tor’s ControlPort in torrc matches the bundle’s port.
    • Fix: Check Tor logs (/var/log/tor/log) for connection errors.
  3. Deprecated Methods:

    • Some methods (e.g., getConf()) may return null if Tor’s config is not fully loaded. Always validate responses.
    • Fix: Use getInfo() for runtime values instead of getConf() for static config.
  4. Race Conditions:

    • Operations like signal("HUP") may take time to propagate. Add retries or delays:
    $this->torControl->signal("HUP");
    sleep(2); // Wait for reload
    
  5. Hidden Service Delays:

    • .onion addresses may take minutes to generate. Poll the hostname file with a timeout:
    $timeout = time() + 60;
    while (time() < $timeout) {
        if (file_exists($hsdir . "/hostname")) break;
        sleep(5);
    }
    

Debugging

  1. Tor Logs: Enable verbose logging in torrc:

    Log notice stdout
    ControlLog stdout
    
  2. Bundle Debugging: Enable Symfony’s profiler to inspect TorControl service calls:

    // config/packages/dev/debug.yaml
    framework:
        profiler: { only_exceptions: false }
    
  3. Connection Testing: Manually test TorControl connection:

    telnet 127.0.0.1 9051
    AUTHENTICATE "password"
    GETINFO version
    

Extension Points

  1. Custom Commands: Extend the bundle by adding new TorControl commands:

    namespace App\Command;
    
    use Dunglas\TorControlBundle\Service\TorControl;
    use Symfony\Component\Console\Command\Command;
    
    class TorCircuitCommand extends Command
    {
        protected static $defaultName = 'app:tor:circuit';
    
        public function __construct(private TorControl $torControl)
        {}
    
        protected function execute(InputInterface $input, OutputInterface $output): int
        {
            $circuit = $this->torControl->newCircuit();
            $circuit->build(4);
            $output->writeln("Circuit ID: {$circuit->getId()}");
            return Command::SUCCESS;
        }
    }
    
  2. Event Listeners: Subscribe to Tor events (e.g., circuit status changes):

    use Dunglas\TorControlBundle\Event\TorEvent;
    
    class TorListener
    {
        public function onTorEvent(TorEvent $event)
        {
            if ($event->getType() === 'CIRC') {
                $this->logger->info("Circuit event: {$event->getData()}");
            }
        }
    }
    
  3. Configuration Overrides: Dynamically override config at runtime:

    $container->getParameterBag()->set('dunglas_tor_control.hostname', 'new-host');
    
  4. Testing: Mock TorControl in tests using Symfony’s TestContainer:

    use Dunglas\TorControlBundle\Service\TorControl;
    
    $container->register('tor_control.test', TorControl::class)
        ->addArgument($this->createMock(TorControl::class));
    

Performance Tips

  1. Batch Operations: Group multiple Tor commands into a single connection to reduce overhead:
    $this->torControl->getConnection()->send("GETINFO version");
    $this->torControl->getConnection()->send("GETINFO traffic");
    $responses = $this->torControl->getConnection()->
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle