From 50e459ed79295e18caf6396eb1bf7beca4454720 Mon Sep 17 00:00:00 2001 From: Ben_Kosytorz Date: Thu, 24 Sep 2026 16:00:43 +0200 Subject: [PATCH] Docs: Yggdrasil overlay note (rationale, deployment, admin API) + link updates --- documentation/Home.md | 3 + documentation/ideen/architektur.md | 3 +- documentation/ideen/overlay.md | 134 +++++++++++++++++++++++++++++ documentation/ideen/roadmap.md | 14 ++- server/README.md | 38 ++++++-- 5 files changed, 179 insertions(+), 13 deletions(-) create mode 100644 documentation/ideen/overlay.md diff --git a/documentation/Home.md b/documentation/Home.md index c1196dd..6d2e4f0 100644 --- a/documentation/Home.md +++ b/documentation/Home.md @@ -21,6 +21,7 @@ Nachbarschaft betreibt ihre eigene Instanz nach eigenen Regeln. | [[Ethos]] | Werte: Gemeingut, Fairness, Leechen erlaubt, legale Basis | | [[Idee]] | Kernidee + ehrlicher Realitätscheck | | [[Architektur]] | Schichten: Physik → Routing → Pooling → Freenet-Inhalte | +| [[Overlay]] | Yggdrasil als Overlay: Auswahl, Deployment, Grenzen | | [[Recht]] | Deutsche Rechtslage + Pflichtregeln für die Software | | [[Splitting]] | Was sich splitten lässt: Ranges, Flow-Verteilung, Realtime | | [[Lizenz]] | Lizenz-Optionen (Code & Doku) | @@ -41,6 +42,8 @@ Nachbarschaft betreibt ihre eigene Instanz nach eigenen Regeln. - [[Recht]] §5 (Pflichtregeln) ↔ [[Server-README]] (Haftungsausschluss) - [[Idee]] (Realitätscheck) ↔ [[Architektur]] (link-agnostische Physik, `sn-fetch`) - [[Splitting]] ↔ [[Architektur]] (Schicht 2) — was der Exit-Pool tatsächlich nutzen kann +- [[Overlay]] ↔ [[Architektur]] (Schicht 1) — Routing-Entscheidung und deren Grenzen +- [[Overlay]] ↔ [[Server-README]] — `sn-node` generiert die Yggdrasil-Config, `sn-fetch` nutzt `Egress::Proxy` - [[Lizenz]] ↔ [[Ethos]] §6 (Transparenz) und `freenet-core` (AGPL) ## Außerhalb der Doku diff --git a/documentation/ideen/architektur.md b/documentation/ideen/architektur.md index dcd4935..7b3aac3 100644 --- a/documentation/ideen/architektur.md +++ b/documentation/ideen/architektur.md @@ -53,7 +53,8 @@ mehr Pooling-Gewinn. ## Schicht 1 — Routing (Overlay über alle Haushalte) -Kandidaten (Auswahl offen, Kriterium: simpel, wartbar, verschlüsselt): +Auswahl, Deployment und Grenzen stehen in [[Overlay]] — kurz: **Yggdrasil +ist gewählt** (erste Wahl, bewusst austauschbar gehalten): | Kandidat | Pro | Con | |---|---|---| diff --git a/documentation/ideen/overlay.md b/documentation/ideen/overlay.md new file mode 100644 index 0000000..3a6e8c1 --- /dev/null +++ b/documentation/ideen/overlay.md @@ -0,0 +1,134 @@ +# Overlay: Yggdrasil + +Wie die Häuser untereinander erreichbar werden, bevor irgendwas gepoolt +wird. Stand: konzeptionell entschieden (erste Wahl), `sn-node`-Anbindung +begonnen (siehe [[Server-README]]). + +## Warum Yggdrasil? + +[Yggdrasil](https://yggdrasilnetwork.github.io/) ist ein +**self-contained Userspace-Router**: Jeder Node bekommt eine stabilen +IPv6-Adresse im `200::/7`-Raum, Nodes verbinden sich zu einem +end-to-end-verschlüsselten Overlay (Routing über einen +Spanning-Tree), egal ob Glasfaser, LAN, WLAN oder Internet dazwischen +liegt. + +Pro: + +- **Out-of-the-box verschlüsselt** — Peering-Verbindungen sind + kryptographisch gesichert, ohne extra WireGuard-Stapel +- **Null Konfiguration fürs Peering**: auf demselben LAN (also über die + Nachbarschafts-Faser oder den Keller-Switch) finden sich Nodes per + Multicast automatisch +- **Link-agnostisch** wie SpiderNet selbst: tcp://, tls://, quic:// + Listener und Peer-URIs, Funk/LAN/Faser egal +- **Feste Adresse pro Keypair** — die Node-Adresse bleibt, solange der + Schlüssel bleibt (wichtig für Exit-Zuteilung und Nachbarschafts-ACL) +- **`AllowedPublicKeys`**: nur gelistete Nachbarn dürfen peeren — + das Nachbarschafts-Vertrauen wird direkt vom Overlay erzwungen +- Single Rust/CPU-Binary, läuft auf Mini-PCs und Einplatinen + +Contra (ehrlich benannt): + +- Experimenteller als Babel; Performance-Obergrenze liegt deutlich + unter der, die dichte Glasfaser theoretisch bieten könnte — für + Phase 1 (2–3 Haushalte) völlig ausreichend, Messwerte dokumentieren +- Wenn das Overlay zum Flaschenhals wird: Babel + WireGuard als + Ausweich-Kandidat (siehe [[Architektur]], Schicht 1) + +## Rollen im SpiderNet-Node + +```mermaid +flowchart LR + subgraph Haushalt + DEVICES[Geraete] -->|own uplink| ROUTER[Router/ISP] + NODE[sn-node] --- YG[yggdrasil daemon] + YG <-->|mesh links| NACHBAR[yggdrasil der Nachbarn] + NODE -->|getSelf / getPeers| YG + NODE -->|sn-exit: HTTP proxy| YG + end + NACHBAR -->| Exit requests| ORIGIN((Origin)) +``` + +1. **yggdrasil-Daemon** (Prozess/Sidecar, nicht von uns implementiert): + bildet das Overlay, jede Faser wird zur Overlay-Verbindung. +2. **sn-node** (unser Daemon): generiert die yggdrasil.conf aus + validierten Einstellungen, fragt den Admin-Socket ab (Node-Adresse, + Peers), orchestriert Exit und Fetch. +3. **sn-exit** (geplant): HTTP-Proxy, der auf der Yggdrasil-Adresse des + Haushalts lauscht — Nachbarn senden ihre Segment-Requests dorthin, + der Haushalt holt sie über seinen Uplink. +4. **sn-fetch**: kennt pro Exit einen `Egress` (`Direct` = eigener + Uplink, `Proxy` = HTTP-Proxy eines Nachbarn) und plant Segmente + darauf. + +## Admin-Socket (technische Fakten) + +Quelle: [Admin-API-Doku](https://yggdrasil-network.github.io/admin.html) + +- Default `localhost:9001` (TCP), alternativ Unix-Socket + (`AdminListen` in der Konfig) +- Protokoll: JSON-Stanza + `\n`; Anfrage `{"request": "getself"}`; + Antwort enthält immer `"status"` (`"success"`/`"error"`), optional + `"response"` und `"error"` +- `getSelf` → eigene Adresse, routed `/64`-Subnetz (`300:…::/64`), + Public Key, Build-Version +- `getPeers` → aktive Peer-Sessions inkl. Peering-URI +- `sn-node status` kapselt genau das (siehe unten) + +## Deployment: zwei Häuser verkabeln + +Schritt-für-Schritt für Phase 1 (Prototyp-Scope, **keine Garantie**, +siehe [[Recht]]): + +1. **Hardware:** je Haus ein Mini-PC mit zwei NICs (eine zum + Heim-Router, eine zur Nachbarschafts-Faser bzw. zum Switch im + Keller) — oder übergangsweise eine NIC am Mesh-Switch. +2. **Yggdrasil installieren** (Debian-Paket oder Binary). +3. **Config generieren:** + `sn-node genconf --peer "tcp://[]:1337" --listen "tcp://[::]:1337" --allow-key --out /etc/yggdrasil.conf` + - im selben LAN reicht Multicast-Auto-Peering ohne `--peer` + - `--no-multicast`, wenn Peering nur über die explizite Liste laufen + soll (z. B. gemischte Nachbarschaft) + - die `allowed_public_keys`-ACL: nur die gelisteten Nachbarn können + peeren — für ein Viertel die persönliche Freischaltung +4. **Start:** `yggdrasil -useconffile /etc/yggdrasil.conf` +5. **Status:** `sn-node status` → eigene Overlay-Adresse, Subnetz, + Version, verbundene Nachbarn +6. **Test:** von Haus A `ping ` (IPv6 im Overlay). +7. **Exit anbieten** (geplanter `sn-exit`): HTTP-Proxy auf der + Overlay-Adresse binden; beim Nachbarn dann + `sn-fetch -e "1=1,2=1@http://:8080"`. + +Die Config-Datei enthält den **privaten** Schlüssel des Nodes: +`chmod 600` (macht `sn-node genconf` selbst), niemals committen, nie +teilen. Private Adressen realer Nachbarn gehören nicht ins Repo +(Regeln in `AGENTS.md`). + +## Grenzen & Sicherheit + +- **Yggdrasil ist keine Anonymisierung.** Die Overlay-Adresse ist ein + stabiler Pseudonym; wer Peering-Verbindungen beobachtet, sieht, wer + mit wem verbunden ist. SpiderNet verspricht deshalb nirgends + Anonymität (konsistent mit Freenet-Position in [[Ethos]]). +- **Exit = Vertrauensstellung:** Der Exit-Haushalt sieht die URLs der + Segmente, die er für Nachbarn holt. Standard-Kontingente, jederzeit + widerruflich (Kill-Switch, siehe [[Architektur]]). +- **Port-Forwarding:** Eingehende Peerings über das Internet (z. B. + wenn zwei Häuser nicht direkt verbunden sind und den Weg übers + normale Internet nehmen) brauchen ein Forward des `Listen`-Ports; + innerhalb der Faser/Multicast nicht nötig. +- **Wenn die Faser später schneller als Yggdrasil wird:** Messwerte + sammeln; ggf. pro Link WireGuard-Punkt-zu-Punkt direkt nutzen und + Yggdrasil nur als Control-Plane — Architektur-Schicht 1 ist bewusst + austauschbar gehalten. + +## Quellen + +- Yggdrasil-Website & Docs: +- Admin API: +- Configuration: + (genconf/useconf, HJSON/JSON, `Peers`, `Listen`, `MulticastInterfaces`, + `AllowedPublicKeys`, `IfName: none` für router-only) +- Quellcode (Go, AGPL-3.0 — wir rufen nur das Binary auf, keine + Derivate): diff --git a/documentation/ideen/roadmap.md b/documentation/ideen/roadmap.md index 88e1a44..aae59de 100644 --- a/documentation/ideen/roadmap.md +++ b/documentation/ideen/roadmap.md @@ -18,8 +18,14 @@ Ziel: Beweis, dass Pooling über zwei Anschlüsse real funktioniert. - [x] `sn-fetch` PoC (lokal): Range-Probe, gewichteter Planner, parallele Segment-Downloads, Reassembly + SHA-256 — verifiziert gegen einen echten Server (Debian-Mirror); Multi-Exit-Routing folgt mit dem Mesh -- [ ] SpiderNet-Node auf Mini-PC (Raspberry Pi / N100-Box), Yggdrasil-Overlay - zwischen 2 Haushalten (Kabel oder Kurzstrecke WLAN/60-GHz) +- [x] `sn-fetch`: Segment-Retry mit Exit-Reassignment, Progress-Sinks, + per-Exit-Egress (`Direct`/`Proxy`) — Nachbar-Exit über HTTP-Proxy + end-to-end getestet +- [x] `sn-node` v0: Yggdrasil-Config-Generierung (`genconf`) + Admin-Socket- + Client (`status`) — die Overlay-Anbindung beginnt +- [ ] Yggdrasil-Overlay zwischen 2 Haushalten (Kabel oder Kurzstrecke + WLAN/60-GHz), `sn-node`-Daemon orchestriert den Node +- [ ] `sn-exit` v0: HTTP-Proxy auf der Yggdrasil-Adresse (Kontingente) - [ ] `sn-fetch` PoC über 2 echte Exits, plus Baseline-Messung (1-Exit vs. 2-Exit, gleiche Datei) - [ ] Fair-Share-Scheduler v0: zwei gleichzeitige Downloads, faire Aufteilung @@ -29,8 +35,8 @@ Ziel: Beweis, dass Pooling über zwei Anschlüsse real funktioniert. Ziel: ein Paket, das 3–10 Haushalte installieren können. -- [ ] `sn-node` Daemon: Discovery, Peering, Metriken (per-Exit Bandbreite/ - Latenz), Onboarding-Flow (QR/Knopfdruck) +- [ ] `sn-node` Daemon v1: Metriken aus Yggdrasil-Peering (per-Exit + Bandbreite/Latenz), Onboarding-Flow (QR/Knopfdruck) - [ ] Exit-Pool: Kontingente, opt-in/opt-out, Leech-Modus, Kill-Switch - [ ] `sn-fetch`: API + CLI + einfache Browser-Integration - [ ] `sn-cache`: lancache-artiger transparenter Cache (DNS-basiert) diff --git a/server/README.md b/server/README.md index 61a4a8a..03076e0 100644 --- a/server/README.md +++ b/server/README.md @@ -12,17 +12,39 @@ macht. Sprache: **Rust**. Exit, Mindest-Segmentgröße mit Merge-Fix, validated: lückenlose, vollständige Abdeckung) - Parallele Segment-Downloads (Streaming, eigener reqwest-Client pro Exit) +- **Retry mit Exit-Reassignment:** fehlgeschlagene Segmente werden (wieder- + holbar, Standard 3 Versuche) bevorzugt auf einem anderen Exit wiederholt; + nicht-retrybare Fehler (4xx, korrupte Parts) brechen sofort ab — ein + halbfertiges File wird nie als Erfolg ausgegeben +- **Progress:** `ProgressSink`-Events (Segment started/finished/failed, + `BytesTracker`) + `tracing`-Logging +- **Per-Exit-Egress:** `Direct` (eigener Uplink) oder `Proxy` (HTTP-Proxy + eines Nachbarn — der Weg für `sn-exit` über das Overlay); end-to-end + getestet gegen einen echten Forward-Proxy - Reassembly in Index-Reihenfolge + Streaming-SHA-256 + Längen-Check - Fallback: range-hostile Server werden als single-stream geladen -- CLI: `sn-fetch [-o out] [-e "1=2,2=1"] [-s n] [--sha256 hex] --probe-only` +- CLI: `sn-fetch [-o out] [-e "1=2,2=1@http://[ygg]:8080"] [-s n] + [--max-attempts n] [--sha256 hex] --probe-only` Verifiziert gegen einen echten Server (Debian-CD-Mirror, 756 MB, 8 Segmente, SHA-256 entspricht der offiziellen `SHA256SUMS`). -**Noch nicht drin:** Multi-Exit-Routing über das Mesh (aktuell laufen alle -Exits als lokale Verbindungen — die Struktur [`HttpExit`]-Trait, -Exit-Registry] ist dafür schon bereit), Retry bei Segment-Fehlern, -Progress-Anzeige während des Laufs. +**`sn-node` v0 ist implementiert** (siehe `crates/sn-node/`): + +- `sn-node genconf`: erzeugt eine Yggdrasil-Config aus validierten + Einstellungen — Basis ist immer der echte `yggdrasil -genconf -json` + Output (keine hartcodierten Defaults), gepatcht mit `Peers`, `Listen`, + `MulticastInterfaces`, `AdminListen`, `AllowedPublicKeys` (Nachbarschafts- + ACL), `IfName`, `PrivateKeyPath`; Output-Datei wird auf 600 gesetzt +- `sn-node status`: fragt den Admin-Socket ab (`getSelf`/`getPeers` über + TCP `localhost:9001` oder Unix-Socket) — Overlay-Adresse, Subnetz, + Version, aktive Peer-Verbindungen + +**Noch nicht drin:** `sn-exit` (der Proxy-Dienst, der auf der Yggdrasil- +Adresse lauscht und Segmente für Nachbarn holt), `sn-node`-Daemon (Supervisor, +der yggdrasil + sn-exit + sn-fetch orchestriert), Fairness-Scheduler. + +Details zum Overlay: [[Overlay]]. ## Haftungsausschluss (muss im Produkt sichtbar sein) @@ -52,14 +74,14 @@ Einplatinenrechner), der: | Crate/Binary | Zweck | |---|---| -| `sn-node` | Daemon: Discovery, Peering, Metriken, Onboarding | -| `sn-exit` | Exit-Dienst: kontingentierter Uplink-Proxy für Nachbarn (verschlüsselt) | +| `sn-node` | Node-Glue: Yggdrasil-Config (`genconf`), Overlay-Status (`status`), später Daemon/Supervisor | +| `sn-exit` | Exit-Dienst: kontingentierter Uplink-Proxy auf der Yggdrasil-Adresse (geplant) | | `sn-fetch` | Segmentierter Multi-Exit-Downloader (HTTP-API + CLI) | | `sn-fair` | Fairness-Scheduler (max-min, Exit-Kontingente, Karma, Leech-Modus) | | `sn-cache` | Transparenter Nachbarschafts-Cache (DNS-basiert) | | `sn-freenet` | Integration von `freenet-core` (Contracts für Nachbarschafts-Inhalte) | -## MVP (Phase 2 der [[Roadmap]]) +## MVP (Phase 1→2, siehe [[Roadmap]]) Kleinster brauchbarer Schnitt: