@hahahhh/sshx 0.0.6 → 0.0.7-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +50 -0
  2. package/package.json +4 -1
package/README.md CHANGED
@@ -1,15 +1,35 @@
1
1
  # sshx
2
2
 
3
+ **English** · [简体中文](README_zh.md) · [Website](https://xiaot623.github.io/sshx/)
4
+
3
5
  > Transparent SSH enhancement — add remote-to-local commands, auto port forwarding, and local domains to your SSH workflow. Zero side effects when you don't need them.
4
6
 
5
7
  **sshx** is a drop-in wrapper around OpenSSH. Wrap it as `alias ssh=sshx` and your existing SSH workflow works exactly as before — every flag, config, and connection passes through verbatim. But when you connect to a host (or Docker container) with sshx-aware features enabled, you unlock a connection-scoped shared remote server that gives you:
6
8
 
9
+ ![sshx animated terminal demo](docs/assets/sshx-demo.svg)
10
+
7
11
  - 🔄 **Reverse command bridge** — run `sshx local <cmd>` *on the remote* to execute commands on your local machine, with stdout, stderr, exit code, and stdin all propagated.
8
12
  - 📁 **Bidirectional workspace mount** — direct CLI sessions can use remote tools on local files, and local tools on remote files.
9
13
  - 🔌 **Automatic port forwarding** — remote local listeners (loopback `127.0.0.1` and wildcard `0.0.0.0`; e.g., a dev server on `0.0.0.0:8080` or `localhost:8080`) are automatically detected and forwarded to your local machine.
10
14
  - 🌐 **Local domain binding** — access forwarded ports as `<host>.<your-user>.sshx:<port>` in your local browser, no manual `-L` flags needed.
15
+ - 🛡️ **Remote egress proxy** — opt in to route proxy-aware remote tools through the local client's proxy or TUN-backed network stack.
11
16
  - 🐳 **Docker container support** — target running containers by name or ID: `sshx my-container`. Command bridge support works inside containers via `docker exec`.
12
17
 
18
+ ## Table of Contents
19
+
20
+ - [Why sshx?](#why-sshx)
21
+ - [Architecture](#architecture)
22
+ - [Features](#features)
23
+ - [Installation](#installation)
24
+ - [Quick Start](#quick-start)
25
+ - [Configuration Reference](#configuration-reference)
26
+ - [How It Works](#how-it-works)
27
+ - [Safety & Bypass](#safety--bypass)
28
+ - [Platform Support](#platform-support)
29
+ - [Project Structure](#project-structure)
30
+ - [Roadmap](#roadmap)
31
+ - [License](#license)
32
+
13
33
  ## Why sshx?
14
34
 
15
35
  | Without sshx | With sshx |
@@ -144,6 +164,30 @@ ls /dev/macfuse*
144
164
 
145
165
  Absolute source paths are preserved as a hierarchy below sshx's private session directory, but absolute command arguments are not rewritten. RemoteFS does not expose special files/xattrs/ACLs or support Docker targets, FUSE-T, or FSKit. It is optimized for source trees and small files rather than large-file throughput.
146
166
 
167
+ ### 🛡️ Remote Egress Proxy (opt-in)
168
+
169
+ Set `features.proxy: true` or run with `SSHX_USE_PROXY=1` to give the remote session authenticated HTTP and SOCKS5 proxy endpoints that travel back over OpenSSH:
170
+
171
+ ```sh
172
+ SSHX_USE_PROXY=1 sshx remote
173
+
174
+ # Optionally force a local upstream. Supported schemes (URL credentials work):
175
+ # http, https, socks5, socks5h
176
+ SSHX_USE_PROXY=1 SSHX_PROXY_URL=socks5h://127.0.0.1:7890 sshx remote
177
+ ```
178
+
179
+ sshx overrides uppercase and lowercase `HTTP_PROXY`, `HTTPS_PROXY`, and `ALL_PROXY` inside the remote session. Existing `NO_PROXY` values are preserved and extended with remote loopback addresses.
180
+
181
+ Local egress selection is:
182
+
183
+ 1. `SSHX_PROXY_URL`, when set.
184
+ 2. For ordinary HTTP requests, `HTTP_PROXY` then `ALL_PROXY`; for HTTPS CONNECT and general SOCKS TCP connections, `ALL_PROXY`, `HTTPS_PROXY`, then `HTTP_PROXY`. Lowercase forms are also read, and local `NO_PROXY`/`no_proxy` rules bypass the selected upstream.
185
+ 3. A normal local TCP connection. A local TUN proxy naturally captures this connection.
186
+
187
+ The remote listener is bound only to `127.0.0.1`, uses a dynamically allocated port, and requires per-session credentials. DNS names sent through `ALL_PROXY=socks5h://...` are resolved locally or by the configured local upstream. Upstream failures fail the affected request and never silently fall back to a direct connection.
188
+
189
+ This feature covers TCP applications that honor proxy environment variables, including tools such as curl, Git, and many package managers. It does not provide a remote TUN device, UDP/ICMP forwarding, PAC/system-GUI proxy discovery, or Docker target support.
190
+
147
191
  ### 🔌 Automatic Port Detection & Forwarding
148
192
 
149
193
  When a process on the remote starts listening on `127.0.0.1` or `0.0.0.0` (e.g., `npm run dev` on port 3000), sshx detects it and:
@@ -321,6 +365,10 @@ features:
321
365
  # Requires FUSE on each machine receiving a mount.
322
366
  remoteFs: false
323
367
 
368
+ # Route proxy-aware remote TCP applications through the local client.
369
+ # Default: false. SSHX_USE_PROXY=0|1 overrides this value.
370
+ proxy: false
371
+
324
372
  commands:
325
373
  # Commands blocked from bridge execution.
326
374
  deny: []
@@ -361,6 +409,7 @@ When `sshx` is invoked for a **non-matching host** (no sshx config, or host not
361
409
  - `sshx local ...` on a **client** (not inside a remote session) — errors immediately with a clear message. `local` is globally reserved.
362
410
  - `remoteFs` never silently falls back to an unmounted command. A failed FUSE mount fails the invocation.
363
411
  - Remote exports are anchored with Go's `os.Root`; path traversal and symlink escapes are rejected.
412
+ - The remote egress proxy binds only to loopback and uses random per-session credentials.
364
413
  - Docker containers that aren't running or can't be reached are pure passthrough — sshx falls back to raw `ssh` with no side effects.
365
414
  - Unmatched hosts are pure passthrough — no files created, no processes started.
366
415
 
@@ -395,6 +444,7 @@ sshx/
395
444
  │ ├── remotefs/ # FS protocol, secure backend, and FUSE adapter
396
445
  │ ├── ports/ # Port sniffing (/proc/net/tcp*)
397
446
  │ ├── forward/ # TCP forwarding
447
+ │ ├── proxy/ # Authenticated local HTTP/SOCKS egress proxy
398
448
  │ ├── domain/ # DNS resolver
399
449
  │ └── locald/ # Local daemon (socket, DNS, forwarding)
400
450
  ├── scripts/ # Integration tests
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hahahhh/sshx",
3
- "version": "0.0.6",
3
+ "version": "0.0.7-rc.0",
4
4
  "type": "module",
5
5
  "description": "Transparent SSH enhancement wrapper for OpenSSH",
6
6
  "repository": {
@@ -22,6 +22,9 @@
22
22
  "scripts": {
23
23
  "build": "node scripts/build-native.js",
24
24
  "build:go": "go build -trimpath -ldflags \"-X github.com/xiaot623/sshx/internal/version.Version=${npm_package_version}\" -o sshx ./cmd/sshx",
25
+ "site": "npm --prefix docs install --no-audit --no-fund && npm --prefix docs run site",
26
+ "site:dev": "npm --prefix docs install --no-audit --no-fund && npm --prefix docs run dev",
27
+ "site:preview": "npm --prefix docs run preview",
25
28
  "check": "go vet ./...",
26
29
  "test": "go test ./... && node --test test/*.test.js",
27
30
  "postinstall": "node ./bin/sshx.js --npm-refresh-integrations",