Stem Docs

Down the Rabbit Hole

Down the Rabbit Hole

Underneath it all Stem is a Python implementation of Tor's control and directory specifications. Anything you can do with Stem you can also do with telnet (albeit with quite a bit of extra work).

Playing with Tor's control port directly is a great way of learning what Tor can and cannot do. This is handy because Stem can take advantage of anything the control interface offers, but conversely is also limited by things it lacks.

To help Stem offers a control prompt with nice usability improvements over telnet...

Getting started

Getting started with the control prompt is easy. Assuming you have Stem installed it will be available under /usr/local/bin/tor-prompt, and can attach to either an existing Tor instance or start one of its own.

If Tor's already running with a control port then you can attach to it using --interface or --socket (by default it checks on port 9051)...

../_images/attach.png

If Tor isn't running this prompt will start a temporary instance of its own. Tor will have a minimal non-relaying configuration, and be shut down when you're done.

../_images/starting_tor.png

What can I do with it?

This prompt accepts three types of commands...

  • Commands for the interpreter itself, such as /help and /info. These are handled by the interpreter and always begin with a slash.
  • Commands for Tor's control port, such as GETINFO version and GETCONF ExitPolicy. These are passed along directly to Tor.
  • Commands that do not match either of the above are treated as Python.

To get a list of the interpreter and Tor commands run /help. You can also run /help [command] (such as /help SIGNAL) to get details on what does...

../_images/help.png

Another useful interpreter command is /info [relay] which provides information about a relay. With this you can look up details about any relay by its IP address, fingerprint, or nickname...

../_images/info.png

Tor commands are passed along directly to Tor's control port, providing raw responses just as telnet would...

../_images/tor_commands.png

And last but certainly not least this prompt provides a Python interpreter, just like IDLE. You start with a Controller for you Tor instance available as your controller variable. This makes it easy to experiment with Stem and see what it can do...

../_images/python.png

Event handling

As mentioned in an earlier tutorial you can subscribe to receive events from Tor. Stem's Controller does this with its add_event_listener() method, but with our raw Tor access we can also subscribe with SETEVENTS [event types].

Events we've received are available in two different ways. First, /events provides a quick dump of the events we've received thus far...

../_images/events_command.png

You can list events of just a certain type by saying which (for instance /events BW). More useful though is the events() function, which provides a list of Event instances we've received...

../_images/events_variable.png

You can specify event types to either /events or events() to just receive events of those types (for instance, events('BW', 'DEBUG')).

To stop receiving events run SETEVENTS without any event types, and to clear the backlog of events we've received run /events clear.

Running individual commands

With its --run argument tor-prompt can also be used to run individual commands...

../_images/run.png

... listen to a space separated list of events with --run 'SETEVENTS [event_types]'...

../_images/run_events.png

... pipe its output to other destinations...

../_images/run_events_pipe.png

... and invoke files with a series of commands...

../_images/run_file.png