Skip to content

Commit 13d32db

Browse files
authored
feat: add base path support for reverse proxy deployments (#157)
Add -base-path configuration option to enable WStunnel server deployment behind reverse proxies (Envoy, Istio, nginx) with path-based routing. ## Summary * Add -base-path command-line flag to configure base path prefix * Implement automatic path normalization (leading/trailing slashes) * Update HTTP route registration to use base path prefixes * Add URL rewriting middleware to strip base path from requests * Preserve existing functionality when no base path is configured ## Features * **Base Path Configuration**: New -base-path flag for server deployment * **Path Normalization**: Automatic handling of leading/trailing slashes * **Route Prefixing**: All endpoints (/_tunnel, /_health_check, /_stats, /_token/) support base paths * **URL Rewriting**: Transparent base path removal before request processing * **Backward Compatibility**: No impact on existing deployments ## Implementation Details * Added BasePath field to WSTunnelServer struct * Created normalizeBasePath() helper for path validation * Implemented shouldStripBasePath() for proper URL matching * Added buildPath() utility for route construction * Enhanced HTTP handler wrapper for automatic path stripping ## Testing * Comprehensive unit tests for path normalization and URL rewriting * Integration tests with real HTTP servers and various base path configurations * Edge case testing for empty paths, root paths, and special characters * All existing tests continue to pass ## Documentation * Updated README.md with base path configuration examples * Enhanced CLAUDE.md with operational guidance * Created comprehensive proxy configuration examples (Envoy, Istio, nginx, HAProxy) * Added Kubernetes deployment examples and troubleshooting guide ## Use Cases This enables WStunnel deployment in modern containerized environments: * Kubernetes ingress controllers with path-based routing * Istio service mesh with VirtualService path matching * Envoy proxy configurations with prefix routing * nginx reverse proxy setups with location blocks * API gateway deployments with versioned paths ## Example Usage ```bash # Deploy behind reverse proxy at /wstunnel path ./wstunnel srv -port 8080 -base-path /wstunnel # Access endpoints with base path curl http://proxy.example.com/wstunnel/_health_check curl http://proxy.example.com/wstunnel/_stats ``` Fixes #129
1 parent 19d805d commit 13d32db

File tree

5 files changed

+1356
-9
lines changed

5 files changed

+1356
-9
lines changed

CLAUDE.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,11 @@ WStunnel is a WebSocket-based reverse HTTP/HTTPS tunneling solution that enables
7878
## Configuration Options
7979
- **Max Requests Per Tunnel**: Use `-max-requests-per-tunnel N` to limit queued requests per tunnel (default: 20)
8080
- **Max Clients Per Token**: Use `-max-clients-per-token N` to limit concurrent clients per token (default: 0/unlimited)
81+
- **Base Path**: Use `-base-path /path` to run behind reverse proxies with path-based routing (e.g., `-base-path /wstunnel`)
8182
- When a tunnel reaches the max request limit, new requests return "too many requests in-flight, tunnel broken?"
8283
- When a token reaches the max client limit, new connections return HTTP 429 "Maximum number of clients reached"
8384
- Client counts are automatically decremented when clients disconnect
85+
- Base path configuration automatically prefixes all endpoints (/_tunnel, /_health_check, /_stats, /_token/) with the specified path
8486

8587
## CodeRabbit Review Settings
8688
The project uses CodeRabbit for automated code reviews (see `.coderabbit.yaml`). When writing code, ensure compliance with:

README.md

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,17 @@ WSTUNSRV RUNNING
103103
$
104104
```
105105

106+
When using a base path, the health check URL includes the base path:
107+
108+
```bash
109+
$ ./wstunnel srv -port 8080 -base-path /wstunnel &
110+
2014/01/19 09:51:31 Listening on port 8080
111+
2014/01/19 09:51:31 Base path configured basePath=/wstunnel
112+
$ curl http://localhost:8080/wstunnel/_health_check
113+
WSTUNSRV RUNNING
114+
$
115+
```
116+
106117
#### Server Configuration Options
107118

108119
The WStunnel server supports several configuration options to control resource usage and security:
@@ -136,10 +147,26 @@ $ ./wstunnel srv -port 8080 -max-clients-per-token 1 &
136147

137148
This is useful when you want to ensure only a single client instance per token is allowed, preventing unauthorized token sharing or connection conflicts.
138149

150+
**Base Path Configuration:**
151+
When running behind a reverse proxy (like Envoy, Istio Ingress Gateway, or nginx) with path-based routing, use the `-base-path` option to specify the base path for all endpoints:
152+
153+
```bash
154+
$ ./wstunnel srv -port 8080 -base-path /wstunnel &
155+
2024/01/19 09:51:31 Listening on port 8080
156+
2024/01/19 09:51:31 Base path configured basePath=/wstunnel
157+
```
158+
159+
With a base path configured, all WStunnel endpoints become available under the specified path:
160+
- Health check: `http://proxy.example.com/wstunnel/_health_check`
161+
- Stats: `http://proxy.example.com/wstunnel/_stats`
162+
- Tunnel endpoint: `ws://proxy.example.com/wstunnel/_tunnel`
163+
- Token-based requests: `http://proxy.example.com/wstunnel/_token/your-token/path`
164+
139165
**Combined Configuration Example:**
140166

141167
```bash
142168
$ ./wstunnel srv -port 8080 \
169+
-base-path /api/v1/tunnel \
143170
-passwords 'prod-token:secure-password,dev-token:dev-pass' \
144171
-max-requests-per-tunnel 30 \
145172
-max-clients-per-token 2 &
@@ -161,10 +188,19 @@ $ ./wstunnel cli -tunnel ws://wstun.example.com:8080 -server http://localhost -t
161188
2014/01/19 09:54:51 Opening ws://wstun.example.com/_tunnel
162189
```
163190

191+
If the server is running with a base path (e.g., `-base-path /wstunnel`), include it in the tunnel URL:
192+
193+
```bash
194+
$ ./wstunnel cli -tunnel ws://wstun.example.com:8080/wstunnel -server http://localhost -token 'my_b!g_$secret!!'
195+
2014/01/19 09:54:51 Opening ws://wstun.example.com/wstunnel/_tunnel
196+
```
197+
164198
To use a token with a password for additional security:
165199

166200
```bash
167201
$ ./wstunnel cli -tunnel ws://wstun.example.com:8080 -server http://localhost -token 'my_b!g_$secret!!:mypassword'
202+
# Or with base path:
203+
$ ./wstunnel cli -tunnel ws://wstun.example.com:8080/wstunnel -server http://localhost -token 'my_b!g_$secret!!:mypassword'
168204
```
169205

170206
> **Security Warning**: Passing passwords via command-line arguments is not recommended as they can be exposed through:
@@ -186,13 +222,21 @@ $ ./wstunnel cli -tunnel ws://wstun.example.com:8080 -server http://localhost -t
186222
On `client.example.com` use curl to make a request to the web server running on `www.example.com`:
187223

188224
```bash
189-
190225
$ curl 'https://wstun.example.com:8080/_token/my_b!g_$secret!!/some/web/page'
191226
<html> .......
192227
$ curl '-HX-Token:my_b!g_$secret!!' https://wstun.example.com:8080/some/web/page
193228
<html> .......
194229
```
195230

231+
If the server is running with a base path, include it in the request URLs:
232+
233+
```bash
234+
$ curl 'https://wstun.example.com:8080/wstunnel/_token/my_b!g_$secret!!/some/web/page'
235+
<html> .......
236+
$ curl '-HX-Token:my_b!g_$secret!!' https://wstun.example.com:8080/wstunnel/some/web/page
237+
<html> .......
238+
```
239+
196240
### Running on Android
197241

198242
WStunnel can be run on Android devices using terminal emulators like Termux. See the [Android documentation](docs/ANDROID.md) for detailed setup instructions.
@@ -270,7 +314,7 @@ server {
270314

271315
### Monitoring and Status Endpoint
272316

273-
WStunnel server provides a `/_stats` endpoint that displays information about connected tunnels. When accessed from localhost, it provides detailed information including:
317+
WStunnel server provides a `/_stats` endpoint that displays information about connected tunnels (or `/your-base-path/_stats` when using a base path). When accessed from localhost, it provides detailed information including:
274318

275319
- Number of active tunnels
276320
- Server configuration limits

0 commit comments

Comments
 (0)