# sshproxy **Repository Path**: adream307/sshproxy ## Basic Information - **Project Name**: sshproxy - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-05 - **Last Updated**: 2026-06-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # sshproxy A local proxy written in C++17 that works like `ssh -D`: it listens on **one** local port, auto-detects **SOCKS4 / SOCKS4a / SOCKS5** and **HTTP / HTTPS** proxy protocols on that same port, and tunnels every connection through an SSH server using [libssh2](https://libssh2.org/). It reads `~/.ssh/config`, authenticates with key files from `~/.ssh/`, and supports **jump hosts** (`ProxyJump` / `ProxyCommand ... -W`). ``` curl --socks5-hostname 127.0.0.1:2000 http://example.com # SOCKS5 curl -x http://127.0.0.1:2000 http://example.com # HTTP proxy curl -x http://127.0.0.1:2000 https://example.com # HTTPS via CONNECT ``` ## Features - **One port, many protocols** — SOCKS4/4a/5 and HTTP(S) are distinguished by the first byte of each connection. - **`ssh -D` semantics** — dynamic forwarding via SSH `direct-tcpip` channels. - **`~/.ssh/config`** — `HostName`, `User`, `Port`, `IdentityFile`, `ProxyJump`; also derives a jump host from `ProxyCommand ssh JUMP -W %h:%p`. - **Public-key auth** — key files under `~/.ssh/` (with `ssh-agent` fallback). - **Jump hosts** — native SSH-over-SSH chaining (e.g. `ssh1 → cann`). - **Single-threaded `poll()` event loop** sharing one SSH session and multiplexing all channels, with backpressure and half-close handling. ## Build Requires CMake ≥ 3.16, a C++17 compiler, and OpenSSL. The build fetches and compiles **libssh2 1.11** automatically (the distro's 1.10 only signs RSA with SHA-1, which modern OpenSSH rejects). ```bash cmake -S . -B build cmake --build build -j # binary: build/sshproxy ``` To link a system libssh2 (must be ≥ 1.11) instead of fetching: ```bash cmake -S . -B build -DSSHPROXY_USE_SYSTEM_LIBSSH2=ON ``` ## Usage ``` sshproxy [options] Host from ~/.ssh/config (e.g. ssh1, or cann for a jump chain) -D, -p Local listen port (default 2000) -b Local bind address (default 127.0.0.1) -F ssh config file (default ~/.ssh/config) -v Verbose (debug) logging -h Help ``` Example — forward through `ssh1`: ```bash sshproxy -D 2000 ssh1 ``` Example — forward through the `cann` jump host (which reaches its target via `ssh1`): ```bash sshproxy -D 2001 cann ``` > Note: if your shell sets `no_proxy=127.0.0.1,...`, `curl` will **bypass** the > proxy for those hosts. Clear it (or use `--noproxy ''`) when testing against > localhost targets. ## Test `scripts/selftest.sh` starts local HTTP/HTTPS origin servers, launches the proxy against the given aliases, and checks SOCKS/HTTP/HTTPS proxying, a 5 MB transfer integrity hash, and concurrency: ```bash cmake --build build -j scripts/selftest.sh ssh1 cann ``` ## Design See [docs/DESIGN.md](docs/DESIGN.md) for architecture and mermaid diagrams (event loop, protocol detection, and the SSH-over-SSH jump-host mechanism). ## Layout ``` CMakeLists.txt # build (FetchContent libssh2 1.11) src/ main.cpp # CLI + lifecycle ssh_config.{h,cpp} # ~/.ssh/config parser ssh_connection.{h,cpp}# SSH transport + ProxyJump chaining proxy_session.{h,cpp} # protocol detection + relay state machine server.{h,cpp} # poll() event loop + channel orchestration log.{h,cpp} # logging docs/DESIGN.md # design document (mermaid) scripts/selftest.sh # end-to-end test ```