diff --git a/changelog.md b/changelog.md index 9f7aeaf..ea49568 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # Changelog +## 2026-03-26 - 4.15.1 - fix(readme) +clarify unified runtime configuration and firewall update behavior + +- Updates the architecture and feature descriptions to reflect that ports, firewall rules, and rate limits are pushed together in a single config update +- Clarifies that firewall configuration is delivered via FRAME_CONFIG on handshake and subsequent updates, with atomic full-rule replacement at the edge +- Simplifies and reorganizes README wording around edge and hub responsibilities without changing implementation behavior + ## 2026-03-26 - 4.15.0 - feat(edge,hub) add hub-controlled nftables firewall configuration for remote ingress edges diff --git a/readme.md b/readme.md index 848b840..2634206 100644 --- a/readme.md +++ b/readme.md @@ -20,25 +20,22 @@ pnpm install @serve.zone/remoteingress TLS or QUIC Tunnel ┌─────────────────────┐ ◄══════════════════════════► ┌─────────────────────┐ │ Network Edge │ TCP+TLS: frame mux │ Private Cluster │ -│ │ QUIC: native streams │ │ -│ RemoteIngressEdge │ UDP: QUIC datagrams │ RemoteIngressHub │ -│ │ │ │ -│ Accepts TCP & UDP │ │ Forwards to │ -│ on hub-assigned │ │ SmartProxy on │ -│ ports │ │ local ports │ -│ │ │ │ -│ 🔥 nftables rules │ ◄── firewall config pushed ── │ Configures edge │ -│ applied locally │ via FRAME_CONFIG │ firewalls remotely │ -└─────────────────────┘ └─────────────────────┘ - ▲ │ - │ TCP + UDP from end users ▼ - Internet DcRouter / SmartProxy +│ │ QUIC: native streams │ │ +│ RemoteIngressEdge │ UDP: QUIC datagrams │ RemoteIngressHub │ +│ │ │ │ +│ • TCP/UDP listeners│ ◄─── FRAME_CONFIG pushes ─── │ • Port assignments │ +│ • nftables firewall│ ports + firewall rules │ • Firewall config │ +│ • Rate limiting │ at any time │ • Rate limit rules │ +└─────────────────────┘ └─────────────────────┘ + ▲ │ + │ TCP + UDP from end users ▼ + Internet DcRouter / SmartProxy ``` | Component | Role | |-----------|------| -| **RemoteIngressEdge** | Deployed at the network edge (VPS, cloud instance). Runs as root. Listens on TCP and UDP ports assigned by the hub, accepts connections/datagrams, and tunnels them to the hub. Applies nftables firewall rules pushed by the hub for IP blocking and rate limiting. Ports and firewall config are hot-reloadable at runtime. | -| **RemoteIngressHub** | Deployed alongside DcRouter/SmartProxy in a private cluster. Accepts edge connections, demuxes streams/datagrams, and forwards each to SmartProxy with PROXY protocol headers so the real client IP is preserved. Pushes firewall configuration to edges. | +| **RemoteIngressEdge** | Deployed at the network edge (VPS, cloud instance). Runs as root. Listens on hub-assigned TCP/UDP ports, tunnels traffic to the hub, and applies hub-pushed nftables rules (IP blocking, rate limiting). All config is hot-reloadable at runtime. | +| **RemoteIngressHub** | Deployed alongside DcRouter/SmartProxy in a private cluster. Accepts edge connections, demuxes streams/datagrams, and forwards each to SmartProxy with PROXY protocol headers so the real client IP is preserved. Pushes all edge config (ports, firewall) via a single API. | | **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`. | ### ⚡ Key Features @@ -46,14 +43,14 @@ pnpm install @serve.zone/remoteingress - **Dual transport** — choose between TCP+TLS (frame-multiplexed) or QUIC (native stream multiplexing, zero head-of-line blocking) - **TCP + UDP tunneling** — tunnel any TCP connection or UDP datagram through the same edge/hub pair - **PROXY protocol v1 & v2** — SmartProxy sees the real client IP for both TCP (v1 text) and UDP (v2 binary) -- **Hub-controlled firewall** — push nftables rules (IP blocking, rate limiting, custom rules) from the hub to edges via `@push.rocks/smartnftables` +- **Hub-controlled firewall** — push nftables rules (IP blocking, rate limiting, custom firewall rules) to edges as part of the same config update that assigns ports — powered by `@push.rocks/smartnftables` - **Multiplexed streams** — thousands of concurrent TCP connections over a single tunnel - **QUIC datagrams** — UDP traffic forwarded via QUIC unreliable datagrams for lowest possible latency - **Shared-secret authentication** — edges must present valid credentials to connect - **Connection tokens** — encode all connection details into a single opaque base64url string - **STUN-based public IP discovery** — edges automatically discover their public IP via Cloudflare STUN - **Auto-reconnect** with exponential backoff if the tunnel drops -- **Dynamic port configuration** — the hub assigns TCP and UDP listen ports per edge, hot-reloadable at runtime +- **Dynamic runtime configuration** — the hub pushes ports, firewall rules, and rate limits to edges at any time via a single `updateAllowedEdges()` call - **Event-driven** — both Hub and Edge extend `EventEmitter` for real-time monitoring - **3-tier QoS** — control frames, normal data, and sustained (elephant flow) traffic each get their own priority queue - **Adaptive flow control** — per-stream windows scale with active stream count to prevent memory overuse @@ -205,18 +202,13 @@ const data = decodeConnectionToken(token); Tokens are base64url-encoded — safe for environment variables, CLI arguments, and config files. -## 🔥 Hub-Controlled Firewall +## 🔥 Firewall Config -Edges run as root and use `@push.rocks/smartnftables` to apply nftables rules pushed from the hub. This gives you centralized control over network-level security at every edge node. +The `firewallConfig` field in `updateAllowedEdges()` works exactly like `listenPorts` — it travels in the same `FRAME_CONFIG` frame, is delivered on initial handshake and on every subsequent update, and is applied atomically at the edge using `@push.rocks/smartnftables`. Each update fully replaces the previous ruleset. -### How It Works +Since edges run as root, the rules are applied directly to the Linux kernel via nftables. If the edge isn't root or nftables is unavailable, it logs a warning and continues — the tunnel works fine, just without kernel-level firewall rules. -1. The hub includes `firewallConfig` when calling `updateAllowedEdges()` -2. The config flows through the Rust binary as an opaque JSON blob via `FRAME_CONFIG` -3. The edge TypeScript layer receives it and applies the rules using `SmartNftables` -4. On each config update, all previous rules are replaced atomically (full replacement, not incremental) - -### Firewall Config Structure +### Config Structure ```typescript interface IFirewallConfig { @@ -272,10 +264,6 @@ await hub.updateAllowedEdges([ ]); ``` -### Graceful Degradation - -If the edge isn't running as root or nftables is unavailable, the SmartNftables initialization logs a warning and continues operating normally — the tunnel works fine, just without kernel-level firewall rules. - ## API Reference ### `RemoteIngressHub` diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 956ba8d..16b75e0 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@serve.zone/remoteingress', - version: '4.15.0', + version: '4.15.1', description: 'Edge ingress tunnel for DcRouter - tunnels TCP and UDP traffic from the network edge to SmartProxy over TLS or QUIC, preserving client IP via PROXY protocol.' }