Commit Graph
11 Commits
Author SHA1 Message Date
KKRainbow 8794e12a26 feat(vpn): hot add/remove WireGuard portal clients without restart (#2514)
* feat(vpn): hot add/remove WireGuard portal clients without restart

WireGuard portal clients were frozen at instance construction: the
engine slot maps, host key table, and PortalModule state were all
immutable after startup, so any client change required recreating the
whole instance and dropping every established session.

Wire dynamic client management through the existing config-patch
channel (ConfigRpc.patch_config -> apply_config_patch), following the
same pattern as connectors, port forwards, and proxy networks:

- proto: InstanceConfigPatch gains repeated VpnPortalClientPatch
  (Add/Remove/Clear by client name)
- engine: slot maps move under an RwLock with a free-index allocator;
  add_client/remove_client recycle indices, mark removed slots retired,
  and expire active sessions so Core tears down the attached peer via
  the regular channel-close path (credential revocation and disconnect
  events included); untouched clients keep their sessions intact. The
  retired flag is re-checked under the session lock so a datagram that
  races with removal cannot resurrect a session
- host: WireGuardPortalHost derives keys deterministically per name
  (HKDF), keeps a mutable client table for render_client_config, and
  forwards updates to the live engine; changed clients are re-added so
  they re-handshake into a fresh generation with the new virtual IP or
  groups
- PortalModule: client set, statuses, and session locks become shared
  mutable state; run_session resolves clients from the shared map at
  accept time; update_clients() validates against a caller-supplied
  runtime snapshot. An empty client set is legal in every lifecycle
  stage, so clearing all clients never produces a configuration that
  fails instance recreation
- config_patch: apply_vpn_portal_client_patches mutates the candidate
  TOML; the sub-patch runs last and is deep-validated and hot-applied
  before the candidate commits, so a rejected client set leaves neither
  the shared model nor the live portal changed, and validation sees the
  fully patched state including routes and node IPv4 from the same
  request. Rejects patches when no portal is configured or a removed
  client does not exist
- cli: vpn-portal add-client/remove-client/clear-clients subcommands

Tests: engine index recycling, module update validation/state/host
notification, TOML patch application, and a three-node integration test
that adds a second WireGuard client live, removes the first while the
second stays online, and asserts rejected patches leave the shared
model unchanged.

* feat(web): reconcile WireGuard portal client edits as hot patches

The web console reconciles desired network config against the running
instance and patches it in place when possible. VPN portal changes were
not part of that: any client edit made the base configs differ, so every
save recreated the instance and dropped all established sessions.

Exclude vpn_portal_config from the base comparison and diff its clients
by name instead. Client add/remove/change now produces
VpnPortalClientPatch entries (removals first, changed clients as
remove+add) applied through the existing PatchConfig channel. Listener
identity changes (address or private key) and enabling or disabling the
portal still fall back to a full instance recreate, since those change
the listener lifecycle.

* feat(web/gui): map portal client patches to frontend RPC backends

Extend the RemoteClient seam with add/remove/clear VPN portal client
operations so frontend hosts can drive the same PatchConfig channel as
the CLI. There is deliberately no dedicated editing UI: the config form
stays the single editing surface (aligned with port forwards), and
these methods exist for programmatic and future use.

- web console: JSON proxy-rpc to ConfigRpcService.patch_config with
  VpnPortalClientPatch entries (pbjson string enum actions)
- desktop GUI: patch_vpn_portal_clients tauri command forwarding the
  same patch through the typed ConfigRpc client
2026-08-22 01:18:42 +08:00
KKRainbow 62e4fd15e9 feat(vpn): multi-client WireGuard portal with attached peers (#2502)
* feat(peer): support protocol-agnostic attached peers

Add locally attached peers backed by independent, peer-level portable
managers and authenticated in-process ring connections. Carry trusted
connection provenance through packet admission so attached relay
privileges cannot be forged through packet headers.

Let every peer manager own ACL loading, sanitized policy updates, route
refresh, and runtime cleanup. In Secure Mode, grant attached identities
ephemeral credentials instead of sharing administrator and group secrets.

* feat(vpn): add reusable attached-peer portal runtime

Add a protocol-neutral portal runtime that converts authenticated client
sessions into attached EasyTier peers. Own per-client generations,
status, packet forwarding, address translation, and peer cleanup without
knowing the transport protocol.

Add transactional IPv4 source and destination rewriting with correct
IPv4, TCP, UDP, ICMP, and quoted-packet checksum updates. Keep the old
production portal path temporarily active until the WireGuard adapter is
migrated in the next change.

* feat(wireguard): attach named clients through peer portal

Replace the monolithic WireGuard portal with a native adapter that owns
key derivation, UDP demultiplexing, reauthentication, roaming, and
bounded per-client packet queues. Hand authenticated sessions to the
generic portal runtime for peer lifecycle and IPv4 translation.

Move portal configuration into the core instance model, require a
dedicated server key, and preserve existing listener, CLI, and runtime
configuration behavior. Reject runtime address conflicts before
publishing shared configuration.

* feat(vpn): expose per-client portal status

Project configured clients and their runtime state through the portal
RPC, including generated client configuration, listener, peer identity,
endpoint, tunnel address, ACL groups, and errors. Keep private client
configuration out of the broad instance-info response and expose the
explicit RPC through the CLI and Tauri bridge.

* feat(vpn): add portal configuration to web clients

Expose WireGuard portal listener, key, client, ACL group, and runtime
status fields in the shared frontend library, Web dashboard, and Tauri
client. Preserve UUID and uint64 values across protobuf JSON
boundaries, keep dynamic client editor rows stable, and document the
portal workflow.

* test(vpn): cover multi-client and roaming WireGuard portals

Add two three-node integration tests for the WireGuard VPN portal.

The multi-client test connects two kernel WireGuard clients from
separate network namespaces, verifies per-client connectivity to mesh
nodes, and exercises cross-client traffic that runs the IPv4 source
and destination translation in both directions. A TCP echo exchange
through the portal additionally covers the TCP pseudo-header checksum
rewrite path that ICMP-only ping tests miss, and portal status
snapshots must report both clients online with distinct peer ids and
correctly learned tunnel addresses.

The roaming test swaps the client namespace address (delete the old
address, then add the new one) so the kernel WireGuard source cache is
invalidated and the client keeps sending under the same session from
the new source, exactly like a real network change. The portal must
update the client endpoint on the same peer id via the data path
(same generation, no re-handshake, no detach/reconnect) while
connectivity to mesh nodes is preserved.

Supporting changes: run_wireguard_client now takes an interface name,
and the shared namespace topology gains net_f (10.1.2.5) on the portal
bridge for the second client.
2026-08-21 10:59:05 +08:00
KKRainbow e38b1354b3 Fix credential ospf logic, fix udp subnet proxy loop protection (#2315) 2026-06-07 12:40:09 +08:00
KKRainbow 958b246f05 improve webclient (#2151) 2026-04-23 13:44:18 +08:00
KKRainbow 0aeea39fbe refactor(gui): collapse public server and standalone into initial peer list (#2017)
The GUI exposed three networking modes: public server, manual, and standalone. In practice EasyTier does not have a server/client role distinction here. Those options only mapped to different peer bootstrap shapes, which made the product model misleading and pushed users toward a non-existent "public server" concept.

This change rewrites the shared configuration UX around initial nodes. Users now add or remove one or more initial node URLs directly, and the UI explains that EasyTier networking works like plugging in a cable: once a node connects to one or more existing nodes, it can join the mesh. Initial nodes may be self-hosted or shared by others.

To preserve compatibility, the frontend keeps the legacy fields and adds normalization helpers in the shared NetworkConfig layer. Old configs are read as initial_node_urls, while saves, runs, validation, config generation, and persisted GUI config sync still denormalize back into the current backend shape: zero initial nodes -> Standalone, one -> PublicServer, many -> Manual. This avoids any proto or backend API change while making old saved configs and imported TOML files load cleanly in the new UI.

Code changes:

- add initial_node_urls plus normalize/denormalize helpers in the shared frontend NetworkConfig model

- remove the mode switch and public-server/manual specific inputs from the shared Config component and replace them with a single initial-node list plus explanatory copy

- update Chinese and English locale strings for the new terminology

- normalize configs received from GUI/web backends and denormalize them before outbound API calls

- normalize GUI save-config events before storing them in localStorage so legacy payloads remain editable under the new model
2026-03-27 11:37:09 +08:00
KKRainbow 005b321f62 allow open rpc port in gui normal mode (#1795)
* allow open rpc port for gui normal mode
* downgrade dev tool console
2026-01-16 11:12:32 +08:00
Mg Pig 0a718163fd feat(gui): GUI add support to connect to config server (#1596) 2025-12-04 23:05:36 +08:00
Mg Pig 1f2517c731 feat(gui): add service and remote mode support (#1578)
This PR fundamentally restructures the EasyTier GUI, introducing support for service mode and remote mode, transforming it from a simple desktop application into a powerful network management terminal. This change allows users to persistently run the EasyTier core as a background service or remotely manage multiple EasyTier instances, greatly improving deployment flexibility and manageability.
2025-11-25 13:59:27 +08:00
Mg Pig 1273426009 feat: Enable core to use local config files while being managed via the web (#1540) 2025-11-08 20:32:00 +08:00
Mg Pig bbe8f9f810 feat(ui): Display network names and optimize list loading (#1503) 2025-10-22 13:40:36 +08:00
Mg Pig eba9504fc2 refactor(gui): refactor gui to use RemoteClient trait and RemoteManagement component (#1489)
* refactor(gui): refactor gui to use RemoteClient trait and RemoteManagement component
* feat(gui): Add network config saving and refactor RemoteManagement
2025-10-20 22:07:01 +08:00