During the 0.4.x cycle of pagekite.py
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 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.
The code is on github and .tar.gz archives for individual releases may be found here.
Mini-roadmap:
This module is used by pagekite.py
0.4.4 and above to handle encryption and proxy chaining for all outgoing connections.
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!
# '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
.
We accept Bitcoin at:
Comments
This is very confusing, to install, to run, you mix PySocksipyChain, sockschain and socksipy to explain one you link to another module, to install you say use socks.py, which one? I hava more than 8 socks.py.
May you develop and explain howto?
Thanks
My email does not work very well but bitmessage address does:
BM-2cU3dbpW6QFP7NCHQwqwpSNW4M7iZvcw1X