Files
nx9-wg/docs/NATIVE-WIREGUARD.md
T

89 lines
4.8 KiB
Markdown

# Native Linux WireGuard Engine (`NativeLinuxWireGuardEngine`)
The `NativeLinuxWireGuardEngine` provides direct, in-process communication with the Linux kernel WireGuard subsystem via Linux Netlink sockets.
---
## 1. Protocol Architecture: RTNETLINK & Generic Netlink
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) │
└────────────────────────────────────────────────────────┘
```
### A. RTNETLINK Link Lifecycle
- **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.
### B. WireGuard Generic Netlink Protocol
- Resolves the dynamic Generic Netlink family ID for `"wireguard"`.
- **`WG_CMD_SET_DEVICE`**: Atomically configures the interface private key, UDP listen port, and peer list.
- **`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
```mermaid
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, PrivateKey, Peer Array
Genl->>Kernel: Transmit Netlink Message
Kernel->>Kernel: Validate Keys, Bind UDP Port, 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)
```
### Cryptographic Attribute Encoding:
- **Keys**: 32-byte binary Curve25519 keys (`WGPEER_A_PUBLIC_KEY`, `WGPEER_A_PRESHARED_KEY`).
- **Allowed IPs**: Nested attributes (`WGALLOWEDIP_A_FAMILY`, `WGALLOWEDIP_A_IPADDR`, `WGALLOWEDIP_A_CIDR_MASK`).
- **Endpoint**: `sockaddr_in` (IPv4) or `sockaddr_in6` (IPv6) socket address structures.
- **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.