Socks5 Server Python

S

Writing a simple SOCKS server in Python | Artem Golubin

Writing a simple SOCKS server in Python | Artem Golubin

This article explains how to write a tiny and basic SOCKS 5 server in Python 3. 6. I am assuming that you already have a basic understanding of proxy troductionSOCKS is a generic proxy protocol that relays TCP connections from one point to another using intermediate connection (socks server). Originally, SOCKS proxies were mostly used as a circuit-level gateways, that is, a firewall between local and external resources (the internet). However, nowadays it is also popular in censorship circumvention and web roughout the article, I will be referring the RFC 1928 specification which describes SOCKS reading this article, I recommend you to clone a completed version of the implementation so you can see the full sessions handlingThe SOCKS protocol is implemented on top of the TCP stack, in such way that the client must establish a separate TCP connection with the SOCKS server for each remote server it wants to exchange data, first of all, we need to create a regular TCP session handler. Python has a built-in socketserver module, which simplifies the task of writing network socketserver import ThreadingMixIn, TCPServer, StreamRequestHandler
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
pass
class SocksProxy(StreamRequestHandler):
def handle(self):
# Our main logic will be here
if __name__ == ‘__main__’:
with ThreadingTCPServer((‘127. 0. 1′, 9011), SocksProxy) as server:
rve_forever()
Here the ThreadingTCPServer creates a threading version of TCP server and listens for incoming connections on a specified address and port. Every time there is a new incoming TCP connection (session) the server spawns a new thread with SocksProxy instance running inside it. It gives us an easy way to handle concurrent ThreadingMixIn can be replaced by ForkingTCPServer, which uses forking approach, that is, it spawns a new process for each TCP nnection establishment and negotiationWhen a client establishes a TCP session to the SOCKS server, it must send a greeting message consists of 3 fields:versionnmethodsmethods1 byte1 byte0 to 255 bytesHere version field represents a version of the protocol, which equals to 5 in our case. The nmethods field contains the number of authentication methods supported by the client. The methods field consists of a sequence of supported methods by the client. Thus the methods field indicates the length of a methods cording to the RFC 1928, the supported values of methods field defined as follows:’00’ NO AUTHENTICATION REQUIRED’01’ GSSAPI’02’ USERNAME/PASSWORD’03’ to X’7F’ IANA ASSIGNED’80’ to X’FE’ RESERVED FOR PRIVATE METHODS’FF’ NO ACCEPTABLE METHODSWhen the SOCKS server receives such message, it should choose an appropriate method and answer back. Let’s pretend we only support a USERNAME/PASSWORD format of the answer looks as follows:versionmethod1 byte1 byteHere is how the whole process looks in Python: def handle(self):
# Greating header
# read and unpack 2 bytes from a client
header = (2)
version, nmethods = (“! BB”, header)
# socks 5
assert version == SOCKS_VERSION
assert nmethods > 0
# Get available methods
methods = t_available_methods(nmethods)
# accept only USERNAME/PASSWORD auth
if 2 not in set(methods):
# close connection
ndall((“! BB”, SOCKS_VERSION, 255))
(quest)
return
# Send server choice
ndall((“! BB”, SOCKS_VERSION, 2))
def get_available_methods(self, n):
methods = []
for i in range(n):
(ord((1)))
return methods
Here the recv function reads n bytes from the client and the struct module helps to pack and unpack binary data using specified the client has received the server choice, it responds with username and password rsionulenunameplenpasswd1 byte1 byte0 to 255 bytes1 byte0 to 255 bytesThe version field represents the authentication version, which is equals to 1 in our case. The ulen and plen fields represent lengths of text fields so the server knows how much data it should read from the server response should look as follows:versionstatus1 byte1 byteThe status field of 0 indicates a successful authorization, while other values treated as a version of authorization looks as follows: def verify_credentials(self):
version = ord((1))
assert version == 1
username_len = ord((1))
username = (username_len)(‘utf-8’)
password_len = ord((1))
password = (password_len)(‘utf-8′)
if username == ername and password == ssword:
# Success, status = 0
response = (“! BB”, version, 0)
ndall(response)
return True
# Failure, status! = 0
response = (“! BB”, version, 0xFF)
return False
Once the authorization has completed the client can send request drdst. port1 byte1 byte1 byte1 byte4 to 255 bytes2 bytesWhere:VERSION protocol version: ’05’CMDCONNECT ’01’BIND ’02’UDP ASSOCIATE ’03’RSV RESERVEDATYP address type of following addressIP V4 address: ’01’DOMAINNAME: ’03’IP V6 address: ’04’ desired destination desired destination port in network octet orderThe cmd field indicates the type of connection. This article is limited to CONNECT method only, which is used for TCP connections. For more details, please read the SOCKS a client sends a domain name, it should be resolved by the DNS on the server side. Thus a client has no need for a working DNS server when working with soon as server establishes a connection to the desired destination it should reply with a status and remote drbnd. port1 byte1 byte1 byte1 byte4 to 255 bytes2 bytesWhere:VER protocol version: X’05’REP Reply field:’00’ succeeded’01’ general SOCKS server failure’02’ connection not allowed by ruleset’03’ Network unreachable’04’ Host unreachable’05’ Connection refused’06’ TTL expired’07’ Command not supported’08’ Address type not supported’09’ to X’FF’ unassignedRSV RESERVEDATYP address type of following addressIP V4 address: ’01’DOMAINNAME: ’03’IP V6 address: ’04’ server bound server bound port in network octet orderHere is how it looks in Python:# client request
version, cmd, _, address_type = (“! BBBB”, (4))
if address_type == 1: # ipv4
address = et_ntoa((4))
elif address_type == 3: # domain
domain_length = ord((1)[0])
address = (domain_length)
port = (‘! H’, (2))[0]
# server reply
try:
if cmd == 1: # CONNECT
remote = (_INET, CK_STREAM)
nnect((address, port))
bind_address = tsockname()
else:
addr = (“! I”, et_aton(bind_address[0]))[0]
port = bind_address[1]
reply = (“! BBBBIH”, SOCKS_VERSION, 0, 0, address_type,
addr, port)
except Exception as err:
# return Connection refused error
reply = nerate_failed_reply(address_type, 5)
ndall(reply)
# Establish data exchange
if reply[1] == 0 and cmd == 1:
_loop(nnection, remote)
If server’s reply indicates a success, the client may now start passing the data. In order to work with both client and remote hosts concurrently we can use select library which supports select and pool Unix is how we can read and resend data in one loop both from client and remote host:def exchange_loop(self, client, remote):
while True:
# wait until client or remote is available for read
r, w, e = ([client, remote], [], [])
if client in r:
data = (4096)
if (data) <= 0: break if remote in r: That's it! We have got a working SOCKS 5 we can test it using curl: curl -v --socks5 127. 1:9011 -U username:password How to create a simple and secure Socks5 proxy in python?

How to create a simple and secure Socks5 proxy in python?

I recommend using requesocks along with stem (assumes Tor). The official stem library is provided by Tor. Here’s a simplified example based on a scraper that I wrote which also uses fake_useragent so you look like a browser:
import requesocks
from fake_useragent import UserAgent
from stem import Signal
from ntrol import Controller
class Proxy(object):
def __init__(self,
socks_port=9050,
tor_control_port=9051,
tor_connection_password=’password’)
self. _socks_port = int(socks_port)
self. _tor_control_port = int(tor_control_port)
self. _tor_connection_password = tor_connection_password
self. _user_agent = UserAgent()
self. _session = None
self. _update_session()
def _update_session(self):
self. _session = ssion()
# port 9050 is the default SOCKS port
oxies = {
”: ‘socks5127. 0. 1:{}'(self. _socks_port),
”: ‘socks5127. _socks_port), }
def _renew_tor_connection(self):
with om_port(port=self. _tor_control_port) as controller:
thenticate(password=self. _tor_connection_password)
()
def _sample_get_response(self, url):
if not self. _session:
# generate random user agent string for every request
headers = {
‘User-Agent’:,
‘Accept’: ‘text/html, application/xhtml+xml, application/xml;q=0. 9, */*;q=0. 8’,
‘Accept-Language’: ‘en-us, en;q=0. 5’, } # adjust as desired
response = (url, verify=False, headers=headers)
return response
You must have the Tor service running before executing this script and you must also modify your torrc file to enable the control port (9051).
Tor puts the torrc file in /usr/local/etc/tor/torrc if you compiled Tor from source, and /etc/tor/torrc or /etc/torrc if you installed a pre-built package. If you installed Tor Browser, look for
Browser/TorBrowser/Data/Tor/torrc inside your Tor Browser directory (On Mac OS X, you must right-click or command-click on the Tor Browser icon and select “Show Package Contents” before the Tor Browser directories become
visible).
Once you’ve found your torrc file, you need to uncomment the corresponding lines:
ControlPort 9051
## If you enable the controlport, be sure to enable one of these
## authentication methods, to prevent attackers from accessing it.
HashedControlPassword 16:05834BCEDD478D1060F1D7E2CE98E9C13075E8D3061D702F63BCD674DE
Please note that the HashedControlPassword above is for the password “password”. If you want to set a different password (recommended), replace the HashedControlPassword in the torrc file by noting the output from tor –hash-password “” where is the password that you want to set.
Once you’ve changed your torrc file, you will need to restart tor for the changes to take effect (note that you actually only need to send Tor a HUP signal, not actually restart it). To restart it:
sudo service tor restart
I hope this helps and at least gets you started for what you were looking for.
PySocks - PyPI

PySocks – PyPI

PySocks lets you send traffic through SOCKS and HTTP proxy servers. It is a modern fork of SocksiPy with bug fixes and extra features.
Acts as a drop-in replacement to the socket module. Seamlessly configure SOCKS proxies for any socket object by calling t_proxy().
SOCKS proxy client for Python 2. 7 and 3. 4+
TCP supported
UDP mostly supported (issues may occur in some edge cases)
HTTP proxy client included but not supported or recommended (you should use urllib2’s or requests’ own HTTP proxy interface)
urllib2 handler included. pip install / install will automatically install the sockshandler module.
pip install PySocks
Or download the tarball / git clone and…
python install
These will install both the socks and sockshandler modules.
Alternatively, include just in your project.
Warning: PySocks/SocksiPy only supports HTTP proxies that use CONNECT tunneling. Certain HTTP proxies may not work with this library. If you wish to use HTTP (not SOCKS) proxies, it is recommended that you rely on your HTTP client’s native proxy support (proxies dict for requests, or oxyHandler for urllib2) instead.
cksocket
import socks
s = cksocket() # Same API as in the standard lib
t_proxy(CKS5, “localhost”) # SOCKS4 and SOCKS5 use port 1080 by default
# Or
t_proxy(CKS4, “localhost”, 4444)
t_proxy(, “5. 5. 5”, 8888)
# Can be treated identical to a regular socket object
nnect((“, 80))
ndall(“GET / HTTP/1. 1… “)
print (4096)
Monkeypatching
To monkeypatch the entire standard library with a single default proxy:
import urllib2
import socket
t_default_proxy(CKS5, “localhost”)
= cksocket
urllib2. urlopen(“) # All requests will pass through the SOCKS proxy
Note that monkeypatching may not work for all standard modules or for all third party modules, and generally isn’t recommended. Monkeypatching is usually an anti-pattern in Python.
urllib2 Handler
Example use case with the sockshandler urllib2 handler. Note that you must import both socks and sockshandler, as the handler is its own module separate from PySocks. The module is included in the PyPI package.
from sockshandler import SocksiPyHandler
opener = _opener(SocksiPyHandler(CKS5, “127. 0. 1”, 9050))
print (“) # All requests made by the opener will pass through the SOCKS proxy
Original SocksiPy README attached below, amended to reflect API changes.
SocksiPy
A Python SOCKS module.
(C) 2006 Dan-Haim. All rights reserved.
See LICENSE file for details.
WHAT IS A SOCKS PROXY?
A SOCKS proxy is a proxy server at the TCP level. In other words, it acts as
a tunnel, relaying all traffic going through it without modifying it.
SOCKS proxies can be used to relay traffic using any network protocol that
uses TCP.
WHAT IS SOCKSIPY?
This Python module allows you to create TCP connections through a SOCKS
proxy without any special effort.
It also supports relaying UDP packets with a SOCKS5 proxy.
PROXY COMPATIBILITY
SocksiPy is compatible with three different types of proxies:
SOCKS Version 4 (SOCKS4), including the SOCKS4a extension.
SOCKS Version 5 (SOCKS5).
HTTP Proxies which support tunneling using the CONNECT method.
SYSTEM REQUIREMENTS
Being written in Python, SocksiPy can run on any platform that has a Python
interpreter and TCP/IP support.
This module has been tested with Python 2. 3 and should work with greater versions
just as well.
INSTALLATION
Simply copy the file “” to your Python’s lib/site-packages directory,
and you’re ready to go. [Editor’s note: it is better to use python install for PySocks]
USAGE
First load the socks module with the command:
>>> import socks
>>>
The socks module provides a class called socksocket, which is the base to all of the module’s functionality.
The socksocket object has the same initialization parameters as the normal socket
object to ensure maximal compatibility, however it should be noted that socksocket will only function with family being AF_INET and
type being either SOCK_STREAM or SOCK_DGRAM.
Generally, it is best to initialize the socksocket object with no parameters
>>> s = cksocket()
The socksocket object has an interface which is very similiar to socket’s (in fact
the socksocket class is derived from socket) with a few extra methods.
To select the proxy server you would like to use, use the set_proxy method, whose
syntax is:
set_proxy(proxy_type, addr[, port[, rdns[, username[, password]]]])
Explanation of the parameters:
proxy_type – The type of the proxy server. This can be one of three possible
choices: PROXY_TYPE_SOCKS4, PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP for SOCKS4,
SOCKS5 and HTTP servers respectively. SOCKS4, SOCKS5, and HTTP are all aliases, respectively.
addr – The IP address or DNS name of the proxy server.
port – The port of the proxy server. Defaults to 1080 for socks and 8080 for.
rdns – This is a boolean flag than modifies the behavior regarding DNS resolving.
If it is set to True, DNS resolving will be preformed remotely, on the server.
If it is set to False, DNS resolving will be preformed locally. Please note that
setting this to True with SOCKS4 servers actually use an extension to the protocol,
called SOCKS4a, which may not be supported on all servers (SOCKS5 and servers
always support DNS). The default is True.
username – For SOCKS5 servers, this allows simple username / password authentication
with the server. For SOCKS4 servers, this parameter will be sent as the userid.
This parameter is ignored if an HTTP server is being used. If it is not provided,
authentication will not be used (servers may accept unauthenticated requests).
password – This parameter is valid only for SOCKS5 servers and specifies the
respective password for the username provided.
Example of usage:
>>> t_proxy(CKS5, “”) # uses default port 1080
>>> t_proxy(CKS4, “”, 1081)
After the set_proxy method has been called, simply call the connect method with the
traditional parameters to establish a connection through the proxy:
>>> nnect((“, 80))
Connection will take a bit longer to allow negotiation with the proxy server.
Please note that calling connect without calling set_proxy earlier will connect
without a proxy (just like a regular socket).
Errors: Any errors in the connection process will trigger exceptions. The exception
may either be generated by the underlying socket layer or may be custom module
exceptions, whose details follow:
class ProxyError – This is a base exception class. It is not raised directly but
rather all other exception classes raised by this module are derived from it.
This allows an easy way to catch all proxy-related errors. It descends from IOError.
All ProxyError exceptions have an attribute socket_err, which will contain either a
caught exception, or None if there wasn’t any.
class GeneralProxyError – When thrown, it indicates a problem which does not fall
into another category.
Sent invalid data – This error means that unexpected data has been received from
the server. The most common reason is that the server specified as the proxy is
not really a SOCKS4/SOCKS5/HTTP proxy, or maybe the proxy type specified is wrong.
Connection closed unexpectedly – The proxy server unexpectedly closed the connection.
This may indicate that the proxy server is experiencing network or software problems.
Bad proxy type – This will be raised if the type of the proxy supplied to the
set_proxy function was not one of SOCKS4/SOCKS5/HTTP.
Bad input – This will be raised if the connect() method is called with bad input
parameters.
class SOCKS5AuthError – This indicates that the connection through a SOCKS5 server
failed due to an authentication problem.
Authentication is required – This will happen if you use a SOCKS5 server which
requires authentication without providing a username / password at all.
All offered authentication methods were rejected – This will happen if the proxy
requires a special authentication method which is not supported by this module.
Unknown username or invalid password – Self descriptive.
class SOCKS5Error – This will be raised for SOCKS5 errors which are not related to
authentication.
The parameter is a tuple containing a code, as given by the server,
and a description of the
error. The possible errors, according to the RFC, are:
0x01 – General SOCKS server failure – If for any reason the proxy server is unable to
fulfill your request (internal server error).
0x02 – connection not allowed by ruleset – If the address you’re trying to connect to
is blacklisted on the server or requires authentication.
0x03 – Network unreachable – The target could not be contacted. A router on the network
had replied with a destination net unreachable error.
0x04 – Host unreachable – The target could not be contacted. A router on the network
had replied with a destination host unreachable error.
0x05 – Connection refused – The target server has actively refused the connection
(the requested port is closed).
0x06 – TTL expired – The TTL value of the SYN packet from the proxy to the target server
has expired. This usually means that there are network problems causing the packet
to be caught in a router-to-router “ping-pong”.
0x07 – Command not supported – For instance if the server does not support UDP.
0x08 – Address type not supported – The client has provided an invalid address type.
When using this module, this error should not occur.
class SOCKS4Error – This will be raised for SOCKS4 errors. The parameter is a tuple
containing a code and a description of the error, as given by the server. The
possible error, according to the specification are:
0x5B – Request rejected or failed – Will be raised in the event of an failure for any
reason other then the two mentioned next.
0x5C – request rejected because SOCKS server cannot connect to identd on the client –
The Socks server had tried an ident lookup on your computer and has failed. In this
case you should run an identd server and/or configure your firewall to allow incoming
connections to local port 113 from the remote server.
0x5D – request rejected because the client program and identd report different user-ids –
The Socks server had performed an ident lookup on your computer and has received a
different userid than the one you have provided. Change your userid (through the
username parameter of the set_proxy method) to match and try again.
class HTTPError – This will be raised for HTTP errors. The message will contain
the HTTP status code and provided error message.
After establishing the connection, the object behaves like a standard socket.
Methods like makefile() and settimeout() should behave just like regular sockets.
Call the close() method to close the connection.
In addition to the socksocket class, an additional function worth mentioning is the
set_default_proxy function. The parameters are the same as the set_proxy method.
This function will set default proxy settings for newly created socksocket objects,
in which the proxy settings haven’t been changed via the set_proxy method.
This is quite useful if you wish to force 3rd party modules to use a SOCKS proxy,
by overriding the socket object.
For example:
>>> t_default_proxy(CKS5, “”)
>>> = cksocket
>>> urllib. urlopen(“)
PROBLEMS
Please open a GitHub issue at

Frequently Asked Questions about socks5 server python

About the author

proxyreview

If you 're a SEO / IM geek like us then you'll love our updates and our website. Follow us for the latest news in the world of web automation tools & proxy servers!

By proxyreview

Recent Posts

Useful Tools