Skip to main content

sans-io socks proxy client/server with couple io backends

Project description


Travis status for master branch Codecov coverage for master branch Pypi version Pypi downloads count

Sans-io socks 4/5 client/server library/framework.


  • No one-shot socks servers
  • Sans-io
  • asyncio-ready twunnel3 is dead
  • aiosocks do not mimic asyncio.open_connection arguments (maybe dead too)
  • Fun


  • Only tcp connect (no bind, no udp)
  • Both client and server
  • Socks versions: 4, 4a, 5
  • Socks5 auth: no auth, username/password
  • Couple io backends: asyncio, trio, socketserver
  • One-shot socks server (python -m siosocks)


siosocks is offered under WTFPL license.


  • python 3.6+

IO implementation matrix

Framework Client Server
asyncio + +
trio + +
socket +

Feel free to make it bigger :wink:


End user implementations mimic «parent» library api.


Extra keyword-only arguments:

  • socks_host: string
  • socks_port: integer
  • socks_version: integer (4 or 5)
  • username: optional string (default: None)
  • password: optional string (default: None)
  • encoding: optional string (default: "utf-8")
  • socks4_extras: optional dictionary
  • socks5_extras: optional dictionary


  • socks4
    • user_id: string (default: "")
  • socks5
    • None at this moment, added for uniform api


End user implementations mimic «parent» library server request handlers.

You should use partial to bind socks specific arguments:

  • allowed_versions: set of integers (default: {4, 5})
  • username: optional string (default: None)
  • password: optional string (default: None)
  • strict_security_policy: boolean, if True exception will be raised if authentication required and 4 is in allowed versions set (default: True)
  • encoding: optional string (default: "utf-8")

Nothing to say more. Typical usage can be found at



This section will use asyncio as backend, since it is main target/reason for siosocks


import asyncio

from import open_connection

HOST = ""
REQ = """GET /?format=json HTTP/1.1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en,en-US;q=0.7,ru;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0


async def main():
    # assume we have tor started
    r, w = await open_connection(HOST, 80, socks_host="localhost", socks_port=9050, socks_version=5)
    w.write(REQ.replace("\n", "\r\n").encode())
    await w.drain()

loop = asyncio.get_event_loop()


import socket
import asyncio
import contextlib

from .io.asyncio import socks_server_handler

loop = asyncio.get_event_loop()
coro = asyncio.start_server(socks_server_handler,, port=ns.port, family=family)
server = loop.run_until_complete(coro)
addresses = []
for sock in server.sockets:
    if in (socket.AF_INET, socket.AF_INET6):
        host, port, *_ = sock.getsockname()
print(f"Socks{socks_versions} proxy serving on {', '.join(addresses)}")
with contextlib.suppress(KeyboardInterrupt):

But if you just want one-shot socks server then try:

python -m siosocks

This will start socks 4, 5 server on all interfaces on 1080 port. For more information try --help

python -m siosocks --help
usage: siosocks [-h] [--backend {asyncio,socketserver,trio}] [--host HOST]
                [--port PORT] [--family {ipv4,ipv6,auto}] [--socks SOCKS]
                [--username USERNAME] [--password PASSWORD]
                [--encoding ENCODING] [--no-strict] [-v]

Socks proxy server

optional arguments:
  -h, --help            show this help message and exit
  --backend {asyncio,socketserver,trio}
                        Socks server backend [default: asyncio]
  --host HOST           Socks server host [default: None]
  --port PORT           Socks server port [default: 1080]
  --family {ipv4,ipv6,auto}
                        Socket family [default: auto]
  --socks SOCKS         Socks protocol version [default: []]
  --username USERNAME   Socks auth username [default: None]
  --password PASSWORD   Socks auth password [default: None]
  --encoding ENCODING   String encoding [default: utf-8]
  --no-strict           Allow multiversion socks server, when socks5 used with
                        username/password auth [default: False]
  -v, --version         Show siosocks version


Shadowsocks-like client/server. Shadowsocks-like built on top of socks5 and encryption. It have «client», which is actually socks server and «server». So, precisely there are two servers: client side and server side. Purpose of shadowsocks is to encrypt data between «incoming» and «outgoing» servers. In common this looks like:

client (non-encrypted socks) «incoming» socks server (encrypted socks) «outgoing» socks server (non-socks connection) target server

Example above use Caesar cipher for simplicity (and security of course).


  • add more backends (average)
  • speed up passthrough implementation (seems hard)

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for siosocks, version 0.0.2
Filename, size File type Python version Upload date Hashes
Filename, size siosocks-0.0.2.tar.gz (34.6 kB) File type Source Python version None Upload date Hashes View
Filename, size siosocks-0.0.2-py3-none-any.whl (13.6 kB) File type Wheel Python version py3 Upload date Hashes View

Supported by

AWS AWS Cloud computing Datadog Datadog Monitoring Facebook / Instagram Facebook / Instagram PSF Sponsor Fastly Fastly CDN Google Google Object Storage and Download Analytics Huawei Huawei PSF Sponsor Microsoft Microsoft PSF Sponsor NVIDIA NVIDIA PSF Sponsor Pingdom Pingdom Monitoring Salesforce Salesforce PSF Sponsor Sentry Sentry Error logging StatusPage StatusPage Status page