the fast, reliable localhost tunneling solution

Chaining support in SocksiPy

By Bjarni RĂșnar Einarsson 2012-05-08, 14:11


During the 0.4.x cycle of development, the socksipy Python module was adopted and enhanced to handle the PageKite tunnel connections.


During PageKite development we've found ourselves repeatedly encountering the concept of chained proxies. We both want to be able to connect to the world, even over convoluted paths, and we want clients to be able to access services behind PageKite, in which case itself may be the final proxy in a chain of multiple hops.

Another important goal, was to be able to TLS-encrypt our communication as much as possible, even if the underlying tools or libraries don't know how to. We have had difficulties configuring both urllib and xmlrpclib for TLS encryption, especially on older Python distributions. The Python SSL libraries themselves currently lack SNI support and basic support for things like certificate name validation, which leads to another set of weird work-arounds in

Finally, in some cases, being able to use anonymous TLS ciphers might allow PageKite connections to circumvent blocking, because packet sniffers would have no idea what service is actually being requested (recommendation from Jacob Applebaum).

The PageKiteProtocol does not actually say much about encryption and proxies, but for the above reasons, a lot of encryption and proxy code has found it's way into all the same. Moving most of that logic into an improved sockispy module seems like a good way to both simplify and make the features more widely available to other Python projects.

Code and Plan

The code is on github and .tar.gz archives for individual releases may be found here.


  1. Add chaining support - done
  2. Add routing support (so host A is proxied differently from B) - done
  3. Create a simple netcat replacement which supports chaining - done
  4. Add support for anonymous TLS encryption - done
  5. Add support for secure TLS encryption - done
  6. ???
  7. Contribute patches back up-stream to previous maintainers.

This module is used by 0.4.4 and above to handle encryption and proxy chaining for all outgoing connections.

Python Example

import socket
import sockschain as socks

# Enable debugging
def DEBUG(msg):
  print msg


# Configure a default chain
chain = [
  'tor://localhost:9050/', # First hop is Tor,
  'ssl://', # then SSL to
  '' # ...and auth to an HTTP proxy
socks.setdefaultproxy() # Clear the default chain
for hop in chain:

# Configure alternate routes (no proxy for localhost)
socks.setproxy('localhost', socks.PROXY_TYPE_NONE)
socks.setproxy('', socks.PROXY_TYPE_NONE)

# This would have set proxies using the standard environment variables:

rawsocket = socket.socket
socket.socket = socks.socksocket
# Everything will be proxied!

Command-line Examples

# 'netcat' over Tor and and an HTTP proxy, to
$ tor:localhost

# Connect to hidden pagekite service (e.g. ssh)

# Same as above, but use system default proxy as first hop
$ defaults

To enable debugging, add --debug to any command-line.

To prefer python's native SSL library over pyOpenSSL, add --nopyopenssl.


None yet, you can be first!

Leave a comment

( (Please leave these blank: )

We use Gravatar for commenter's photos. Get your own, it's free!




We accept Bitcoin at: