From ee2f5d545825752af63da36e2b9ec7a92985a875 Mon Sep 17 00:00:00 2001 From: James O'Doherty Date: Fri, 29 May 2026 18:29:12 -0400 Subject: feat: implement userspace wireguard data-path and unprivileged host fd-passing - Implement complete rootless network namespace bootstrap via C launcher using unshare(CLONE_NEWUSER | CLONE_NEWNS | CLONE_NEWNET). - Resolve unprivileged network isolation blackhole via host-socket preservation (FD passing): open client UDP sockets on the host pre-isolation, clear O_CLOEXEC, and ingest them via custom `FDBind` inside the sandbox. - Implement isolated routing table automation over `tun0` (addresses, MTU, default routes). - Implement persistent, multi-process namespace sharing and joining using reference-counted PID files and the setns system call. - Write robust, self-contained E2E data plane test suites in `tests/e2e/e2e_test.go` using a mock UDP listener. - Update project documentation (`README.md` and `AGENTS.md`) to reflect completed milestones. - Ensure 100% test passing rate and zero lint/staticcheck warnings. --- AGENTS.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'AGENTS.md') diff --git a/AGENTS.md b/AGENTS.md index dd1bdaa..8067fdf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -79,9 +79,9 @@ We employ a three-tier testing approach to balance speed and reliability: - **MTU**: Always default the TUN device MTU to `1420` to account for WireGuard overhead. ### 3. Namespace Lifecycle -- **Creation**: `CLONE_NEWUSER` $\rightarrow$ `CLONE_NEWNET`. -- **Persistence**: Namespaces are pinned by bind-mounting the namespace file to `/run/user/$UID/wg-wrap/profiles/`. -- **Cleanup**: The tool must monitor the wrapped process and ensure the namespace is unpinned/torn down via `wg-wrap profile stop` or upon process termination. +- **Creation**: `CLONE_NEWUSER` $\rightarrow$ `CLONE_NEWNS` $\rightarrow$ `CLONE_NEWNET` inside an embedded C launcher. +- **Persistence & Sharing**: Namespaces are pinned and shared rootlessly. Processes record active runs inside a profile's `pids/` directory. Subsequent wrapping calls use `setns` (via `unix.Setns`) to enter the existing namespace context in $\approx 10\text{ms}$. +- **Cleanup**: When the last active process registers its exit, the reference counting detects 0 remaining sessions, automatically unpins state files, and releases resources cleanly. ## System Assumptions The project assumes the target environment is a modern Linux system configured for rootless container operations (e.g., Podman is installed and functional): @@ -90,9 +90,10 @@ The project assumes the target environment is a modern Linux system configured f - **TUN Access**: The user has permission to access `/dev/net/tun`. - **Tooling**: The `ip` command (iproute2) is available in the environment. -## Roadmap Priority -1. **Configuration**: Implement robust `.conf` parsing in `pkg/wgconf`. -2. **Bootstrapping**: Implement the `unshare` and user-mapping flow in `internal/namespace`. -3. **Data Path**: Integrate `wireguard-go` with the TUN device in `internal/wireguard`. -4. **Routing**: Automate the isolated routing table setup. -5. **Lifecycle**: Implement namespace pinning and cleanup. +## Roadmap Priority (Completed) +1. **Configuration**: Parse robust `.conf` files in `pkg/wgconf`. +2. **Bootstrapping**: Unshare Mount, User, and Network namespaces safely using an embedded static C launcher. +3. **Host Socket Preservation**: Open UDP sockets on the host before isolation and pass them (`WG_WRAP_HOST_SOCKET_FD`) to `wireguard-go` using `FDBind` to bypass kernel security boundaries. +4. **Data Path**: Integrate `wireguard-go` with `tun` devices seamlessly inside the namespace. +5. **Routing**: Automatically build default routing gateway tables in the isolated network namespace. +6. **Namespace Sharing**: Connect concurrent wrapping runs to the active tunnel rootlessly via `setns`. -- cgit v1.2.3