6

I'm using the stem to control a tor node created with stem.process.launch_tor_with_config. I've also created a stem.control.Controller that is operating on the aforementioned process' control port.

How can I change the exit node? I looked at stem.controller.Controller.new_circuit, but this appears to change the intermediate nodes, preserving the endpoint.

Does anybody know how this could be done?

Thanks!

Edit:

So I think I may be misunderstanding something fundamental, but I can't seem to wrap my head around it. I tried calling Controller.get_circuits() and found a list of CircuitEvent objects. Does this mean that a single process can handle multiple circuits? If so, how do I select one for use?

Note that I'm directing HTTP requests to through Privoxy, which in turn is forwarding it to the tor process' SOCKS port.

Edit 2:

I found something that works, but I don't know how it works, which worries me. I'll gladly award an answer to anyone who can either:

  1. Explain why my approach works
  2. Show be a better approach and explain how that works

Here's what I've done:

for circuit in controller.get_circuits():
    controller.close_circuit(circuit.id)

There it is. The external IP changed, so I know I've done something but hell if I know exactly what.

Louis Thibault
  • 20,240
  • 25
  • 83
  • 152

1 Answers1

6

You have a couple options to use a specific exit...

  • Set the ExitNodes attribute in your torrc. This is exemplified in...

https://stem.torproject.org/tutorials/to_russia_with_love.html

  • Call extend_circuit() on one of your present circuits to the desired endpoint...

https://stem.torproject.org/api/control.html#stem.control.Controller.extend_circuit

If the question you're trying to ask is really 'how do I get a new IP address' then that's a question we're more reluctant to answer. Partly because it's primarily for ban evasion or SEO, and partly because repeated circuit creation puts a high load on the Tor network.

As for why your IP seems to change when you call close_circuit(), that's because Tor then needs to recreate a new circuit on your behalf for the following request. There is no guarantee that the IP will be new, and doing so involves a fair bit of traffic to telescope your connection through three fresh hops.

I'm not often on StackOverflow so if you have further questions about scripting against Tor then I would suggest the tor-dev@ email list...

https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev/

Cheers! -Damian (stem's author)

Damian
  • 2,944
  • 2
  • 18
  • 15
  • First of all, thank you for your answer. Second of all, please have my assurance that I'm not abusing the TOR network. My goas *is*, in fact, to have some control over the endpoint IP, but I'm doing this for (what I think) is a good reason. I'm trying to run a pool of TOR processes with various IPs to investigate some properties of the TOR network. In other words, I'm hacking (in the constructive sense). I hope this is okay! With that in mind, is there a way to make a guaranteed change in endpoint IP? – Louis Thibault Jun 11 '13 at 16:04
  • Glad to hear! If you're simply looking for a pool of different exit relays then the simplest option wound probably be to find the set you want to use in atlas (http://atlas.torproject.org/), then call create_circuit() to make a circuit through each of them. The unpleasant bit is that you'll need to manually attach streams to circuits to determine 'which stream gets which IP'. See attach_stream() for this (https://stem.torproject.org/api/control.html#stem.control.Controller.attach_stream). – Damian Jun 11 '13 at 17:05