2026-04-29 12:58:06 +00:00
2026-04-29 12:58:06 +00:00
2026-04-29 12:58:06 +00:00
2024-04-14 03:38:00 +02:00
2024-04-14 03:38:00 +02:00
2024-04-14 03:38:00 +02:00
2026-04-29 12:58:06 +00:00
2026-05-07 20:22:12 +00:00
2026-04-29 12:58:06 +00:00
2026-05-07 20:22:12 +00:00

@serve.zone/remoteingress

@serve.zone/remoteingress is a Rust-powered, TypeScript-controlled edge tunnel for moving TCP and UDP traffic from public edge nodes into a private dcrouter or SmartProxy host while preserving the original client IP through PROXY protocol.

Issue Reporting and Security

For reporting bugs, issues, or security vulnerabilities, please visit 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/ account to submit Pull Requests directly.

What It Does

Remote ingress solves the common edge problem: your workload or gateway lives behind NAT, a firewall, or a private network, but public traffic should enter through one or more hardened edge VPS nodes.

Internet clients
      |
      v
public edge node: RemoteIngressEdge
      |
      | TLS or QUIC tunnel
      v
private site: RemoteIngressHub -> dcrouter / SmartProxy

The edge binds public TCP and UDP ports assigned by the hub. Each accepted connection or datagram is tunneled to the hub, which forwards it to a local target host with PROXY headers so downstream routing can still see the real client address.

Highlights

  • Rust networking core managed from TypeScript through @push.rocks/smartrust
  • 🔁 Hub/edge model with dynamic updateAllowedEdges() reconciliation
  • 🌐 TCP forwarding over frame-multiplexed TLS or native QUIC streams
  • 📡 UDP forwarding over TCP frames or QUIC datagrams
  • 🧾 PROXY protocol preservation for client IP visibility at SmartProxy
  • 🛡️ Hub-pushed nftables firewall snapshots for blocklists, rate limits, and custom rules
  • 🔐 Shared-secret edge authentication and compact connection tokens
  • 🚦 Transport modes: tcpTls, quic, and quicWithFallback
  • 📊 EventEmitter status events for edge lifecycle, streams, port assignments, and crash recovery

Install

pnpm add @serve.zone/remoteingress

Hub Side

Run the hub next to the private service you want to expose. In dcrouter deployments the target is usually SmartProxy on 127.0.0.1.

import { RemoteIngressHub } from '@serve.zone/remoteingress';

const hub = new RemoteIngressHub();

hub.on('edgeConnected', ({ edgeId }) => console.log('edge connected', edgeId));
hub.on('edgeDisconnected', ({ edgeId }) => console.log('edge disconnected', edgeId));
hub.on('streamOpened', ({ edgeId, streamId }) => console.log('stream', edgeId, streamId));

await hub.start({
  tunnelPort: 8443,
  targetHost: '127.0.0.1',
});

await hub.updateAllowedEdges([
  {
    id: 'edge-fra-01',
    secret: 'replace-with-a-long-random-secret',
    listenPorts: [80, 443],
    listenPortsUdp: [443],
    stunIntervalSecs: 300,
    firewallConfig: {
      blockedIps: ['198.51.100.25'],
      rateLimits: [
        { id: 'https-per-ip', port: 443, protocol: 'tcp', rate: '200/second', burst: 100, perSourceIP: true },
      ],
    },
  },
]);

const status = await hub.getStatus();
console.log(status.connectedEdges);

await hub.stop();

Edge Side

The edge runs on the public node. It normally needs root privileges to bind privileged ports and apply nftables rules. If nftables cannot be initialized, the tunnel can still run, but kernel-level edge firewalling is skipped.

import { RemoteIngressEdge } from '@serve.zone/remoteingress';

const edge = new RemoteIngressEdge();

edge.on('tunnelConnected', () => console.log('tunnel connected'));
edge.on('portsAssigned', ({ listenPorts }) => console.log('TCP ports', listenPorts));
edge.on('firewallConfigUpdated', () => console.log('firewall snapshot applied'));

await edge.start({
  hubHost: 'ingress-hub.example.com',
  hubPort: 8443,
  edgeId: 'edge-fra-01',
  secret: 'replace-with-a-long-random-secret',
  transportMode: 'quicWithFallback',
});

console.log(await edge.getStatus());

await edge.stop();

Connection Tokens

Tokens are base64url-encoded compact JSON. They are useful when the hub operator provisions an edge and wants to hand over one opaque string.

import {
  RemoteIngressEdge,
  encodeConnectionToken,
  decodeConnectionToken,
} from '@serve.zone/remoteingress';

const token = encodeConnectionToken({
  hubHost: 'ingress-hub.example.com',
  hubPort: 8443,
  edgeId: 'edge-fra-01',
  secret: 'replace-with-a-long-random-secret',
});

console.log(decodeConnectionToken(token));

const edge = new RemoteIngressEdge();
await edge.start({ token });

CLI Mode

The package entry point exports runCli(), and the repo's cli.js wrapper can run hub or edge mode.

node cli.js hub --tunnel-port 8443 --target-host 127.0.0.1
node cli.js edge --token eyJoIjoiaW5ncmVzcy1odWIuZXhhbXBsZS5jb20i...

Environment-based startup is also supported:

Variable Purpose
REMOTEINGRESS_MODE hub or edge
REMOTEINGRESS_TOKEN Edge connection token
REMOTEINGRESS_HUB_HOST / REMOTEINGRESS_HUB_PORT Explicit edge connection target
REMOTEINGRESS_EDGE_ID / REMOTEINGRESS_SECRET Explicit edge credentials
REMOTEINGRESS_TARGET_HOST Hub-side forwarding target, default 127.0.0.1
REMOTEINGRESS_ALLOWED_EDGES_JSON Hub-side allowed edge list
REMOTEINGRESS_PERFORMANCE_JSON Optional performance configuration

Transport Modes

Mode Behavior
tcpTls Single TLS connection with frame-based stream multiplexing. Good for conservative networks.
quic QUIC streams for TCP and QUIC datagrams for UDP. Best latency and no TCP head-of-line blocking.
quicWithFallback Default edge mode. Tries QUIC and falls back to TCP/TLS when UDP is blocked.

Firewall Config

firewallConfig travels in the same hub-to-edge configuration update as port assignments. Each update is a full desired-state snapshot.

await hub.updateAllowedEdges([
  {
    id: 'edge-fra-01',
    secret: 'secret',
    listenPorts: [80, 443],
    firewallConfig: {
      blockedIps: ['203.0.113.0/24'],
      rateLimits: [
        { id: 'http', port: 80, protocol: 'tcp', rate: '100/second', perSourceIP: true },
      ],
      rules: [
        { id: 'allow-monitoring', direction: 'input', action: 'accept', sourceIP: '10.0.0.0/8', destPort: 9090, protocol: 'tcp' },
      ],
    },
  },
]);

API Surface

Export Purpose
RemoteIngressHub Starts/stops the private hub, authorizes edges, pushes runtime config, and reports connected edges.
RemoteIngressEdge Starts/stops the public edge, connects to the hub, binds assigned ports, and applies firewall rules.
encodeConnectionToken() Encodes hub host, port, edge ID, and secret into a token.
decodeConnectionToken() Decodes and validates a token.
IHubConfig, IEdgeConfig, TAllowedEdge Primary TypeScript shapes for integrating the module.

Development

pnpm run build
pnpm test

Useful source entry points:

  • ts/index.ts exports the public API and CLI runner.
  • ts/classes.remoteingresshub.ts wraps hub management commands and hub events.
  • ts/classes.remoteingressedge.ts wraps edge management commands, nftables application, and edge events.
  • ts/classes.token.ts implements compact connection tokens.
  • rust/ contains the performance-critical tunnel implementation compiled by tsrust.

This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the license file.

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.

Trademarks

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.

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.

Company Information

Task Venture Capital GmbH Registered at District Court Bremen HRB 35230 HB, Germany

For any legal inquiries or further information, please contact us via email at hello@task.vc.

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.

S
Description
remoteingress allows a cluster to be on some computer behind a NAT, and have a RemotePublicConnector runing on a small VPS running somewhere in the cloud.
Readme 2.8 MiB
Languages
Rust 73.8%
TypeScript 25.4%
Dockerfile 0.4%
Shell 0.3%
JavaScript 0.1%