Using normal sockets I can stream a list of numbers (updated every second) from a server to a client. This works perfectly fine. Now I want to do the same using Tor. Using Socksipy I am able to make HTTP requests to a web page (using this code). So from that starting point, I tried to build a piece of code that connects to a remote socket through Tor like this:

import socket
import socks
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "", 9050, True)
#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s = socket.socket = socks.socksocket
s.connect(('<the ip address here>', 46956))
s.sendall('Hello world')

If I uncomment line 4 and comment out line 5 it all works fine, but running it like this results in an error saying: TypeError: unbound method connect() must be called with socksocket instance as first argument (got tuple instance instead).

So my question: What am I doing wrong here? How can I connect to this remote socket through Tor?

Also two other questions:

  1. Is there no better way of doing this? By using stem.socket for example?
  2. How would I be able to build the public socket that I want to connect to, using a Tor hidden service?

Any information or hints are welcome.


This works for me:

import socket
import socks

socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "", 9050, True)
s = socks.socksocket()
s.connect(('anguilla.debian.or.at', 1234))
s.sendall('Hello world')

So, that's just initializing s differently, via s = socks.socksocket().

With socks, connect() also takes a hostname. This should enable you to connect to a hidden service, as in:

socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "", 9050, True)
s = socks.socksocket()
s.connect(('3g2upl4pq6kufc4m.onion', 80))

message = 'GET / HTTP/1.0\r\n\r\n'

reply = s.recv(4069)
print reply

You're almost there, you're replacing socket.socket with socks.socket, so far so good.

However upon assignment of variable s, you're not properly instantiating the replacement class, and therefore later during the connect call, your code results in the unbound method type error.

In your original code, s gets assigned a class instance, and in your updated code, a class method, it's in the difference of socket.socket(...) vs sock.socket, see?

Try this instead:

socket.socket = socks.socksocket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Because you don't actually want to replace socket.socket (a module level class) with a class instance (it might be needed later or be relied upon within 3rd party libraries you're not even aware of).

As for your other two questions, I'm not familiar with stem.socket at all, sorry. With regard to building the public (listening) part of your socket, you do no such thing, you use the tor distribution to tie in your "existing" server to the tor network. Unless ofcourse you don't want your software to be dependent on the official tor distribution, and build it into your code on your own (to my knowledge, no python implementation or library of/for the tor protocol exists, let alone the hidden service implementation, but don't quote me on this). It's not that technically complex a protocol, but if you go that route you need to read a lot of rfc's in order to stay compatible with the rest of the network, version interopability etc.

-- Kind regards, Yuka

  • so, what is wrong with the Weasel's code? what does it lack to read a .onion site? – user4928 Oct 22 '14 at 13:37
  • @john Well, nothing is wrong with Weasel's code, in the sense that his code works. However, besides just asking how to, the OP asked foremost what was WRONG with his code. My answer pointed that out. Furthermore it's far more valuable for OP to understand why something doesn't work, instead of just having a solution as to what would. That being said, I never made any claims stating Weasel's code was faulty in any way. – Yuka Oct 23 '14 at 2:11
  • @john Weasel's answer also didn't touch upon the other (important) part of the question about the incoming connection for the hidden service part, that and the explanation in my previous comment made me feel warranted to supply OP with an alternate (and imho, more complete) answer. – Yuka Oct 23 '14 at 2:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.