GithubHelp home page GithubHelp logo

sethmlarson / socksio Goto Github PK

View Code? Open in Web Editor NEW
51.0 4.0 11.0 65 KB

Sans-I/O implementation of SOCKS4, SOCKS4A, and SOCKS5

Home Page: https://pypi.org/project/socksio

License: MIT License

Python 98.93% Dockerfile 0.53% Shell 0.54%
python socks socks5 socks4 socks4a sans-io socks-proxy

socksio's Introduction

SOCKSIO

Build Status codecov Supported Python Versions PyPI

Client-side sans-I/O SOCKS proxy implementation. Supports SOCKS4, SOCKS4A, and SOCKS5.

socksio is a sans-I/O library similar to h11 or h2, this means the library itself does not handle the actual sending of the bytes through the network, it only deals with the implementation details of the SOCKS protocols so you can use it in any I/O library you want.

Current status: stable

Features not yet implemented:

  • SOCKS5 GSS-API authentication.
  • SOCKS5 UDP associate requests.

Usage

TL;DR check the examples directory.

Being sans-I/O means that in order to test socksio you need an I/O library. And the most basic I/O is, of course, the standard library's socket module.

You'll need to know ahead of time the type of SOCKS proxy you want to connect to. Assuming we have a SOCKS4 proxy running in our machine on port 8080, we will first create a connection to it:

import socket

sock = socket.create_connection(("localhost", 8080))

socksio exposes modules for SOCKS4, SOCKS4A and SOCKS5, each of them includes a Connection class:

from socksio import socks4

# The SOCKS4 protocol requires a `user_id` to be supplied.
conn = socks4.SOCKS4Connection(user_id=b"socksio")

Since socksio is a sans-I/O library, we will use the socket to send and receive data to our SOCKS4 proxy. The raw data, however, will be created and parsed by our SOCKS4Connection.

We need to tell our connection we want to make a request to the proxy. We do that by first creating a request object.

In SOCKS4 we only need to send a command along with an IP address and port. socksio exposes the different types of commands as enumerables and a convenience from_address class method in the request classes to create a valid request object:

# SOCKS4 does not allow domain names, below is an IP for google.com
request = socks4.SOCKS4Request.from_address(
    socks4.SOCKS4Command.CONNECT, ("216.58.204.78", 80))

from_address methods are available on all request classes in socksio, they accept addresses as tuples of (address, port) as well as string address:port.

Now we ask the connection to send our request:

conn.send(request)

The SOCKS4Connection will then compose the necessary bytes in the proper format for us to send to our proxy:

data = conn.data_to_send()
sock.sendall(data)

If all goes well the proxy will have sent reply, we just need to read from the socket and pass the data to the SOCKS4Connection:

data = sock.recv(1024)
event = conn.receive_data(data)

The connection will parse the data and return an event from it, in this case, a SOCKS4Reply that includes attributes for the fields in the SOCKS reply:

if event.reply_code != socks4.SOCKS4ReplyCode.REQUEST_GRANTED:
    raise Exception(
        "Server could not connect to remote host: {}".format(event.reply_code)
    )

If all went well the connection has been established correctly and we can start sending our request directly to the proxy:

sock.sendall(b"GET / HTTP/1.1\r\nhost: google.com\r\n\r\n")
data = receive_data(sock)
print(data)
# b'HTTP/1.1 301 Moved Permanently\r\nLocation: http://www.google.com/...`

The same methodology is used for all protocols, check out the examples directory for more information.

Development

Install the test requirements with pip install -r test-requirements.txt.

Install the project in pseudo-editable mode with flit install -s.

Tests can be ran directly invoking pytest.

This project uses nox to automate testing and linting tasks. nox is installed as part of the test requirements. Invoking nox will run all sessions, but you may also run only some them, for example nox -s lint will only run the linting session.

In order to test against a live proxy server a Docker setup is provided based on the Dante SOCKS server.

A container will start danted listening on port 1080. The docker-compose.yml will start the container and map the ports appropriately. To start the container in the background:

docker-compose -f docker/docker-compose.yml up -d

To stop it:

docker-compose -f docker/docker-compose.yml down

Alternatively, remove the -d flag to run the containers in the foreground.

Reference documents

Each implementation follows the documents as listed below:

License

MIT

socksio's People

Contributors

justlund avatar sethmlarson avatar tjni avatar tomchristie avatar yeraydiazdiaz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

socksio's Issues

What the allowed SOKS5A error responses?

Ref: tailscale/tailscale#6144

that particular project set up a local SOCKS5A server, which sometimes responds, on upstream error, in a way that this Python client library doesn't like, which yields this backtrace:

python3.10/site-packages/socksio/socks5.py", line 257, in loads
    atype = SOCKS5AType(data[3:4])
  File "/usr/local/lib/python3.10/enum.py", line 385, in __call__
    return cls.__new__(cls, value)
  File "/usr/local/lib/python3.10/enum.py", line 710, in __new__
    raise ve_exc
ValueError: b'\x00' is not a valid SOCKS5AType

Thus the question, if the server somehow rejects the request, is it required to fill in bind address type, address and port, or can those be left blank (zero) if the reply (code) is not zero?

Acceptance tests

Up until now I've been running the example scripts against a local SSH proxy, it would be nice to have this process automated.

I believe the SSH proxy does not support username/password though, mitmproxy would've been excellent but it only supports SOCKS5.

I'm trying out Dante which seems pretty full featured.

Any other suggestions?

Move away from Travis

Yes, we're still using Travis ๐Ÿ˜…

I assume to GitHub Actions since urllib3 and quite a lot of other projects use it.

Cannnot install on Mac OSX

Hello,

Thank you for creating this package. This has been a good tool for me and my tools.

Unfortunately on Mac OSX I cannot install the pip package.

pip install socksio 
ERROR: Could not install packages due to an OSError: Missing dependencies for SOCKS support.

Although the package can be used if cloned locally. But it makes it harder of a tool like httpx[socks] that is a dependency of a dependency.

Can this be just a pip packaging option ? I do have access to a mac that can do any tests if necessary.

Existing usage in the wild?

Hi people :-)

Just a small question from me. I'm eager to bootstrap SOCKS support in HTTPX/HTTPCore back up from previous work (@yeraydiazdiaz's encode/httpcore#51, also encode/httpcore#187).

I thought URLLib3 had migrated its SOCKS support to use socksio, but looking at the GitHub repo there I'm not able to find a reference to socksio anymore.

Is this package depended upon by a project yet? I'm happy to lend a hand with maintenance if we integrate this into HTTPCore. Just curious what the status is.

Encapsulate actions in classes?

While writing the examples I noticed a couple of moments where it felt the API was a bit too low level, for example:

conn.request(socks4.SOCKS4Command.CONNECT, "216.58.204.78", 80)

I noticed h11's API encapsulates these actions in classes and reduces the Connection class's API to just methods that deal with sending, recieving and state control.

Of course, there's quite a difference in complexity between the protocols, but I think it might be worth taking a page from their book in that regard, particularly for SOCKS5 where there's a few more actions that can be performed.

Thoughts?

Add usage documentation to the README

This library should be simple enough to have one page of documentation so we may as well just add it to the README.

I'm thinking a section to document how to use the SOCKS[45]Connection classes as a consumer and then a section with all importable classes and a brief description of them.

Documentation

I think it'd be good to start making a proper documentation, ideally with API documentation.

I was thinking of (surprise) copying h11's format.

Thoughts?

Setup automated releases to PyPI

I'm thinking using CalVer because our API isn't going to change and the only time this library will change is if there are bug-fixes.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.