# PSK-Proxy-Tunnel Build & Usage Guide This guide explains how to build single executable binaries and how to run the TLS-PSK tunnel with a three-tier architecture: a local SOCKS5 proxy client, a relay node, and an exit node. Key changes: - The architecture is now Client -> Relay -> Exit. - `proxy-server.js` is now a relay node (`psk-proxy-relay`). - A new `proxy-exit.js` script acts as the exit node (`psk-proxy-exit`). - The client connects to the relay, and the relay connects to the exit node. ## Prerequisites - Node.js: Version 18.0.0 or higher - npm: Usually comes with Node.js - Git: To clone the repository ## Quick Start ### 1) Install dependencies ```bash npm install ``` ### 2) Build for your current platform ```bash # macOS/Linux ./build.sh # Windows build.bat ``` Or via npm directly: ```bash npm run build:macos # macOS npm run build:linux # Linux npm run build:windows # Windows ``` ### 3) Build for all platforms ```bash npm run build ``` ## Build Scripts ### Using the build scripts Unix/Linux/macOS: ```bash chmod +x build.sh ./build.sh # current platform ./build.sh --platform macos ./build.sh --platform linux ./build.sh --platform windows ./build.sh --all # all platforms ./build.sh --clean # remove dist/ ./build.sh --help ``` Windows: ```cmd build.bat # Windows (default) build.bat --all # all platforms build.bat --clean build.bat --help ``` ### Using npm scripts directly ```bash npm run build:macos npm run build:linux npm run build:windows npm run build # all platforms npm run clean # remove dist/ ``` ## Build Output Executables are created in `dist/`: ``` dist/ ├── psk-proxy-client-macos ├── psk-proxy-relay-macos ├── psk-proxy-exit-macos ├── psk-proxy-client-linux ├── psk-proxy-relay-linux ├── psk-proxy-exit-linux ├── psk-proxy-client-windows.exe ├── psk-proxy-relay-windows.exe └── psk-proxy-exit-windows.exe ``` ## Running the Servers and Client The PSK (pre-shared key) file must contain a hex-encoded key string used by all components. ### 1. Exit Node - Listens for a single TLS-PSK tunnel connection from the relay. - Performs outbound TCP connects and UDP sends on behalf of the client. macOS/Linux: ```bash ./dist/psk-proxy-exit-macos \ --relay-port 9000 \ --host 0.0.0.0 \ --psk-file /path/to/psk.hex ``` Windows: ```cmd .\dist\psk-proxy-exit-windows.exe ^ --relay-port 9000 ^ --host 0.0.0.0 ^ --psk-file C:\path\to\psk.hex ``` Required options: - `--relay-port `: Port for the relay to connect to. - `--host `: Bind host (e.g., 0.0.0.0). - `--psk-file `: File containing hex PSK. ### 2. Relay Node - Listens for the client and connects to the exit node. - Relays traffic between the client and the exit node. macOS/Linux: ```bash ./dist/psk-proxy-relay-macos \ --tunnel-port 8443 \ --host 0.0.0.0 \ --psk-file /path/to/psk.hex \ --exit-host exit.node.com \ --exit-port 9000 \ --exit-identity relay1 ``` Windows: ```cmd .\dist\psk-proxy-relay-windows.exe ^ --tunnel-port 8443 ^ --host 0.0.0.0 ^ --psk-file C:\path\to\psk.hex ^ --exit-host exit.node.com ^ --exit-port 9000 ^ --exit-identity relay1 ``` Required options: - `--tunnel-port `: Port for the client to connect to. - `--host `: Bind host. - `--psk-file `: File containing hex PSK. - `--exit-host `: Exit node host. - `--exit-port `: Exit node port. - `--exit-identity `: Identity for the relay when connecting to the exit node. ### 3. Client (Local SOCKS5 Proxy) - Runs a local SOCKS5 proxy. - Connects to the relay node. macOS/Linux: ```bash ./dist/psk-proxy-client-macos \ --server-host relay.node.com \ --server-port 8443 \ --psk-file /path/to/psk.hex \ --identity client1 \ --socks-port 1080 ``` Windows: ```cmd .\dist\psk-proxy-client-windows.exe ^ --server-host relay.node.com ^ --server-port 8443 ^ --psk-file C:\path\to\psk.hex ^ --identity client1 ^ --socks-port 1080 ``` Required options: - `--server-host `: Relay node address. - `--server-port `: Relay node port. - `--psk-file `: File containing hex PSK. - `--identity `: Identity string (logged on relay). - `--socks-port `: Local SOCKS5 proxy port. Optional: - `--bind-host `: Local bind host (default `127.0.0.1`). - `--connect-timeout `: Timeout for connection setup (default 10000). - `--idle-timeout `: Idle timeout for TCP sockets (default 60000). - `--udp-idle-timeout `: Idle timeout for UDP association (default 60000). ## Protocol Summary All multiplexed over a single TLS-PSK socket: Header (9 bytes): - 1 byte type - 4 bytes connection id (unsigned) - 4 bytes payload length (unsigned) - payload bytes Types: - TCP: - DATA (2): stream data - CLOSE (3): close stream - OPEN (4): payload = [2B hostLen][host][2B port] - OPEN_RESULT (5): payload = [1B status] (1=success, 0=failure) - UDP (for SOCKS5 UDP ASSOCIATE): - UDP_OPEN (6): payload empty - UDP_OPEN_RESULT (7): payload = [1B status] (1=success, 0=failure) - UDP_SEND (8): payload = [2B hostLen][host][2B port][2B dataLen][data] - UDP_RECV (9): same layout as UDP_SEND - UDP_CLOSE (10): payload empty ## Testing Assuming the client runs a local SOCKS5 proxy at 127.0.0.1:1080: - HTTP over SOCKS5 (remote DNS resolution via socks5h): ```bash curl -x socks5h://127.0.0.1:1080 http://example.com/ ``` - HTTPS over SOCKS5: ```bash curl -x socks5h://127.0.0.1:1080 https://ifconfig.me ``` - SSH over SOCKS5 (using `nc` as ProxyCommand): ```bash ssh -o ProxyCommand="nc -x 127.0.0.1:1080 -X 5 %h %p" user@your.remote.host ``` - Applications with SOCKS5 (TCP and UDP): - Many apps support SOCKS5 TCP CONNECT (browsers, package managers, etc.). - For UDP ASSOCIATE (e.g., some torrent clients, DNS forwarders with SOCKS5-UDP support), configure them to use 127.0.0.1:1080 SOCKS5 and enable UDP if supported. Note: many CLI tools do not implement SOCKS5 UDP. Notes: - `socks5h` in curl ensures DNS names are resolved through the proxy. - UDP test coverage depends on the client application having SOCKS5 UDP support. ## Troubleshooting 1) "pkg command not found" ```bash npm install -g pkg # or npx pkg proxy-server.js ``` 2) Build fails with permission errors ```bash chmod +x build.sh sudo npm run build # if necessary ``` 3) Executable doesn't run on target platform - Ensure you built for the correct target - Verify executable permissions - Confirm compatible Node target in `pkg` config 4) Tunnel connects but traffic fails - Confirm both server and client use the exact same hex PSK - Check connectivity from server to target hosts/ports (firewall, outbound rules) - Use `--connect-timeout` to tune behavior 5) SOCKS5 UDP doesn't appear to work - Confirm your application actually supports SOCKS5 UDP ASSOCIATE - Check that the client printed "Local SOCKS5 proxy listening ..." - Inspect server logs for UDP_* activity ## Performance Considerations - Single tunnel multiplexes many flows (reduced connection overhead). - UDP sockets are ephemeral and idle-timed to conserve resources. - TCP and UDP buffers are kept minimal; tune OS limits as needed. ## Build Configuration Defined in `package.json` under `pkg`: ```json { "pkg": { "assets": [], "scripts": [], "targets": [ "node18-macos-x64", "node18-linux-x64", "node18-win-x64" ] } } ``` ## Contributing - Keep CLI flags in `proxy-client.js` and `proxy-server.js` in sync with this document. - Update build scripts (`build.sh`, `build.bat`) when adding platforms. - Test TCP (HTTP/HTTPS/SSH) and at least one UDP-capable client where possible.