# 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 local SOCKS5 proxy client (supporting TCP CONNECT and UDP ASSOCIATE). Key changes: - Local proxy is now SOCKS5 (replaces the previous HTTP proxy). - The tunnel supports multiplexed TCP and UDP relaying. - Existing frame protocol extended with UDP_* frames for SOCKS5 UDP ASSOCIATE. ## 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-server-macos ├── psk-proxy-client-macos ├── psk-proxy-server-linux ├── psk-proxy-client-linux ├── psk-proxy-server-windows.exe └── psk-proxy-client-windows.exe ``` ## Running the Server and Client The PSK (pre-shared key) file must contain a hex-encoded key string used by both sides. Example (256-bit key): ``` 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef ``` ### Server (Out-Node) - Listens for a single TLS-PSK tunnel connection from the client. - Performs outbound TCP connects and UDP sends on behalf of the client. macOS/Linux: ```bash ./dist/psk-proxy-server-macos \ --tunnel-port 8443 \ --host 0.0.0.0 \ --psk-file /path/to/psk.hex ``` Windows: ```cmd .\dist\psk-proxy-server-windows.exe ^ --tunnel-port 8443 ^ --host 0.0.0.0 ^ --psk-file C:\path\to\psk.hex ``` Required options: - `--tunnel-port `: TLS-PSK tunnel port - `--host `: Bind host (e.g., 0.0.0.0) - `--psk-file `: File containing hex PSK Optional: - `--connect-timeout `: Outbound TCP connect timeout (default 10000) ### Client (Local SOCKS5 Proxy) - Runs a local SOCKS5 proxy (TCP CONNECT and UDP ASSOCIATE). - Multiplexes many local connections over one TLS-PSK tunnel to the server. macOS/Linux: ```bash ./dist/psk-proxy-client-macos \ --server-host server.example.com \ --server-port 8443 \ --psk-file /path/to/psk.hex \ --identity client1 \ --socks-port 1080 \ --bind-host 127.0.0.1 ``` Windows: ```cmd .\dist\psk-proxy-client-windows.exe ^ --server-host server.example.com ^ --server-port 8443 ^ --psk-file C:\path\to\psk.hex ^ --identity client1 ^ --socks-port 1080 ^ --bind-host 127.0.0.1 ``` Required options: - `--server-host `: Remote out-node address - `--server-port `: Remote out-node port - `--psk-file `: File containing hex PSK - `--identity `: Identity string (logged on server) - `--socks-port `: Local SOCKS5 proxy port Optional: - `--bind-host `: Local bind host (default `127.0.0.1`) - `--connect-timeout `: Waiting time for OPEN/UDP_OPEN result (default 10000) - `--idle-timeout `: Idle timeout for TCP sockets (default 60000, 0=disabled) - `--udp-idle-timeout `: Idle timeout for UDP association (default 60000, 0=disabled) ## 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.