the fast, reliable localhost tunneling solution


Chaining support in SocksiPy

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

SocksiPy

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

Motivation

During PageKite development we've found ourselves repeatedly encountering the concept of chained proxies. We both want pagekite.py 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 pagekite.py 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 pagekite.py.

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 pagekite.py all the same. Moving most of that logic into an improved sockispy module seems like a good way to both simplify pagekite.py 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.

Mini-roadmap:

  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 pagekite.py 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

socks.DEBUG = DEBUG

# Configure a default chain
chain = [
  'tor://localhost:9050/', # First hop is Tor,
  'ssl://proxy.example.com:8443/', # then SSL to proxy.example.com
  'http://user:pass@proxy.example.com/' # ...and auth to an HTTP proxy
]
socks.setdefaultproxy() # Clear the default chain
for hop in chain:
   socks.adddefaultproxy(*socks.parseproxy(hop))

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

# This would have set proxies using the standard environment variables:
#socks.usesystemdefaults()

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

Command-line Examples

# 'netcat' over Tor and and an HTTP proxy, to foo.com:443
$ sockschain.py tor:localhost http:proxy.example.com:8080 foo.com:443

# Connect to hidden pagekite service (e.g. ssh)
$ sockschain.py https:foo.pagekite.me:443 foo.pagekite.me:22

# Same as above, but use system default proxy as first hop
$ sockschain.py defaults https:foo.pagekite.me:443 foo.pagekite.me:22

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

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

Comments

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!

Wiki

Download

Donate

We accept Bitcoin at:

1P28Ke4FPrumagwDu6VLb7FibjQJ7UtV6f