rsocks 2.3.0

A super basic SOCKS5 proxy.
Documentation

Build and Test codecov Version Crates.io GitHub all releases License:MIT

rusty_socks

A super basic SOCKS5 proxy, written in Rust on tokio.

Published on crates.io as rsocks (and the binary is rsocks) — the rusty_socks name was already taken by an unrelated crate. The GitHub repo and Docker image stay rusty_socks.

rusty_socks is a small, no-frills SOCKS5 (CONNECT) proxy: point a browser, an ssh ProxyCommand, or anything else SOCKS5-aware at it and it relays TCP to the requested destination. It adds a CIDR allow-list, optional username/password authentication, a reset-on-activity idle timeout, and optional binding to specific network interfaces — and nothing else.

Usage

Run with defaults (listen on 0.0.0.0:1080, accept every client):

$ rsocks

Every option is available as a CLI flag or its RS_* environment variable (flags win):

$ rsocks --help
A super basic SOCKS5 proxy.

Usage: rsocks [OPTIONS]

Options:
      --listen-interface <LISTEN_INTERFACE>
          Network interface whose IP the proxy listens on (defaults to `0.0.0.0`) [env: RS_LISTEN_INTERFACE=]
      --endpoint-interface <ENDPOINT_INTERFACE>
          Network interface whose IP is used for outbound connections to endpoints (defaults to `0.0.0.0`) [env: RS_ENDPOINT_INTERFACE=]
      --port <PORT>
          Port to listen on [env: RS_PORT=] [default: 1080]
      --buffer-size <BUFFER_SIZE>
          Per-direction buffer size, in bytes [env: RS_BUFFER_SIZE=] [default: 2048]
      --read-timeout <READ_TIMEOUT>
          Idle timeout in milliseconds: a connection with no traffic in either direction for this long is closed. `0` disables the idle timeout entirely [env: RS_READ_TIMEOUT=] [default: 60000]
      --accept-cidr <ACCEPT_CIDR>
          CIDR of client addresses allowed to connect [env: RS_ACCEPT_CIDR=] [default: 0.0.0.0/0]
      --username <USERNAME>
          Username required for SOCKS5 username/password authentication (RFC 1929). Must be set together with `--password`; when both are unset, the proxy requires no auth [env: RS_USERNAME=]
      --password <PASSWORD>
          Password required for SOCKS5 username/password authentication (RFC 1929). Must be set together with `--username` [env: RS_PASSWORD=]
  -h, --help
          Print help
  -V, --version
          Print version

Configuration

Flag Env var Default Description
--listen-interface RS_LISTEN_INTERFACE (none → 0.0.0.0) Network interface whose IP the proxy listens on.
--endpoint-interface RS_ENDPOINT_INTERFACE (none → 0.0.0.0) Network interface used for outbound connections to endpoints.
--port RS_PORT 1080 Port to listen on.
--buffer-size RS_BUFFER_SIZE 2048 Per-direction buffer size, in bytes.
--read-timeout RS_READ_TIMEOUT 60000 Idle timeout (ms); the clock resets on every byte, so only genuinely silent connections are reaped. 0 disables it.
--accept-cidr RS_ACCEPT_CIDR 0.0.0.0/0 CIDR of client addresses allowed to connect.
--username RS_USERNAME (none → no auth) Username for SOCKS5 username/password auth. Set together with --password.
--password RS_PASSWORD (none → no auth) Password for SOCKS5 username/password auth. Set together with --username.

Logging uses tracing; set RUST_LOG to change the level (e.g. RUST_LOG=rsocks=debug).

Authentication

By default the proxy requires no authentication — gate it with --accept-cidr (network-level) and/or username/password (RFC 1929). Setting both --username and --password turns on username/password auth; a client must then offer the user/pass method and present matching credentials, or the connection is refused. Setting only one of the two is a misconfiguration and the proxy refuses to start.

$ rsocks --username bob --password s3cret
# or, keeping secrets out of argv / shell history:
$ RS_USERNAME=bob RS_PASSWORD=s3cret rsocks

The two gates compose: a CIDR allow-list for the networks you control, plus credentials for clients whose source IP you can't pin (a roaming client behind unpredictable NAT). Credentials cross the wire in the clear, exactly as the SOCKS5 protocol specifies — run over a trusted network or an encrypted tunnel, not the open internet.

As a browser proxy

Run rsocks on a host that can reach where you want to go, then set your browser's SOCKS host to host:1080 (SOCKS v5). All browser TCP traffic is relayed through it — the generic, any-destination case SOCKS5 is built for.

As an ssh hop

Tunnel ssh through a machine that can't (or shouldn't) run sshd, using a SOCKS-aware connector such as ncat:

Host myhost
  ProxyCommand ncat --proxy proxy-host:1080 --proxy-type socks5 %h %p
  ServerAliveInterval 15

Keep ServerAliveInterval comfortably under read-timeout so an idle session is kept alive rather than reaped.

Install

Linux:

$ curl -LO https://github.com/twitchax/rusty_socks/releases/latest/download/rsocks_x86_64-unknown-linux-gnu.zip
$ unzip rsocks_x86_64-unknown-linux-gnu.zip -d /usr/local/bin
$ chmod a+x /usr/local/bin/rsocks

macOS (Apple Silicon):

$ curl -LO https://github.com/twitchax/rusty_socks/releases/latest/download/rsocks_aarch64-apple-darwin.zip
$ unzip rsocks_aarch64-apple-darwin.zip -d /usr/local/bin
$ chmod a+x /usr/local/bin/rsocks

Windows:

$ iwr https://github.com/twitchax/rusty_socks/releases/latest/download/rsocks_x86_64-pc-windows-gnu.zip -OutFile rsocks.zip
$ Expand-Archive rsocks.zip -DestinationPath C:\Users\%USERNAME%\AppData\Local\Programs\rsocks

Cargo:

$ cargo install rsocks

Docker

Published as twitchax/rusty_socks. Configure via flags or RS_* env vars:

$ docker run -d --net host \
    -e RS_PORT=1080 \
    -e RS_ACCEPT_CIDR=10.0.0.0/8 \
    twitchax/rusty_socks

Testing

$ cargo nextest run

License

This project is licensed under the MIT License - see the LICENSE file for details.