This is a simple [[http://en.wikipedia.org/wiki/SOCKS|SOCKSv4 proxy]] written in pure python. Suitable for use with browsers. #!/usr/bin/python import sys import socket import struct import thread from optparse import OptionParser # Very simple multi-threaded SOCKSv4(a) proxy # by Tyler Bletsch (Tyler.Bletsch at gmail dot com) parser = OptionParser("Usage: %prog [options]") parser.add_option("-p", "--port", dest="listen_port", help="Port on which to listen (default: %default).", metavar="PORT", type="int", default=1080) parser.add_option("-l", "--listen-interface", dest="listen_interface", help="IP address of the interface to listen on (default: all of them).", metavar="IP", default='0.0.0.0') parser.add_option("-c", "--connect-interface", dest="connect_interface", help="IP address of the interface to connect out with (default: default route).", metavar="IP", default=None) parser.add_option("-b", "--buffer-size", dest="buffer_size", help="Size of the forwarding buffer (default: %default).", metavar="N", type="int", default=4096) (options, args) = parser.parse_args() buffer_size = options.buffer_size listen_port = options.listen_port listen_interface = options.listen_interface connect_interface = options.connect_interface def readstr(s): r='' while 1: c = s.recv(1) if not c: return None if c == '\0': break r += c return r def tunnel(src,dest): while 1: try: r = src.recv(buffer_size) except Exception as e: print "Recv error: %s" % e src.close() dest.close() break if not r: src.close() dest.close() break try: dest.send(r) except Exception as e: print "Send error: %s" % e src.close() dest.close() break svr = socket.socket(socket.AF_INET, socket.SOCK_STREAM) svr.bind((listen_interface, listen_port)) svr.listen(32) SOCKS4_REQUEST_FORMAT = '!BBH4s' # byte (socks_ver), byte (command), short (port), 4-char string (IP addr) SOCKS4_RESPONSE_OKAY = struct.pack('!BBHI',0,0x5a,0,0) SOCKS4_RESPONSE_FAIL = struct.pack('!BBHI',0,0x5b,0,0) print "Listening on %s:%d..." % (listen_interface,listen_port) while 1: initiator, initiator_addr = svr.accept() sys.stdout.write('%16s:%-5d ' % (initiator_addr)) data = initiator.recv(struct.calcsize(SOCKS4_REQUEST_FORMAT)) if not data: print "Connection dropped." break (socks_ver,command,target_port,target_addr) = struct.unpack(SOCKS4_REQUEST_FORMAT,data) (target_addr_int,) = struct.unpack('!I',target_addr) target_addr = socket.inet_ntoa(target_addr) username = readstr(initiator) if socks_ver!=4: print "Dropping non-SOCKSv4 request." initiator.send(SOCKS4_RESPONSE_FAIL) initiator.close() continue if command!=1: print "Dropping non-connect request." initiator.send(SOCKS4_RESPONSE_FAIL) initiator.close() continue is_socks4a = target_addr_int>0 and target_addr_int<256 # check for 0.0.0.x, i.e. SOCKS4a domain mode if is_socks4a: target_addr = readstr(initiator) sys.stdout.write("SOCKSv4%s => %s:%d " % ('a' if is_socks4a else ' ', target_addr, target_port)) target = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if connect_interface: target.bind((connect_interface, 0)) try: target.connect((target_addr, target_port)) except Exception as e: initiator.send(SOCKS4_RESPONSE_FAIL) initiator.close() print "FAIL: %s" % e continue if not target: initiator.send(SOCKS4_RESPONSE_FAIL) initiator.close() print "FAIL" continue print "OK" initiator.send(SOCKS4_RESPONSE_OKAY) thread.start_new_thread(tunnel,(initiator,target)) thread.start_new_thread(tunnel,(target,initiator))