Implement the WireGuard data plane plugin
The first IP plugin, built on the data plane boundary the core already had. Plugin: - one X25519 key per network in the plugin's own wireguard.sqlite, separate from the iroh identity and from the network secret; a damaged store is an error, never a silently regenerated identity - deterministic IPv6 ULA overlay: every member derives the same /64 from the network id and its own /128 from its WireGuard public key, so no coordinator allocates addresses - AllowedIPs are derived locally, never taken from a peer's announcement, so a member cannot claim another member's overlay address; a mismatched claim is rejected - bounded, versioned, validated announcement carried as the existing opaque capability payload, which the core still never parses - each agent builds its own full-mesh configuration (N-1 peers) and reconciles on every change and on a timer, repairing drift - WireguardBackend abstraction: RecordingBackend in memory, and WgToolBackend driving real wg/ip on Linux, split into a pure planner plus parsers and a thin executor so everything interesting is testable without root Core, three generic additions the plugin needed: - IpPlugin::on_network_activated, so per-network state is ready before peers - PluginContext for re-announcements and error reports from plugin tasks, with errors counted by the owning network runtime - IpPlugin::shutdown, awaited with a grace period, so system objects go away 94 tests pass offline with no privileges: 35 new WireGuard unit tests and 12 integration tests over real iroh connections. The real wg/ip backend needs root and is behind --ignored in tests/wireguard_system.rs; it was not run. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+18
-2
@@ -19,6 +19,10 @@ Read this before relying on anything here. The protocol is in
|
||||
messages for network B, even over a shared physical connection.
|
||||
- **Confidentiality and integrity in transit.** Provided by QUIC/TLS. This
|
||||
crate adds no encryption of its own.
|
||||
- **Overlay address ownership.** A WireGuard peer's `AllowedIPs` are derived
|
||||
from its public key, not taken from its announcement, so a member cannot
|
||||
claim another member's overlay address and receive its traffic. See
|
||||
[wireguard.md](wireguard.md#deterministic-overlay-addressing).
|
||||
- **Resource bounds.** Frame lengths are validated before allocation; strings,
|
||||
lists, queues, concurrent dials and in-flight handshakes are all bounded;
|
||||
handshakes, dials and writes have timeouts.
|
||||
@@ -45,8 +49,20 @@ Read this before relying on anything here. The protocol is in
|
||||
permissions are owner-only where the platform supports it, and the state
|
||||
directory takes an ownership lock, but neither defends against a user who can
|
||||
read the file or against malware running as that user.
|
||||
- **User IP traffic.** Not carried here at all. Filtering it is the operating
|
||||
system's and the user's job.
|
||||
- **User IP traffic.** Carried by the WireGuard plugin, not by iroh, and
|
||||
encrypted by WireGuard itself. *Filtering* it is still the operating system's
|
||||
and the user's job: the plugin creates connectivity between members and does
|
||||
not police what flows over it.
|
||||
- **Overlay address squatting.** A member can mint many WireGuard keys and
|
||||
therefore occupy many overlay addresses. It cannot pick which ones, but it
|
||||
can consume them and appear as many participants.
|
||||
- **Plugin keys on disk.** The WireGuard private keys live in the plugin's own
|
||||
`wireguard.sqlite`, owner-only where the platform supports it. Copying that
|
||||
file copies this agent's overlay identity, exactly as copying `state.sqlite`
|
||||
copies its control plane identity.
|
||||
- **What the data plane does not police.** The plugin sets `AllowedIPs` per
|
||||
peer, which stops a member impersonating another member's overlay address.
|
||||
It does not stop a member sending whatever it likes *from its own* address.
|
||||
- **Denial of service.** Bounds and timeouts stop trivial resource exhaustion
|
||||
from a single peer. They do not make the agent resistant to a determined
|
||||
attacker who knows the secret, and no rate limiting per identity exists yet.
|
||||
|
||||
Reference in New Issue
Block a user