@serve.zone/remoteingress 3.1.0 → 3.1.1

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.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/remoteingress',
6
- version: '3.1.0',
6
+ version: '3.1.1',
7
7
  description: 'Edge ingress tunnel for DcRouter - accepts incoming TCP connections at network edge and tunnels them to DcRouter SmartProxy preserving client IP via PROXY protocol v1.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSwyQkFBMkI7SUFDakMsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHlLQUF5SztDQUN2TCxDQUFBIn0=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serve.zone/remoteingress",
3
- "version": "3.1.0",
3
+ "version": "3.1.1",
4
4
  "private": false,
5
5
  "description": "Edge ingress tunnel for DcRouter - accepts incoming TCP connections at network edge and tunnels them to DcRouter SmartProxy preserving client IP via PROXY protocol v1.",
6
6
  "main": "dist_ts/index.js",
package/readme.md CHANGED
@@ -2,13 +2,17 @@
2
2
 
3
3
  Edge ingress tunnel for DcRouter — accepts incoming TCP connections at the network edge and tunnels them to a DcRouter SmartProxy instance, preserving the original client IP via PROXY protocol v1.
4
4
 
5
+ ## Issue Reporting and Security
6
+
7
+ For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
8
+
5
9
  ## Install
6
10
 
7
11
  ```sh
8
12
  pnpm install @serve.zone/remoteingress
9
13
  ```
10
14
 
11
- ## Architecture
15
+ ## 🏗️ Architecture
12
16
 
13
17
  `@serve.zone/remoteingress` uses a **Hub/Edge** topology with a high-performance Rust core and a TypeScript API surface:
14
18
 
@@ -17,8 +21,8 @@ pnpm install @serve.zone/remoteingress
17
21
  │ Network Edge │ ◄══════════════════════════► │ Private Cluster │
18
22
  │ │ (multiplexed frames + │ │
19
23
  │ RemoteIngressEdge │ shared-secret auth) │ RemoteIngressHub │
20
- Listens on :80,:443│ │ Forwards to │
21
- Accepts client TCP │ │ SmartProxy on │
24
+ Accepts client TCP │ │ Forwards to │
25
+ connections │ │ SmartProxy on │
22
26
  │ │ │ local ports │
23
27
  └─────────────────────┘ └─────────────────────┘
24
28
  ▲ │
@@ -28,26 +32,27 @@ pnpm install @serve.zone/remoteingress
28
32
 
29
33
  | Component | Role |
30
34
  |-----------|------|
31
- | **RemoteIngressEdge** | Deployed at the network edge (e.g. a VPS or cloud instance). Listens on public ports, accepts raw TCP connections, and multiplexes them over a single TLS tunnel to the hub. |
35
+ | **RemoteIngressEdge** | Deployed at the network edge (e.g. a VPS or cloud instance). Accepts raw TCP connections and multiplexes them over a single TLS tunnel to the hub. |
32
36
  | **RemoteIngressHub** | Deployed alongside DcRouter/SmartProxy in a private cluster. Accepts edge connections, demuxes streams, and forwards each to SmartProxy with a PROXY protocol v1 header so the real client IP is preserved. |
33
37
  | **Rust Binary** (`remoteingress-bin`) | The performance-critical networking core. Managed via `@push.rocks/smartrust` RustBridge IPC — you never interact with it directly. Cross-compiled for `linux/amd64` and `linux/arm64`. |
34
38
 
35
- ### Key Features
39
+ ### Key Features
36
40
 
37
- - **TLS-encrypted tunnel** between edge and hub (auto-generated self-signed cert or bring your own)
38
- - **Multiplexed streams** — thousands of client connections flow over a single tunnel
39
- - **PROXY protocol v1** — SmartProxy sees the real client IP, not the tunnel IP
40
- - **Shared-secret authentication** — edges must present valid credentials to connect
41
- - **STUN-based public IP discovery** — the edge automatically discovers its public IP via Cloudflare STUN
42
- - **Auto-reconnect** with exponential backoff if the tunnel drops
43
- - **Event-driven** both Hub and Edge extend `EventEmitter` for real-time monitoring
44
- - **Rust core** — all frame encoding, TLS, and TCP proxying happen in native code for maximum throughput
41
+ - 🔒 **TLS-encrypted tunnel** between edge and hub (auto-generated self-signed cert or bring your own)
42
+ - 🔀 **Multiplexed streams** — thousands of client connections flow over a single tunnel
43
+ - 🌐 **PROXY protocol v1** — SmartProxy sees the real client IP, not the tunnel IP
44
+ - 🔑 **Shared-secret authentication** — edges must present valid credentials to connect
45
+ - 🎫 **Connection tokens** — encode all connection details into a single opaque string
46
+ - 📡 **STUN-based public IP discovery** the edge automatically discovers its public IP via Cloudflare STUN
47
+ - 🔄 **Auto-reconnect** with exponential backoff if the tunnel drops
48
+ - 📣 **Event-driven**both Hub and Edge extend `EventEmitter` for real-time monitoring
49
+ - ⚡ **Rust core** — all frame encoding, TLS, and TCP proxying happen in native code for maximum throughput
45
50
 
46
- ## Usage
51
+ ## 🚀 Usage
47
52
 
48
53
  Both classes are imported from the package and communicate with the Rust binary under the hood. All you need to do is configure and start them.
49
54
 
50
- ### Setting up the Hub (private cluster side)
55
+ ### Setting Up the Hub (Private Cluster Side)
51
56
 
52
57
  ```typescript
53
58
  import { RemoteIngressHub } from '@serve.zone/remoteingress';
@@ -95,32 +100,45 @@ console.log(status);
95
100
  await hub.stop();
96
101
  ```
97
102
 
98
- ### Setting up the Edge (network edge side)
103
+ ### Setting Up the Edge (Network Edge Side)
104
+
105
+ The edge can be configured in two ways: with an **opaque connection token** (recommended) or with explicit config fields.
106
+
107
+ #### Option A: Connection Token (Recommended)
108
+
109
+ A single token encodes all connection details — ideal for provisioning edges at scale:
99
110
 
100
111
  ```typescript
101
112
  import { RemoteIngressEdge } from '@serve.zone/remoteingress';
102
113
 
103
114
  const edge = new RemoteIngressEdge();
104
115
 
105
- // Listen for events
106
- edge.on('tunnelConnected', () => {
107
- console.log('Tunnel to hub established');
108
- });
109
- edge.on('tunnelDisconnected', () => {
110
- console.log('Tunnel to hub lost — will auto-reconnect');
111
- });
112
- edge.on('publicIpDiscovered', ({ ip }) => {
113
- console.log(`Public IP: ${ip}`);
116
+ edge.on('tunnelConnected', () => console.log('Tunnel established'));
117
+ edge.on('tunnelDisconnected', () => console.log('Tunnel lost — will auto-reconnect'));
118
+ edge.on('publicIpDiscovered', ({ ip }) => console.log(`Public IP: ${ip}`));
119
+
120
+ // Single token contains hubHost, hubPort, edgeId, and secret
121
+ await edge.start({
122
+ token: 'eyJoIjoiaHViLmV4YW1wbGUuY29tIiwicCI6ODQ0MywiZSI6ImVkZ2UtbnljLTAxIiwicyI6InN1cGVyc2VjcmV0dG9rZW4xIn0',
114
123
  });
124
+ ```
125
+
126
+ #### Option B: Explicit Config
127
+
128
+ ```typescript
129
+ import { RemoteIngressEdge } from '@serve.zone/remoteingress';
130
+
131
+ const edge = new RemoteIngressEdge();
132
+
133
+ edge.on('tunnelConnected', () => console.log('Tunnel established'));
134
+ edge.on('tunnelDisconnected', () => console.log('Tunnel lost — will auto-reconnect'));
135
+ edge.on('publicIpDiscovered', ({ ip }) => console.log(`Public IP: ${ip}`));
115
136
 
116
- // Start the edge — it connects to the hub and starts listening for clients
117
137
  await edge.start({
118
138
  hubHost: 'hub.example.com', // hostname or IP of the hub
119
139
  hubPort: 8443, // must match hub's tunnelPort (default: 8443)
120
140
  edgeId: 'edge-nyc-01', // unique edge identifier
121
141
  secret: 'supersecrettoken1', // must match the hub's allowed edge secret
122
- listenPorts: [80, 443], // public ports to accept TCP connections on
123
- stunIntervalSecs: 300, // STUN refresh interval in seconds (optional)
124
142
  });
125
143
 
126
144
  // Check status at any time
@@ -138,9 +156,39 @@ console.log(edgeStatus);
138
156
  await edge.stop();
139
157
  ```
140
158
 
141
- ### API Reference
159
+ ### 🎫 Connection Tokens
160
+
161
+ Connection tokens let you distribute a single opaque string instead of four separate config values. The hub operator generates the token; the edge operator just pastes it in.
162
+
163
+ ```typescript
164
+ import { encodeConnectionToken, decodeConnectionToken } from '@serve.zone/remoteingress';
165
+
166
+ // Hub side: generate a token for a new edge
167
+ const token = encodeConnectionToken({
168
+ hubHost: 'hub.example.com',
169
+ hubPort: 8443,
170
+ edgeId: 'edge-nyc-01',
171
+ secret: 'supersecrettoken1',
172
+ });
173
+ console.log(token);
174
+ // => 'eyJoIjoiaHViLmV4YW1wbGUuY29tIiwi...'
175
+
176
+ // Edge side: inspect a token (optional — start() does this automatically)
177
+ const data = decodeConnectionToken(token);
178
+ console.log(data);
179
+ // {
180
+ // hubHost: 'hub.example.com',
181
+ // hubPort: 8443,
182
+ // edgeId: 'edge-nyc-01',
183
+ // secret: 'supersecrettoken1'
184
+ // }
185
+ ```
186
+
187
+ Tokens are base64url-encoded (URL-safe, no padding) — safe to pass as environment variables, CLI arguments, or store in config files.
188
+
189
+ ## 📖 API Reference
142
190
 
143
- #### `RemoteIngressHub`
191
+ ### `RemoteIngressHub`
144
192
 
145
193
  | Method / Property | Description |
146
194
  |-------------------|-------------|
@@ -152,18 +200,48 @@ await edge.stop();
152
200
 
153
201
  **Events:** `edgeConnected`, `edgeDisconnected`, `streamOpened`, `streamClosed`
154
202
 
155
- #### `RemoteIngressEdge`
203
+ ### `RemoteIngressEdge`
156
204
 
157
205
  | Method / Property | Description |
158
206
  |-------------------|-------------|
159
- | `start(config)` | Spawns the Rust binary, connects to the hub, and starts listening on the specified ports. |
207
+ | `start(config)` | Spawns the Rust binary and connects to the hub. Accepts `{ token: string }` or `IEdgeConfig`. |
160
208
  | `stop()` | Gracefully shuts down the edge and kills the Rust process. |
161
209
  | `getStatus()` | Returns current edge status including connection state, public IP, and active streams. |
162
210
  | `running` | `boolean` — whether the Rust binary is alive. |
163
211
 
164
212
  **Events:** `tunnelConnected`, `tunnelDisconnected`, `publicIpDiscovered`
165
213
 
166
- ### Wire Protocol
214
+ ### Token Utilities
215
+
216
+ | Function | Description |
217
+ |----------|-------------|
218
+ | `encodeConnectionToken(data)` | Encodes `IConnectionTokenData` into a base64url token string. |
219
+ | `decodeConnectionToken(token)` | Decodes a token back into `IConnectionTokenData`. Throws on malformed or incomplete tokens. |
220
+
221
+ ### Interfaces
222
+
223
+ ```typescript
224
+ interface IHubConfig {
225
+ tunnelPort?: number; // default: 8443
226
+ targetHost?: string; // default: '127.0.0.1'
227
+ }
228
+
229
+ interface IEdgeConfig {
230
+ hubHost: string;
231
+ hubPort?: number; // default: 8443
232
+ edgeId: string;
233
+ secret: string;
234
+ }
235
+
236
+ interface IConnectionTokenData {
237
+ hubHost: string;
238
+ hubPort: number;
239
+ edgeId: string;
240
+ secret: string;
241
+ }
242
+ ```
243
+
244
+ ## 🔌 Wire Protocol
167
245
 
168
246
  The tunnel uses a custom binary frame protocol over TLS:
169
247
 
@@ -173,37 +251,64 @@ The tunnel uses a custom binary frame protocol over TLS:
173
251
 
174
252
  | Frame Type | Value | Direction | Purpose |
175
253
  |------------|-------|-----------|---------|
176
- | `OPEN` | `0x01` | Edge -> Hub | Open a new stream; payload is PROXY v1 header |
177
- | `DATA` | `0x02` | Edge -> Hub | Client data flowing upstream |
178
- | `CLOSE` | `0x03` | Edge -> Hub | Client closed the connection |
179
- | `DATA_BACK` | `0x04` | Hub -> Edge | Response data flowing downstream |
180
- | `CLOSE_BACK` | `0x05` | Hub -> Edge | Upstream (SmartProxy) closed the connection |
254
+ | `OPEN` | `0x01` | Edge Hub | Open a new stream; payload is PROXY v1 header |
255
+ | `DATA` | `0x02` | Edge Hub | Client data flowing upstream |
256
+ | `CLOSE` | `0x03` | Edge Hub | Client closed the connection |
257
+ | `DATA_BACK` | `0x04` | Hub Edge | Response data flowing downstream |
258
+ | `CLOSE_BACK` | `0x05` | Hub Edge | Upstream (SmartProxy) closed the connection |
181
259
 
182
260
  Max payload size per frame: **16 MB**.
183
261
 
184
- ### Example Scenarios
262
+ ## 💡 Example Scenarios
263
+
264
+ ### 1. Expose a Private Kubernetes Cluster to the Internet
185
265
 
186
- 1. **Expose a private Kubernetes cluster to the internet** — Deploy an Edge on a public VPS, configure your DNS to point to the VPS IP. The Edge tunnels all traffic to the Hub running inside the cluster, which hands it off to SmartProxy/DcRouter. Your cluster stays fully private — no public-facing ports needed.
266
+ Deploy an Edge on a public VPS, point your DNS to the VPS IP. The Edge tunnels all traffic to the Hub running inside the cluster, which hands it off to SmartProxy/DcRouter. Your cluster stays fully private — no public-facing ports needed.
187
267
 
188
- 2. **Multi-region edge ingress** — Run multiple Edges in different geographic regions (NYC, Frankfurt, Tokyo) all connecting to a single Hub. Use GeoDNS to route users to their nearest Edge. The Hub sees the real client IPs via PROXY protocol regardless of which edge they connected through.
268
+ ### 2. Multi-Region Edge Ingress
189
269
 
190
- 3. **Secure API exposure** Your backend runs on a private network with no direct internet access. An Edge on a minimal cloud instance acts as the only public entry point. TLS tunnel + shared-secret auth ensure only your authorized Edge can forward traffic.
270
+ Run multiple Edges in different geographic regions (NYC, Frankfurt, Tokyo) all connecting to a single Hub. Use GeoDNS to route users to their nearest Edge. The Hub sees the real client IPs via PROXY protocol regardless of which edge they connected through.
271
+
272
+ ### 3. Secure API Exposure
273
+
274
+ Your backend runs on a private network with no direct internet access. An Edge on a minimal cloud instance acts as the only public entry point. TLS tunnel + shared-secret auth ensure only your authorized Edge can forward traffic.
275
+
276
+ ### 4. Token-Based Edge Provisioning
277
+
278
+ Generate connection tokens on the hub side and distribute them to edge operators. Each edge only needs a single token string to connect — no manual configuration of host, port, ID, and secret.
279
+
280
+ ```typescript
281
+ // Hub operator generates token
282
+ const token = encodeConnectionToken({
283
+ hubHost: 'hub.prod.example.com',
284
+ hubPort: 8443,
285
+ edgeId: 'edge-tokyo-01',
286
+ secret: 'generated-secret-abc123',
287
+ });
288
+ // Send `token` to the edge operator via secure channel
289
+
290
+ // Edge operator starts with just the token
291
+ const edge = new RemoteIngressEdge();
292
+ await edge.start({ token });
293
+ ```
191
294
 
192
295
  ## License and Legal Information
193
296
 
194
- This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
297
+ This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file.
195
298
 
196
299
  **Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
197
300
 
198
301
  ### Trademarks
199
302
 
200
- This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
303
+ This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
304
+
305
+ Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
201
306
 
202
307
  ### Company Information
203
308
 
204
309
  Task Venture Capital GmbH
205
- Registered at District court Bremen HRB 35230 HB, Germany
310
+ Registered at District Court Bremen HRB 35230 HB, Germany
206
311
 
207
- For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
312
+ For any legal inquiries or further information, please contact us via email at hello@task.vc.
208
313
 
209
314
  By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/remoteingress',
6
- version: '3.1.0',
6
+ version: '3.1.1',
7
7
  description: 'Edge ingress tunnel for DcRouter - accepts incoming TCP connections at network edge and tunnels them to DcRouter SmartProxy preserving client IP via PROXY protocol v1.'
8
8
  }