0

This is the whonix documentation on stream isolation and tor circuits

This is the whonix documentation on interfacing and controlling Tor via sockets

I have previously tried the python requests library to make GET requests to Tor's official link for checking exit node IP information inside a whonix workstation VM (read about whonix here). The request always shows the same IP information, independent of me running the script, closing it, running it again. In the first link the author describes what applications are already supported. If not listed, the user must provide support.

I attempted to provide support in my own script by communicating to the specific socket using first sockets, then the stem library. Sockets by itself had no effect, and now the stem library is giving me errors at runtime.

from stem import Signal
from stem.control import Controller

with Controller.from_port(port=9051) as controller:
        controller.signal(Signal.NEWNYM)
        controller.close()

This code gives the following runtime error:

Traceback (most recent call last):
  File "/path/to/stem/connection.py", line 1018, in get_protocolinfo
    protocolinfo_response = _msg(controller, 'PROTOCOLINFO 1')
  File "/path/to/stem/connection.py", line 1036, in _msg
    return controller.msg(message)
  File "/path/to/stem/control.py", line 658, in msg
    raise response
  File "/path/to/stem/control.py", line 937, in _reader_loop
    control_message = self._socket.recv()
  File "/path/to/stem/socket.py", line 464, in recv
    return self._recv(lambda s, sf: recv_message(sf))
  File "/path/to/stem/socket.py", line 278, in _recv
    return handler(my_socket, my_socket_file)
  File "/path/to/stem/socket.py", line 464, in <lambda>
    return self._recv(lambda s, sf: recv_message(sf))
  File "/path/to/stem/socket.py", line 693, in recv_message
    raise stem.SocketClosed('Received empty socket content.')
stem.SocketClosed: Received empty socket content.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/path/to/stem/connection.py", line 530, in authenticate
    protocolinfo_response = get_protocolinfo(controller)
  File "/path/to/stem/connection.py", line 1020, in get_protocolinfo
    raise stem.SocketError(exc)
stem.SocketError: Received empty socket content.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "my_program.py", line 103, in <module>
    controller.authenticate()
  File "/path/to/stem/control.py", line 1100, in authenticate
    stem.connection.authenticate(self, *args, **kwargs)
  File "/path/to/stem/connection.py", line 534, in authenticate
    raise AuthenticationFailure('socket connection failed (%s)' % exc)
stem.connection.AuthenticationFailure: socket connection failed (Received empty socket content.)

How can this be resolved? Is there a better solution to provide support that I have not yet considered?

1 Answers1

0

There is no need to use stem or connect to the control port to enable stream isolation for your circuits. Stream isolation is determined by the credentials supplied to Tor's SOCKS proxy.

If you are using Python requests, see this answer.

To use the same IP for a connection, use the same credentials when connecting to the SOCKS proxy. If you want to change the IP (use a different circuit), then you need only use a different set of credentials.

In the example below, each requests session uses a different circuit and should have a different exit IP address.

session1 = requests.session()
session1.proxies = {'http': 'socks5h://foo1:bar1@localhost:9050', 'https': 'socks5h://foo1:bar1@localhost:9050'}
r = session1.get('https://httpbin.org/ip')

session2 = requests.session()
session2.proxies = {'http': 'socks5h://foo2:bar2@localhost:9050', 'https': 'socks5h://foo2:bar2@localhost:9050'}
r = session2.get('https://httpbin.org/ip')

Keep in mind, the number of exits is limited so if you're rapidly creating many streams, eventually you will build circuits that use the same exit IP as previous circuits.

drew010
  • 68,777
  • 11
  • 134
  • 162