Files
nx9-wg/docs/NATIVE-WIREGUARD.md
2026-09-02 15:19:19 +05:30

5.5 KiB

Native Linux WireGuard Engine (NativeLinuxWireGuardEngine)

The NativeLinuxWireGuardEngine provides direct, in-process communication with the Linux kernel WireGuard subsystem via Linux Netlink sockets.


Unlike traditional WireGuard management tools that spawn external CLI processes (wg, wg-quick), nx9-wg uses native kernel sockets:

┌────────────────────────────────────────────────────────┐
│             NativeLinuxWireGuardEngine                 │
└───────────────┬────────────────────────┬───────────────┘
                │                        │
  Link Lifecycle (Create / Up / Down)    │ Cryptographic Config & Telemetry
  via RTNETLINK (AF_NETLINK, NETLINK_ROUTE)│ via Generic Netlink (family "wireguard")
                │                        │
┌───────────────▼────────────────────────▼───────────────┐
│              Linux Kernel (wireguard.ko)               │
└────────────────────────────────────────────────────────┘
  • Interface Creation: Sends RTM_NEWLINK with link type wireguard.
  • Interface Deletion: Sends RTM_DELLINK by interface index or name.
  • Interface State: Toggles IFF_UP and IFF_DOWN flags without invoking ip link set up/down.
  • MTU Assignment: Configures interface MTU directly in the RTM_NEWLINK netlink attributes.
  • Resolves the dynamic Generic Netlink family ID for "wireguard".
  • WG_CMD_SET_DEVICE: Atomically configures the interface private key, UDP listen port (if explicitly configured), and peer list.
    • Optional ListenPort: If interface.listen_port is Some(port) and port != 0, WGDEVICE_A_LISTEN_PORT is emitted. If None (standard for Upstream interfaces like proton0), the attribute is omitted, allowing the Linux kernel to automatically bind an ephemeral dynamic UDP port.
  • WG_CMD_GET_DEVICE: Queries live kernel device state, active listen port, public key, peer public keys, endpoints, allowed IPs, last handshake timestamps, and transfer byte counters.
  • WGDEVICE_F_REPLACE_PEERS: When syncing peers, setting this flag instructs the kernel to atomically replace all existing peers with the supplied desired set, removing stale peers in a single transaction.

2. Peer Cryptographic Synchronization & Role-Aware AllowedIPs

sequenceDiagram
    autonumber
    participant Engine as NativeLinuxWireGuardEngine
    participant Genl as Generic Netlink Socket
    participant Kernel as Linux Kernel (wireguard.ko)

    Engine->>Genl: Send WG_CMD_SET_DEVICE (Interface wg0, ReplacePeers=true)
    Note over Engine,Genl: Encodes ListenPort (if Some), PrivateKey, Peer Array
    Genl->>Kernel: Transmit Netlink Message
    Kernel->>Kernel: Validate Keys, Bind UDP Port (or dynamic), Apply Peers
    Kernel-->>Genl: NLMSG_ERROR (error=0 / Success)
    Genl-->>Engine: Ok(())

    Engine->>Genl: Send WG_CMD_GET_DEVICE (Interface wg0)
    Genl->>Kernel: Query Live State
    Kernel-->>Genl: Return Device Attributes & Peer Telemetry
    Genl-->>Engine: Live Telemetry (Handshakes, Bytes Tx/Rx)

Role-Aware Cryptographic Attribute Encoding:

  • Keys: 32-byte binary Curve25519 keys (WGPEER_A_PUBLIC_KEY, WGPEER_A_PRESHARED_KEY).
  • Role-Aware Allowed IPs:
    • Overlay Peers: Scoped to /32 (IPv4) or /128 (IPv6) derived from the peer's assigned tunnel address.
    • Upstream Provider Peers: Preserves full-tunnel AllowedIPs (0.0.0.0/0, ::/0) on the WireGuard device without modifying the server's Linux FIB default routing table.
  • Endpoint: sockaddr_in (IPv4) or sockaddr_in6 (IPv6) socket address structures representing the remote destination (e.g. 37.19.199.155:51820), independent of the local interface listen port.
  • Persistent Keepalive: Interval in seconds (WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL).

3. Telemetry & Handshake Monitoring

The engine queries live kernel transfer statistics without writing temporary files:

  • last_handshake_at: Calculated from WGPEER_A_LAST_HANDSHAKE_TIME (seconds and nanoseconds since UNIX epoch).
  • rx_bytes / tx_bytes: 64-bit byte counters (WGPEER_A_RX_BYTES, WGPEER_A_TX_BYTES).
  • endpoint: Actual remote socket address learned dynamically by the kernel through authenticated roaming.

4. Security & Memory Safety Invariants

  1. Zero Subprocesses: No calls to wg, wg-quick, or ip.
  2. Secret Redaction: Private keys and preshared keys implement custom std::fmt::Debug formatters emitting [REDACTED].
  3. Memory Scrubbing: Sensitive cryptographic buffers are wrapped in types that zeroize memory upon drop.
  4. Linux Capability Boundary: Requires CAP_NET_ADMIN to open Netlink route and generic sockets.

5. Non-Linux Platform Fallback

On non-Linux platforms (macOS, Windows), nx9-wg automatically switches to SimulatedWireGuardEngine. This allows frontend UI and CLI development on local workstations while preserving the exact same WireGuardEngine trait interface.