dunglas/php-torcontrol
PHP TorControl is a lightweight library to control a Tor server via the Tor Control Protocol. Connect over TCP/SSL/UNIX sockets, authenticate via null/password/cookie, send commands (e.g., NEWNYM), and handle multi-line replies. Composer install.
Installation Add the package via Composer:
composer require dunglas/php-torcontrol
Ensure your composer.json autoloads PSR-4 compliant classes.
Basic Connection
Initialize the client with Tor server credentials (e.g., localhost:9051 with password auth):
use TorControl\TorControl;
$torControl = new TorControl([
'hostname' => 'localhost',
'port' => 9051,
'password' => 'your_secure_password',
'authmethod' => TorControl::AUTH_PASSWORD, // 1
]);
$torControl->connect();
$torControl->authenticate();
First Use Case: Rotate Identity Execute a command to renew a Tor circuit (e.g., for anonymity):
$response = $torControl->executeCommand('SIGNAL NEWNYM');
dd($response); // Inspect reply code/message
GETINFO, SETCONF).TorControl Class Docs – Check method signatures (e.g., executeCommand(), quit()).Connection Management
$torControl in a service container (e.g., Laravel’s bind()) for app-wide access.
$app->bind(TorControl::class, function ($app) {
return new TorControl(['hostname' => config('tor.host'), 'port' => 9051, 'authmethod' => 1]);
});
Command Execution
GETINFO status/networkstatus).
$cacheKey = 'tor_network_status';
$response = Cache::remember($cacheKey, now()->addHours(1), function () use ($torControl) {
return $torControl->executeCommand('GETINFO status/networkstatus');
});
552 for invalid commands).
try {
$torControl->executeCommand('INVALID_COMMAND');
} catch (\TorControl\Exception\TorControlException $e) {
Log::error("Tor error: {$e->getMessage()}");
}
Authentication
$torControl = new TorControl([
'hostname' => 'localhost',
'port' => 9051,
'cookie_file' => '/var/lib/tor/control_auth_cookie',
'authmethod' => TorControl::AUTH_COOKIE, // 2
]);
ControlListenAddress without auth, use:
$torControl = new TorControl(['hostname' => 'localhost', 'port' => 9051, 'authmethod' => 0]);
Configuration Management
SETCONF to adjust runtime settings (e.g., circuit timeout):
$torControl->executeCommand('SETCONF CircuitBuildTimeout=30');
public function register() {
$this->app->singleton(TorControl::class, function ($app) {
$config = config('tor');
return new TorControl($config['connection']);
});
}
php artisan tor:newnym):
$this->call('tor:newnym', [
'--circuit' => 'general',
]);
NOTICE commands:
$torControl->executeCommand('SETEVENTS CIRC');
Multi-Line Replies
GETINFO may return multi-line responses. The library handles this, but ensure you inspect $response[0]['lines'] for verbose output.count($response) for multiple replies.Authentication Failures
authenticate() is called without valid credentials.if (!$torControl->authenticate()) {
throw new \RuntimeException("Tor authentication failed");
}
Socket Timeouts
GETINFO) may time out if Tor is overloaded.$torControl->setSocketTimeout(30); // Default is 10 seconds
Deprecated Auth Methods
AUTH_NULL (0) may be disabled in newer Tor versions.AUTH_COOKIE (2) or AUTH_PASSWORD (1) explicitly.UNIX Socket Paths
/var/run/tor/control.sock) cause connection failures.chmod 600 for cookie files).TorControl to debug mode to log raw commands/responses:
$torControl->setDebug(true);
/var/log/tor/log for errors like Failed to parse/validate config.Custom Commands Extend the library by creating a wrapper class:
class TorService {
protected $torControl;
public function __construct(TorControl $torControl) {
$this->torControl = $torControl;
}
public function renewIdentity() {
return $this->torControl->executeCommand('SIGNAL NEWNYM');
}
}
Event Handling
Parse NOTICE events for real-time monitoring:
$events = $torControl->executeCommand('GETEVENTS CIRC');
foreach ($events[0]['lines'] as $event) {
Log::info("Tor event: $event");
}
Configuration Validation
Validate Tor config before connecting (e.g., check ControlPort is enabled):
$status = $torControl->executeCommand('GETINFO status');
if (!isset($status[0]['lines']['ControlPort'])) {
throw new \RuntimeException("Tor ControlPort not enabled");
}
GETINFO for Status Checks
Query Tor’s status before executing commands:
$status = $torControl->executeCommand('GETINFO status');
if ($status[0]['code'] !== 250) {
// Handle error
}
SETCONF for Runtime Tweaks
Adjust settings dynamically (e.g., EntryNodes for path control):
$torControl->executeCommand('SETCONF EntryNodes={us}');
AUTH_NULL Locally
Simplify development by disabling auth in torrc:
ControlPort 9051
ControlListenAddress 127.0.0.1
How can I help you explore Laravel packages today?