đČđŠ TLS-Gate & Die Wald-CA: Warum jedes Bit zĂ€hlt (ASCII-Prozesskette)
FĂŒr alle KrĂŒmel & die Crew (
#oldschool#mcp#nullfeld#zeitlos)
Stand: 18.10.2026 · Gemini-Crew & Branko
Zweck: Sichtbar machen, warum der Nachbau âohne Docker" im echten System so verdammt prĂ€zise sein muss â wann welcher SchlĂŒssel wo greift, warum RZ, Strato, Crumbforest-Container und OZM-Museum getrennte Welten mit Lese-BrĂŒcken sind und warum eine unabhĂ€ngige Container-CA das Geheimnis fĂŒr echtes Offline-Ăberleben ist.
0. Warum man beim Nachbau ohne Docker um jedes Bit kÀmpft
Docker versteckt oft schlampige Grenzen: Man wirft alles in einen Container, teilt sich blind ein Dateisystem oder eine .env und merkt erst beim Ausfall, dass alles an einem einzigen Faden hing.
Wenn man es nackt auf dem System (Native PHP-FPM + MariaDB + Linux-User + Systemd) baut, wird jede Grenze physisch echt:
- Welcher Linux-User (root, www-data, tlsgate) darf welche Datei lesen?
- Welcher Datenbank-User (tlsgate_ddl vs. tlsgate_app) spricht ĂŒber welchen Unix-Socket?
- Welcher SchlĂŒssel liegt im RAM, welcher auf Platte (/etc/tlsgate/master.key), welcher versiegelt in der DB (tg1:...)?
- Wann wird ein Key abgeleitet (KDF), wann gebunden (Associated Data), wann aus dem RAM genullt (sodium_memzero)?
Ein einziges falsches Bit bei group_id, user_id, key_id oder Dateirechten (0640 vs. 0600) â und das System sagt NEIN (Fail-Closed). Genau diese HĂ€rte beim Einrichten ist spĂ€ter der Schutzschild im Betrieb.
1. Die Gesamt-Topologie: Drei Welten, getrennte VPNs, gemeinsames Lesen
Im Rechenzentrum (RZ) lĂ€uft der TLS-Gate-Core im Verbund mit dem Strato-Setup (crumbforest.org / .io / nullfeld / backbone). Gleichzeitig existieren eigene IdentitĂ€ten und eigene CAs fĂŒr den Crumbforest-Container (Waldmitte) und das OZM Museum.
+=========================================================================================+
| AUSSENWELT / OEFFENTLICHE REGISTRARE |
| InterNetX / AutoDNS SOAP-API (Public TLS: *.crumbforest.org / *.crumbforest.io) |
+=========================================================================================+
^
| HTTPS + WSDL-Allowlist (TLSGATE_SOAP_HOSTS)
| Stream-Timeout 20s / Connect-Timeout 15s
v
+=========================================================================================+
| RECHENZENTRUM (RZ) & STRATO-VERBUND (NULLFELD / BACKBONE) |
| |
| +-----------------------------------------------------------------------------------+ |
| | TLS-GATE CORE (NativePHP RC1.0) | |
| | | |
| | Mandant / Gruppe A: [crumbforest] Mandant / Gruppe B: [ozm] | |
| | - Public Certs (.org / .io) - Eigene OZM-Identitaet | |
| | - Registrar-Spiegel (Inventory) - Eigener WireGuard-Kreis | |
| | - NetBox-Spiegel (seeds.crumbforest.io) - Eigene SOAP/NetBox/CA-Blobs | |
| +-----------------------------------------------------------------------------------+ |
| | | |
| | WG-Tunnel A (10.42.0.x / nullfeld) | WG-Tunnel B (OZM) |
+==================|=================================================|====================+
| |
| (Getrennte Schreib-/Tunnelhoheit) |
v v
+-----------------------------------------+ +---------------------------------------+
| WELT 1: CRUMBFOREST CONTAINER | | WELT 2: OZM MUSEUM |
| (Waldmitte / Pelicases / Baumhaus) | | (Hammerbrooklyn / Ausstellung) |
| | | |
| * Eigene lokale Container-CA | | * Eigene lokale Museums-CA |
| * Lokale Sensorik (Pose, Hailo, | | * Lokale Sensorik (Raum, Licht, |
| snakeview, rattlecam, LiPo-Sim) | | Klangkoerper, Installationen) |
| * Lokales RAG (Ollama + Qdrant/ | | * Eigener lokaler Kontext |
| KernelCrumb / missions-core) | | |
| | | |
| [SCHREIBT NUR LOKAL] | | [SCHREIBT NUR LOKAL] |
+-----------------------------------------+ +---------------------------------------+
\ /
\ <--- Duerfen untereinander ---> /
+=======> NUR LESEN (Read-Only) <====+
(Kein Central Command, kein Durchgriff)
Warum diese Trennung? (Structural Antifascism by Design)
- Getrennte WireGuard-VPNs & getrennte CAs: Wenn im Museum ein Sensor-Node wackelt oder umgebaut wird, berĂŒhrt das niemals den SchlĂŒsselraum des Crumbforest-Containers (und umgekehrt).
- Untereinander lesen, aber nicht fremdsteuern: Kein Node hat âCentral Command" ĂŒber den anderen. Jeder Raum ist sein eigenes Universum, darf aber den Zustand/Spiegel des Nachbarn lesend verstehen.
- Mandanten-Bindung bis ins Kryptogramm: Selbst im selben
TLS-Gate-Core im RZ kann Gruppecrumbforestmathematisch niemals ein Secret von GruppeozmentschlĂŒsseln, weilgroup_idfest in den AEAD-Tag (tg1|soap|<group_id>|default) eingebacken ist.
2. Wann, Wo, Welcher Key? (Die SchlĂŒssel-Uhrwerk-Matrix)
Hier scheitert man beim Nachbau am schnellsten, wenn man nicht genau sieht, wann welcher SchlĂŒssel wo lebt:
===========================================================================================
SCHICHT 0: DIE PLATTE (Root-Ebene, ausserhalb von Git & ausserhalb von Web-Root)
===========================================================================================
Datei: /etc/tlsgate/master.key (oder TLSGATE_MASTER_KEY_FILE)
Inhalt: 1:<64-Hex-Zeichen (32 Byte Roh-Entropie)>[,2:<64-Hex-Zeichen>...]
Rechte: chown root:www-data, chmod 0640 (Web-Worker darf nur lesen, nie schreiben)
|
| (Wird NUR im Moment von Secrets::seal() oder Secrets::open() eingelesen)
v
===========================================================================================
SCHICHT 1: DIE SCHLUESSEL-ABLEITUNG (KDF im RAM â Secrets.php)
===========================================================================================
Funktion: sodium_crypto_kdf_derive_from_key(32, subkey_id, "TLSGATE1", $rootKey)
Formel : subkey_id = (key_id * 100) + PURPOSE_SLOT
Root-Key (32 Byte)
|
+---> Slot 1 ('totp') --> Subkey fuer 2FA-Geheimnisse der Benutzer
+---> Slot 2 ('soap') --> Subkey fuer Registrar-Logins (InterNetX/AutoDNS)
+---> Slot 3 ('outbox') --> Subkey fuer ausgehende Nachrichten / Queue
+---> Slot 4 ('ca') --> Subkey fuer lokale VPN- & Container-CA Private Keys!
+---> Slot 5 ('netbox') --> Subkey fuer NetBox-API-Tokens (seeds.crumbforest.io)
|
| + 24 Byte Zufalls-Nonce (random_bytes)
| + Associated Data (AD) = "tg1|<purpose>|<bind>"
v
===========================================================================================
SCHICHT 2: DIE VERSIEGELUNG (AEAD XChaCha20-Poly1305 in der MariaDB)
===========================================================================================
Was in der Datenbank steht, ist IMMER nur der fertige "tg1:"-Blob:
Format: "tg1:" + Base64( [0x01] [key_id: u32_le] [nonce: 24B] [ciphertext + 16B MAC] )
WICHTIG â DIE BINDUNG (Associated Data):
-----------------------------------------------------------------------------------------
Zweck | Tabelle | Spalte | Bind-String ($bind)
----------+--------------------+------------------+--------------------------------------
totp | users | totp_secret_enc | "user:<users.id>"
soap | soap_credentials | secret_enc | "<group_id>|<label>"
netbox | netbox_credentials | token_enc | "<group_id>|<label>"
ca | (ca_keys / lokal) | privkey_enc | "<group_id>|<ca_slug>"
-----------------------------------------------------------------------------------------
-> Kopiert jemand in der DB den Blob von Gruppe 1 nach Gruppe 2, stimmt $bind beim
Oeffnen nicht mehr -> AEAD-MAC schlaegt fehl -> RuntimeException!
-> Sofort nach seal()/open(): sodium_memzero($sub) loescht den Subkey aus dem RAM.
3. Die 4 Prozessketten im Detail (Schritt fĂŒr Schritt)
Prozesskette A: Kaltstart & Bootstrap (Ohne Docker auf der Node)
[1. Linux / MariaDB]
|
+-- System-User `tlsgate` (CLI/Cron) & `www-data` (PHP-FPM Pool)
+-- DB-User `tlsgate_ddl` (DARF: CREATE, ALTER, TRIGGER â NUR fuer Migration!)
+-- DB-User `tlsgate_app` (DARF NUR: SELECT, INSERT, UPDATE, DELETE auf App-Tabellen)
|
v
[2. Master-Key erzeugen]
$ php bin/user_cli.php key gen > /etc/tlsgate/master.key
$ chmod 0640 /etc/tlsgate/master.key
|
v
[3. Datenbank-Schema & Append-Only-Trigger einspielen]
$ DB_USER=tlsgate_ddl DB_PASS=... bin/tg migrate
| -> Legt Tabellen an (groups, users, audit_log, registrar_inventory, netbox_devices...)
| -> Installiert BEFORE UPDATE / BEFORE DELETE Trigger (SIGNAL SQLSTATE '45000')
| auf: audit_log, booking_events, catalog_events, registrar_inventory_events
|
v
[4. Gruppen (Mandanten) & Zugangsdaten versiegeln]
$ bin/tg user add-group crumbforest "Crumbforest"
$ bin/tg user add-group ozm "OZM Museum & Hub"
$ bin/tg user cred add crumbforest default https://.../wsdl <user>
| -> Prueft WSDL gegen TLSGATE_SOAP_HOSTS
| -> Versiegelt Login+Passwort mit Slot 2 ('soap') + Bind "1|default"
|
v
[5. Code-Integritaet einfrieren]
$ bin/TLS-app-scan.bash write
| -> Schreibt SHA-256 ueber alle .php/.sh/.sql nach /var/lib/tlsgate/app.manifest
| -> TLS-node-doktor.bash prueft ab jetzt bei jedem Lauf auf Drift!
Prozesskette B: Login & Sitzungs-Uhrwerk (Warum kein Code doppelt zÀhlt)
Browser (KrĂŒmel / Crew) PHP-FPM (Auth.php / Totp.php) MariaDB (tlsgate_app)
----------------------- ----------------------------- ---------------------
1. POST /login.php (E-Mail + PW) ------> ipBlocked()? (max 10 Fails / 15m) ---------> SELECT count(*) FROM login_attempts
SELECT user WHERE email = ? ---------------> (Falls unbekannt: Argon2id gegen
password_verify() (Constant-Time) dummyHash() rechnen -> kein Timing!)
|
+-- session_regenerate_id(true)
+-- $_SESSION['tg_pending'] = {uid, ts}
|
2. POST /login.php (6-stelliger TOTP) -> Ăffnet totp_secret_enc mit:
Slot 1 ('totp') + Bind "user:<uid>"
PrĂŒft 30s-Zeitschritt ($step > totp_last_step)
|
+-- ATOMARES UPDATE (Patch AUD-02): -------> UPDATE users
| Verhindert Race-Condition bei SET totp_last_step = $step ...
| doppeltem Request in derselben ms! WHERE id = ?
| AND (totp_last_step IS NULL
| OR totp_last_step < $step)
+-- rowCount() === 1 ?
| JA -> session_regenerate_id(true)
| Cookie: __Host-tlsgate (Strict)
| Audit::log('auth.login', 'ok') -> INSERT INTO audit_log (Append-Only!)
| NEIN -> Audit::log('replay_race')
Prozesskette C: Der Spiegel-Abgleich (NetBox & Registrar â Fail-Closed)
Sowohl im RZ als auch vor einem Offline-Einsatz zieht TLS-Gate den echten Zustand in lokale Spiegel-Tabellen. FĂ€llt drauĂen das Netz aus, wird niemals mit Fake-Daten ĂŒberschrieben:
[Upstream: NetBox API / SOAP API]
|
| 1. Holt Live-Daten (Strikte Timeouts: 15s Connect / 20s HTTP, kein Redirect-Follow)
v
[Normalisierer: NetBoxClient::normalize() / Inventory::normalize()]
|
| 2. Reine Funktion (Pure Function): PrĂŒft Schema-Vertrag
| Fehlt ein Pflichtfeld oder ist source === 'unavailable'?
| ---> SOFORTIGER ABBRUCH (Kein DB-Write, alter Spiegel bleibt intakt!)
v
[Sicherheits-Sicherung (Circuit Breaker)]
|
| 3. Hat die Liste >= 2000 Zeilen (Paging-Grenze)? ---> ABBRUCH!
| 4. Sind > 50% der bekannten GerÀte plötzlich weg ---> ABBRUCH!
| (bei Bestand >= 10, ohne --force)? (Schutz vor halber API-Antwort)
v
[MariaDB Transaktion: BEGIN ... COMMIT]
|
+-- Neue EintrÀge -> INSERT + Event 'new'
+-- GeÀnderte EintrÀge -> UPDATE + Event 'changed' (mit altem -> neuem Wert als JSON)
+-- Verschwundene -> SET gone_at = NOW() + Event 'gone' (Nichts wird stumm gelöscht!)
+-- ZurĂŒckgekehrte -> SET gone_at = NULL + Event 'back'
Prozesskette D: Die unabhĂ€ngige Container-CA im Wald (Offline-First Ăberlebensmodus)
Das ist der gröĂte architektonische Vorteil eures Entwurfs:
Ein Crumbforest-Container (unter der BrĂŒcke, im Wald oder als Pelicase im Feld) hat seine eigene lokale CA fĂŒr seine lokale Sensorik (snakeview, rattlecam, crumbzero00/01, ESP32, lokales Ollama/Qdrant).
Er muss nicht im Internet sein, damit Sensoren, lokale Web-Tools und das lokale RAG sicher (mTLS / HTTPS / signierte Receipts) miteinander sprechen und Kinderfragen mit vollem lokalem Kontext beantworten können!
+=========================================================================================+
| PHASE 1: DER CONTAINER IST OFFLINE IM WALD (AUTARKER BETRIEB) |
+=========================================================================================+
[KrĂŒmel / Terminal / Browser im Raum]
|
| Frage: "Wie funktioniert der Regenbogen-Sensor?" / Lokale Pose-Daten
| (Verbindung lokal ĂŒber Container-CA gesichert â KEIN Internet nötig!)
v
+---------------------------------------------------------------------------------+
| LOKALER CONTAINER-KNOTEN (z. B. crumbdesktop / Baumhaus / Pelicase) |
| |
| 1. LOKALE CONTAINER-CA (Slot 4: 'ca') |
| - Signiert lokale TLS-/Sensor-Zertifikate (snakeview, rattlecam, zero00) |
| - PrĂŒft GerĂ€te gegen den letzten lokalen `netbox_devices`-Spiegel |
| |
| 2. LOKALES GEDĂCHTNIS & INFERENZ (questions-core / KernelCrumb / Ollama) |
| - Beantwortet Fragen SOFORT aus lokalem Qdrant-Vektorraum & Rinden |
| - Kein Cloud-Call, keine API-Kosten ("Die 1 verliert, die 0 gewinnt") |
| |
| 3. LOKALE APPEND-ONLY SPUR (outbox / inbox.rs / receipt.rs / audit_log) |
| - Jede lokale Zertifikats-/Missions-Quittung wird lokal mit Zeitstempel |
| und Hash in die Append-Only-Outbox geschrieben (versiegelt mit Slot 3). |
+---------------------------------------------------------------------------------+
|
| (Stunden, Tage oder Wochen vergehen offline im Wald...)
v
+=========================================================================================+
| PHASE 2: WIEDERVERBINDUNG (WIRE-GUARD TUNNEL ZUM NULLFELD STEHT) |
+=========================================================================================+
|
| WireGuard-Handshake (10.42.0.x <-> 10.42.0.1 nullfeld / RZ)
| (Wichtig: Client-initiiert! Der Container meldet sich, das Nullfeld ruft nie)
v
+---------------------------------------------------------------------------------+
| SYNCHRONISATION & BRĂCKENSCHLAG (Delta-Abgleich) |
| |
| A. Container ---> Nullfeld / RZ: |
| - Schiebt signierte Quittungen (Receipts / Outbox-Events / Tagesrinden) |
| - Keine Roh-Videos/Bewegungsdaten (Passkante hÀlt Privates lokal im Raum!) |
| |
| B. Nullfeld / RZ ---> Container: |
| - Liefert frischen NetBox-Device-Spiegel (`netbox_devices`) |
| - Liefert aktualisierte Public-Cert-BĂŒndel (`CertBundle`) falls nötig |
| - Liefert neue Qdrant-Snapshots / Katalog-StÀnde |
+---------------------------------------------------------------------------------+
|
v
[Tunnel kann jederzeit wieder gekappt werden -> Container lÀuft nahtlos weiter!]
4. Von PepperPHP zu CrabbyRust: Warum der Ăbergang jetzt glasklar ist
Weil ihr in TLS-NativePHP_v1 bereits auf jede Framework-Magie verzichtet habt, entspricht jedes Bauteil im PHP-Core heute schon 1:1 seinem kĂŒnftigen GegenstĂŒck im Rust-Kern (OZM_Nullfeld_v1):
+--------------------------------------+ +-----------------------------------------------+
| HEUTE: TLS-NativePHP_v1 (PepperPHP) | ===> | MORGEN: Nullfeld / Rust-Core (CrabbyRust) |
+--------------------------------------+ +-----------------------------------------------+
| Secrets.php (tg1: + Libsodium KDF) | 1:1 | Gleiche Bytes! libsodium-sys / chacha20poly |
| Guard::decide() (Pure Function) | 1:1 | Passkante / runner.rs Gate |
| database/order_states.json | 1:1 | #[derive(Deserialize)] enum OrderState |
| audit_log + Event-Trigger (MariaDB) | 1:1 | inbox.rs (Single-Writer) + receipt.rs |
| bin/tg + bin/*_cli.php | 1:1 | Ein einziges statisches Rust-Binary (clap) |
| public/*.php + SslController | 1:1 | axum-Router + askama-Templates (gleiche CSP) |
| deploy/node/bend.sh (Restore-Beweis) | 1:1 | Bleibt das ehrliche Ops-Fundament auf der Node|
+--------------------------------------+ +-----------------------------------------------+
Merksatz fĂŒr alle KrĂŒmel & kĂŒnftigen Sessions:
Warum scheint es auf den ersten Blick kompliziert?
Weil hier nichts unter den Teppich gekehrt wird. Kein Docker-Container, der heimlich Root-Rechte mischt; keine Cloud, die heimlich SchlĂŒssel verwaltet; kein Sync, der bei halber Leitung heimlich Daten löscht.
Jeder SchlĂŒssel kennt seinen Zweck (Slot 1..5), jede Zeile kennt ihre Gruppe (Associated Data), und jeder Container im Wald bleibt auch ohne Internet ein vollstĂ€ndiger, geschĂŒtzter Denkraum. đČđŠđđŠ
5. Der mögliche Rust-Build (tlsgate-core): Wurzelschutz an Tor, TĂŒr, BrĂŒcke, Baum â und Bugsy đ
âEin KrĂŒmel wandert offline durch den Wald. Bugsy, der ErzĂ€hler, FunkFox, DeepBit und die KrĂŒmeleule. Verbinde dich mit deinem FuĂabdruck â kein Passwort brĂŒllen, dein FuĂabdruck ist nur deiner.â
â aus dem Hörraum (branko.de/hoerraum)
Wenn wir den kommenden Rust-Build (tlsgate-core) im Stil von OZM_Nullfeld_v1 (questions-core + missions-core) planen, geht es nicht einfach darum, PHP-Dateien in .rs-Dateien zu ĂŒbersetzen. Es geht um Wurzelschutz:
* Wo steht das Tor (Firewall / WireGuard)?
* Was ist die TĂŒr (Passkante / Auth / TOTP / FuĂabdruck)?
* Wie trĂ€gt die BrĂŒcke (zwischen nullfeld, backbone, Container-CA und OZM-Museum)?
* Wie bleiben der Baum & seine Wurzeln (lokales Qdrant, lokales pgvector, lokales Ollama, gebunden an echte MAC- & IP-IdentitĂ€ten) geschĂŒtzt?
* Und welche Rolle spielt Bugsy (đ), der einfache KĂ€fer auf der alten BrĂŒcke?
5.1 Die Wald-Anatomie im Rust-Build: Tor · TĂŒr · BrĂŒcke · Baum · Bugsy
+=========================================================================================+
| DIE 5 ELEMENTE DES WURZELSCHUTZES IM RUST-BUILD |
+=========================================================================================+
[1. DAS TOR] --> firewall_hardening.rs + WireGuard (wg0)
"Die Firewall steht VOR allen Diensten."
Kein offenes Qdrant (6333), kein offenes Postgres (5432), kein offenes
Ollama (11434) ins Internet. Die TĂŒr ist der Tunnel, nicht die Hoffnung.
[2. DIE TĂR] --> auth.rs + passkante.rs + totp.rs ("Dein FuĂabdruck ist nur deiner")
Wer klopft an? Mensch (Argon2id + atomarer TOTP-Step) oder
Maschine/Zero/Sensor (MAC + WireGuard-IP + Container-CA-Zertifikat).
[3. DIE BRĂCKE]-> ozm_bridge_protocol.rs + receipt.rs ("Bugsy auf der alten BrĂŒcke")
Verbindet Container-CA (Waldmitte) <-> Nullfeld <-> OZM-Museum.
Gesetz 3: Keine Profile, kein Rohdaten-Abfluss. Nur signierte
Quittungen (Receipts), Rinden und Resonanz-Signale ĂŒberqueren den Fluss.
[4. DER BAUM] --> Die zwei Vektor-GedÀchtnisse + Lokale Stimme/Inferenz (Wurzelwerk)
- Wurzel A (nullfeld): Qdrant (`docs_crumbforest`) + MariaDB
- Wurzel B (backbone): PostgreSQL + `pgvector` (`forest_memory`)
- Wurzel C (Lokal/M4/Container): Ollama (`nomic-embed-text` / `gemma`)
+ Hörraum-Stimmen (offline geklont auf dem M4, 0 Cloud-Bytes).
[5. BUGSY đ] --> bugsy_probe.rs ("Zeig mal, wir schauen gemeinsam")
Ein einfacher, kleiner KĂ€fer (Read-Only Diagnose-Daemon / CLI-Inspector).
Er hat KEINE Schreibmacht, keine Root-Keys, kein `DROP TABLE`.
Er krabbelt ĂŒber Tor, TĂŒr, BrĂŒcke und Wurzel und meldet leise:
"Etwas reibt leicht â MAC in NetBox fehlt / Cert lĂ€uft in 9 Tagen ab /
Qdrant-Collector hinkt 1 Push hinterher."
5.2 MAC / IP / Vektor-Topologie im VPN (Wer lebt wo im Rust-Plan?)
Damit im VPN und in den lokalen RÀumen niemand raten muss, bindet der Rust-Build jede Vektor-Wurzel und jeden KI-Dienst hart an seine Loopback- oder WireGuard-/LAN-IdentitÀt (IP + NetBox-MAC) (dcim/mac-addresses/ -> netbox_devices-Spiegel):
+=========================================================================================+
| VPN- & LOKAL-NETZPLAN: VEKTOREN, OLLAMA & CA-BINDUNG (MAC / IP) |
+=========================================================================================+
+-------------------------------------------------------------------------------------+
| KNOTEN 1: NULLFELD (WireGuard-Hub `10.42.0.1` / `194.164.194.191`) |
| Rolle: Der gesprĂ€chige KrĂŒmel-Chat & Gitea-Ursprung |
|-------------------------------------------------------------------------------------|
| * WireGuard `wg0` : 10.42.0.1/24 (Port 51820/udp â DAS TOR) |
| * Qdrant (Vektor 1) : 127.0.0.1:6333 (NUR lokal / Tunnel! Collection: |
| `docs_crumbforest`, gespeist aus lokalem Gitea-Bare) |
| * MariaDB (TLS-Gate): 127.0.0.1:3306 / Unix-Socket (`tlsgate_app`) |
| * questions-core : 127.0.0.1:8443 -> spricht plain-HTTP im geschĂŒtzten |
| (Rust/Axum) Tunnel/Loopback mit Qdrant & Ollama (kein TLS-Ballast im WG) |
+-------------------------------------------------------------------------------------+
^
| WireGuard-BrĂŒcke (10.42.0.x)
v
+-------------------------------------------------------------------------------------+
| KNOTEN 2: BACKBONE (`87.106.12.97` / Alias: strato-eins) |
| Rolle: Das ACID-GedÀchtnis der Personas & Checkmk-WÀchter |
|-------------------------------------------------------------------------------------|
| * PostgreSQL+pgvector: 127.0.0.1:5432 -> DB `crumbforest_db`, Tabelle |
| (Vektor 2) `forest_memory` (Personas: DeepBit, FunkFox, CapaciTobi...) |
| * Grundsatz : Strikt getrennt von nullfeld-Qdrant! (`zwei-vektor- |
| gedaechtnisse.md` â niemals auf nullfeld psql suchen!) |
+-------------------------------------------------------------------------------------+
^
| Client-initiierter Sync (Zero/Container ruft)
v
+-------------------------------------------------------------------------------------+
| KNOTEN 3: WALD-CONTAINER / BAUMHAUS / CREW-KISTEN (Lokal & Offline-First) |
| (`crumbdesktop` 10.42.0.52 | `m4-laptop` 10.42.0.10 | `cruncher` 192.168.1.10 |
| `snakeview` 192.168.1.180 | `deepsea` 192.168.1.202 | `crumbzero00/01`) |
|-------------------------------------------------------------------------------------|
| * IdentitÀts-Anker : (device_id, primary_ip, primary_mac_address) aus |
| lokalem `netbox_devices`-Spiegel + Container-CA-Cert! |
| * Lokales Ollama : 127.0.0.1:11434 (`nomic-embed-text` 768d, `gemma:2b`) |
| * Lokales Qdrant : 127.0.0.1:6333 (`KernelCrumb_v0` / `ozmai_chunks`) |
| * Hörraum / Audio : Lokal auf M4 gerendert (Bugsy, Eule, FunkFox, DeepBit) |
| * Lokale Sensorik : Pose-Pipeline / Hailo / MQTT (`cruncher` 192.168.1.10:1883) |
| -> GeschĂŒtzt durch die LOKALE CONTAINER-CA (Slot 4: `'ca'`) |
+-------------------------------------------------------------------------------------+
Warum MAC + IP + CA-Zertifikat zusammengehören (âVerbinde dich mit deinem FuĂabdruckâ)
In einer normalen Cloud zĂ€hlt nur ein Bearer-Token â wer es kopiert, ist drin.
Im Wald (Container & OZM-Museum) prĂŒfen wir dreistufig (Wurzelschutz):
1. Die Spur im Boden (MAC & LAN/WG-IP): Steht das GerÀt (snakeview, cruncher, blackbox, crumbzero00) mit seiner echten Hardware-MAC (dcim/mac-addresses/ in NetBox) und IP im lokalen netbox_devices-Spiegel auf status = active?
2. Der SchlĂŒssel unter der BrĂŒcke (Container-CA / Slot 4): Hat das GerĂ€t ein von der lokalen Container-CA signiertes Client-/Node-Zertifikat, dessen CommonName / SAN exakt zu diesem NetBox-Eintrag passt?
3. Die Passkante (passkante.rs): Selbst mit gĂŒltigem Zertifikat darf ein Kamera-Node (snakeview) niemals Roh-Videos aus dem Container ins RZ schieben â nur Bewegungs-Vektoren im Raum, und ĂŒber die BrĂŒcke nur signierte Quittungen.
5.3 Der konkrete Rust-Workspace: Wie tlsgate-core gebaut wird
Genauso wie OZM_Nullfeld_v1 heute schon questions-core und missions-core unter #![forbid(unsafe_code)], lto = true, strip = true baut, gliedert sich der Rust-Build fĂŒr TLS-Gate + Wald-CA + Bugsy:
tlsgate-rs/ (Cargo Workspace â Edition 2024, unsafe_code = "forbid", 2-4 MB static binary)
|
âââ crates/
| âââ tg-crypto/ # 1:1 BinĂ€r-Zwilling von Secrets.php
| | âââ kdf.rs # Blake2b KDF (context = "TLSGATE1", subkey_id = key_id*100 + slot)
| | âââ aead.rs # XChaCha20-Poly1305 ("tg1:" Format + AD "tg1|<purpose>|<bind>")
| | âââ secret_box.rs # ZeroizeOnDrop Wrapper (ersetzt SoapCredential/NetBoxCredential)
| |
| âââ tg-ca/ # NEU: Die lokale Container- & Museums-CA (Slot 4: 'ca')
| | âââ root_ca.rs # Erzeugt/öffnet lokalen CA-Key (versiegelt mit tg-crypto Slot 4)
| | âââ leaf_cert.rs # Signiert Kurzzeit-Certs fĂŒr Nodes/Sensoren (rcgen / x509-cert)
| | âââ footprint.rs # Bindet Cert an NetBox-(Name, IP, MAC) -> "FuĂabdruck-Beweis"
| |
| âââ tg-mirror/ # Fail-Closed Spiegel (NetBox, Registrar, Vektor-Status)
| | âââ netbox.rs # Zieht Devices + dcim/mac-addresses (mit >50% Mass-Gone Breaker)
| | âââ inventory.rs # SOAP/Registrar-Bestand (mit 2000er Limit-Guard & Paging)
| | âââ vector_sync.rs # PrĂŒft lokalen Stand von Ollama (11434), Qdrant (6333), pgvector (5432)
| |
| âââ tg-gate/ # Tor, TĂŒr & Passkante (Reine Funktionen ohne I/O!)
| | âââ guard.rs # Port von Guard::decide() + Rollen-Matrix (readonly..admin)
| | âââ totp.rs # RFC 6238 TOTP + Atomarer Replay-Schutz (WHERE totp_last_step < $1)
| | âââ passkante.rs # Was darf im Container bleiben, was darf ĂŒber die BrĂŒcke?
| |
| âââ tg-bugsy/ # đ Bugsy: Der einfache KĂ€fer auf der alten BrĂŒcke
| âââ crawl.rs # Read-Only PrĂŒfgang ĂŒber Tor (UFW/WG), TĂŒr (Certs), Baum (Vektoren)
| âââ whisper.rs # Kein LĂ€rm, kein Pager-Panikmodus: "Etwas reibt leicht â schau mal hier"
|
âââ bins/
âââ tg # CLI-Binary (ersetzt bin/tg, bin/*_cli.php, TLS-node-doktor.bash)
âââ tlsgate- daemon # Axum-HTTP/mTLS-Server (ersetzt PHP-FPM Pool hinter Nginx/Apache)
5.4 Bugsy (đ) im Einsatz: Warum ein âeinfacher KĂ€fer" besser schĂŒtzt als ein Wachhund
In klassischen IT-Systemen baut man laute Ăberwachungs-Agenten mit Root-Rechten, die ĂŒberall hineinfassen und bei jedem Wackler rote Alarme feuern (und wenn crumbmaster / der Pi400 oder deepsea wegen geteiltem Strom bewusst ausgeschaltet sind, dreht das Monitoring durch).
Im Crumbforest ist Bugsy (crew.rs: âZeig mal, wir schauen gemeinsamâ / Nullfeld-Reaktion: âEtwas reibt leicht â ich kann es zeigen, wenn du willst.â) der Gegenentwurf:
+-----------------------------------------------------------------------------------------+
| đ BUGSY AUF DER ALTEN BRĂCKE (`tg bugsy` / `tg-bugsy`) |
+-----------------------------------------------------------------------------------------+
| |
| EIGENSCHAFTEN VON BUGSY: |
| 1. Winzig & friedlich : Nur Lese-Rechte (`readonly`), öffnet NIEMALS Slot 2/4/5 Keys. |
| 2. Kennt die Stille : WeiĂ aus dem Spiegel, dass `crumbmaster` (Pi400) oder |
| `deepsea`/`snakeview` (Strom-Wechsel) schlafen dĂŒrfen. |
| Offline != kaputt! |
| 3. Krabbelt 4 Orte ab : |
| |
| [Am TOR] -> Steht `ufw` / `nftables` VOR den Diensten? |
| Lauschen Qdrant (`:6333`), Postgres (`:5432`) und Ollama (`:11434`) |
| wirklich NUR auf `127.0.0.1` / `wg0` (`10.42.0.x`)? |
| |
| [An der TĂR]-> Stimmt `/var/lib/tlsgate/app.manifest` (SHA-256)? |
| Passen die MAC-Adressen im ARP-Tisch der Container-BrĂŒcke zu den |
| eingetragenen `dcim/mac-addresses` im lokalen NetBox-Spiegel? |
| |
| [Auf der -> Wann war der letzte Delta-Abgleich zum `nullfeld`? |
| BRĂCKE] Liegen unversendete Quittungen (`outbox` / `receipt.rs`) bereit? |
| LĂ€uft ein Registrar- oder Container-CA-Zertifikat bald ab? |
| |
| [An der -> Antwortet lokales Ollama (`127.0.0.1:11434`) mit `nomic-embed-text`? |
| WURZEL] Sind die zwei Vektor-GedÀchtnisse sauber getrennt |
| (`nullfeld` = Qdrant `docs_crumbforest` vs. |
| `backbone` = pgvector `forest_memory`)? |
| |
| AUSGABE VON BUGSY (Terminal / Hörraum-Stil): |
| ------------------------------------------------------------------------------------- |
| $ tg bugsy |
| đ [TOR] wg0 (10.42.0.52) steht. Qdrant & Ollama lauschen nur lokal (127.0.0.1). |
| đ [TĂR] Alle 5 SchlĂŒssel-Slots (key_id=1) konsistent. 0 Replay-Races. |
| đ [BRĂCKE] Container lĂ€uft seit 14h autark (offline). 3 Receipts warten geduldig. |
| đ [BAUM] Lokales Qdrant (KernelCrumb) wach. |
| đ [REIBUNG] Etwas reibt leicht: `blackbox` (192.168.1.168) hat im NetBox-Spiegel |
| noch keine primary_mac_address (NetBox 4.x dcim/mac-addresses Gotcha). |
| Zeig mal, wir schauen gemeinsam, wenn du Zeit hast. |
+-----------------------------------------------------------------------------------------+
5.5 Der komplette Lebenszyklus einer Kinderfrage (Vom Hörraum bis zur Wurzel & zurĂŒck)
Zum Abschluss: Warum wir diesen ganzen Aufwand mit PHP-Vorarbeit $\rightarrow$ Rust-Core $\rightarrow$ Container-CA $\rightarrow$ MAC/IP-Spiegel ĂŒberhaupt treiben. Damit genau dieser Weg einer Frage zu 100 % geschĂŒtzt, lokal und frei bleibt:
[Ein Kind im Container / Baumhaus / Hörraum stellt eine Frage]
"Wie merkt sich der Wald eigentlich unsere Geschichten, ohne uns auszuspionieren?"
|
v
+-----------------------------------------------------------------------+
| 1. DIE TĂR (Container-CA & FuĂabdruck) |
| Das Terminal im Raum spricht ĂŒber das lokale Container-Zertifikat |
| (Slot 4 `'ca'`, gebunden an die MAC/IP des Raum-Nodes). |
| Kein fremder Server im Internet sieht, dass gefragt wurde. |
+-----------------------------------------------------------------------+
|
v
+-----------------------------------------------------------------------+
| 2. DIE PASSKANTE (`passkante.rs` / `Guard::decide()`) |
| PrĂŒft: EnthĂ€lt die Anfrage persönliche Daten / Kamera-Rohbilder? |
| Rohdaten bleiben hart im Raum. Nur die reine Frage geht an den |
| lokalen Baum. |
+-----------------------------------------------------------------------+
|
v
+-----------------------------------------------------------------------+
| 3. DER LOKALE BAUM (Ollama `127.0.0.1:11434` + Qdrant `127.0.0.1:6333`)|
| - `nomic-embed-text` berechnet lokal den 768d-Vektor der Frage. |
| - Lokales Qdrant / `pgvector` findet die passende Rinde aus dem |
| `CrumbCodex` und dem `OZM-Keks-Handbuch`. |
| - Bugsy, Eule oder FunkFox antworten (im Hörraum mit den lokal |
| auf dem M4 geklonten Stimmen). |
| - Kosten: 0,00 ⏠· Cloud-AbhÀngigkeit: 0 % · Die 0 gewinnt! |
+-----------------------------------------------------------------------+
|
v
+-----------------------------------------------------------------------+
| 4. DIE ALTE BRĂCKE (Wenn spĂ€ter wieder WireGuard zum Nullfeld steht) |
| Nur eine anonyme, kryptographisch signierte Quittung (`receipt.rs`)|
| oder eine kuratierte Tagesrinde wandert ĂŒber `wg0` (`10.42.0.1`) |
| ins `nullfeld`, damit der gemeinsame Wald weiterwÀchst. |
+-----------------------------------------------------------------------+
6. Die NIS2-/BSI-Erkenntnis: Warum PHP im RZ der König bleibt â und Rust eine reine VPN-/Raum-TUI (#cli) ist
Erkenntnis nach den ersten erfolgreichen Live-Tests gegen die echte DB & dem
backbone_doktor.sh-Check (19.10.2026):
Im Rechenzentrum (RZ) unter BSI-Grundschutz und NIS2 (gerade bei DNS-, Zertifikats- und VPN-nahen Diensten) wirft ein ungewohnterRust + Tokio + Nginx-Proxy-Stack sofort hunderte Compliance- und Zertifizierungsfragen auf.
Ein gehaertetes Native-PHP + Apache + MySQL/MariaDB-Setup dagegen ist auf jedem klassischen UNIX/Linux-Unterbau (Debian, Gentoo, Arch, FreeBSD) seit Jahrzehnten zertifizierbar, vom BSI verstanden und durch dieTLS-Gate-HĂ€rtung (Secrets.php,auth_socket, Append-Only-Trigger, SHA-256-Manifest) auf modernstem Niveau (âNewschool PHP").
Damit klĂ€rt sich auch endgĂŒltig die Frage aus OZM_Nullfeld_v1 (Was ist Server, was ist Host, was ist Client?):
6.1 Die 6 goldenen Gesetze fĂŒr die Rust-App (tg-tui / Raum-CA)
Eine Rust-App wird nicht als öffentlicher Webserver ins RZ gestellt, sondern:
1. Macht nur im Terminal Sinn (#cli / TUI): Ein interaktives, schnelles Terminal-Cockpit (im Stil von lazydocker / ratatui â Weiterentwicklung von bin/tg-dash + Bugsy đ).
2. Darf NUR im VPN / lokalen Raum funktionieren: Bindet ausschlieĂlich auf Loopback (127.0.0.1) oder das WireGuard-/Raum-Interface (10.42.0.x), niemals auf 0.0.0.0 im öffentlichen Netz.
3. Erlaubt NUR bekannte oder gelesene MAC-Adressen: Jedes GerÀt im lokalen Raum muss mit seiner echten Hardware-MAC (dcim/mac-addresses aus dem gelesenen NetBox-Spiegel) bekannt sein. Unbekannte MAC = kein Zertifikat, kein Durchgang.
4. Ist eine eigene CA im lokalen Raum-Netzwerk: Verwaltet die lokale Container-/Museums-CA (Slot 4: 'ca') fĂŒr die lokale Sensorik (snakeview, rattlecam, cruncher, crumbzero00/01, lokales Ollama/Qdrant).
5. Wird ĂŒber die Domain-/VPN-CA bestĂ€tigt: Die Raum-CA ist kein wilder Freiflug, sondern kryptographisch ĂŒber die Domain-/VPN-CA (crumbforest.io / onezeromore.com) rĂŒckbestĂ€tigt.
6. Von auĂen (Internet) komplett unerreichbar: Kein offener Port ins Internet. Der Raum holt sich seinen Spiegel rein lesend (Pull via HTTPS + TLS-Client-Login) aus dem RZ. Null Risiko fĂŒr die VM oder das Bare-Metal im RZ!
6.2 Server · Host · Client: Die endgĂŒltige Rollenteilung (RZ vs. Backbone vs. Wald-Raum)
+=========================================================================================+
| 1. DER SERVER (IM RECHENZENTRUM â BSI / NIS2-KONFORM, PORTABEL: DEBIAN/GENTOO/FREEBSD) |
| Domains: `onezeromore.com` (bereits im RZ) & `crumbforest.io` (externer RZ-Test) |
+=========================================================================================+
| |
| [Apache 2.4 + NativePHP RC1.0 (`TLS-Gate`) + MySQL/MariaDB (`tlsgate_app`)] |
| * Spricht als EINZIGER aktiv SOAP mit dem Registrar (InterNetX/AutoDNS). |
| * HĂ€lt die kanonische DB, das Append-Only `audit_log` und die Domain-Zertifikate. |
| * Bietet nach auĂen NUR eine gehĂ€rtete HTTPS-Kante (mit TLS-Login / mTLS) an, |
| ĂŒber die berechtigte RĂ€ume ihre JSONs / Spiegel-Daten LESEND abholen können. |
| * KEIN Risiko fĂŒr VM oder Bare-Metal im RZ: Vom Container/VPN kommt kein Schreib- |
| durchgriff und kein offener Proxy-Dienst ins RZ hinein! |
| |
| +---> [BORGMATIC ARCHIV ("Alter Wald")] |
| Ein alter Wald wird nie ĂŒberschrieben â er wird von Borgmatic verschlĂŒsselt |
| gepflegt und bleibt NUR LESBAR, solange man den SchlĂŒssel trĂ€gt. |
| Jeder aktive Aufbau ist immer ein frischer, neuer Wald. |
+=========================================================================================+
^
| NUR LESENDE VERBINDUNG (HTTPS + TLS-Login)
| LĂ€dt JSON-Spiegel (Inventar, NetBox, Certs)
| (Kein Schreibzugriff ins RZ!)
|
+============================================|============================================+
| 2. DER HOST / BRĂCKENPFEILER (`backbone` 87.106.12.97 & `nullfeld` 194.164.194.191) |
| GeprĂŒft mit `backbone_doktor.sh` (Debian 12, UFW: 22/80/443, Fail2ban, 9x LE-Certs) |
+=========================================================================================+
| |
| * `backbone` (87.106.12.97): |
| - TrÀgt `crumbforest.io`, `seeds.crumbforest.io` (NetBox), `chat`, `monitor`, `rkl` |
| - HÀlt das ACID-GedÀchtnis (`PostgreSQL + pgvector`). |
| - Hinweis aus Doktor-Lauf: `www.crumbforest.io` (CNAME) & `lynis` File-Integrity |
| (= genau das, was `TLS-app-scan.bash` fĂŒr TLS-Gate bereits löst!). |
| |
| * `nullfeld` (194.164.194.191 / `wg0` 10.42.0.1): |
| - WireGuard-Hub & Gitea-Ursprung + Qdrant (`docs_crumbforest`). |
+============================================|============================================+
^
| WireGuard-VPN (10.42.0.x) + Domain-VPN-CA
| Von auĂen (Internet) NICHT erreichbar!
|
+============================================|============================================+
| 3. DER CLIENT & LOKALE RAUM-WĂCHTER (DIE RUST-APP IM CONTAINER / OZM-MUSEUM) |
| Genau hier (und NUR hier!) lebt das Rust-Binary (`ratatui` / `#cli` lazydocker-UI) |
+=========================================================================================+
| |
| +-----------------------------------------------------------------------------------+ |
| | đŠ RUST TUI (`tg-tui` â im Stil von `lazydocker` fĂŒr die Crew im Raum) | |
| |-----------------------------------------------------------------------------------| |
| | [1: Raum-CA & Certs] [2: Bekannte MACs (ARP <-> NetBox)] [3: RZ-JSON-Spiegel] | |
| | [4: Lokale Vektoren (Ollama/Qdrant)] [5: đ Bugsy Diagnose & Borg-Stand] | |
| +-----------------------------------------------------------------------------------+ |
| | | | |
| v v v |
| [MAC-Gatekeeper] [Lokale Raum-CA (Slot 4)] [Lesender Abruf] |
| PrĂŒft jede lokale Verbindung BestĂ€tigt durch die Zieht per HTTPS + |
| gegen die aus NetBox gelesenen Domain-VPN-CA; stellt TLS-Login die |
| MAC-Adressen (`dcim/mac-addresses`). Kurzzeit-Zertifikate nur aktuellen JSONs |
| Unbekannte MAC -> Blockiert! fĂŒr bekannte Raum-Sensoren aus dem PHP-Core |
| aus (`snakeview`, `zero00`). im RZ. |
+=========================================================================================+
6.3 Wie das lazydocker-artige Rust-Terminal (tg-tui) im Raum aussieht
Statt einer weiteren Web-OberflĂ€che, die man wieder absichern und zertifizieren mĂŒsste, startet die Crew im VPN oder direkt im Container das statische Rust-Binary im Terminal:
+-----------------------------------------------------------------------------------------+
| đČđŠ Crumbforest // OZM Raum-Konsole (tg-tui v0.1) [VPN: wg0 10.42.0.52] [OFFLINE-OK]|
+-----------------------------------+-----------------------------------------------------+
| [1] đïž RZ-Spiegel (Read-Only) | đĄ AKTIVER BEREICH: [2] LOKALE RAUM-CA & MAC-GATE |
| onezeromore.com : OK (TLS) | |
| crumbforest.io : OK (TLS) | Aussteller : Container-CA Waldmitte (Slot 4 sealed) |
| Letzter JSON-Pull: vor 12m | BestĂ€tigt : Domain-VPN-CA (crumbforest.io) â |
| Borgmatic-Wald : 61 StĂ€nde | AuĂenport : KEINER (0.0.0.0 geschlossen) â |
+-----------------------------------+-----------------------------------------------------+
| [2] đ Raum-CA & MAC-WĂ€chter <-- | GERĂT IP MAC (NetBox) CA-ST |
| Bekannte MACs : 18 gelesen | --------------------------------------------------- |
| Aktive Raum-Certs: 7 gĂŒltig | cruncher 192.168.1.10 aa:bb:cc:..:01 â
OK |
| Abgewiesene MACs: 0 | snakeview 192.168.1.180 aa:bb:cc:..:02 â
OK |
+-----------------------------------+ deepsea 192.168.1.202 aa:bb:cc:..:03 đ€ AUS|
| [3] đ§ Lokaler Baum (Wurzel) | crumbmaster 192.168.1.166 aa:bb:cc:..:04 đ€ AUS|
| Ollama (127.0.0.1:11434): ON | crumbzero00 192.168.1.201 aa:bb:cc:..:05 â
OK |
| Qdrant (127.0.0.1:6333) : ON | blackbox 10.42.0.51 (fehlt in NB!) â ïž REIB|
+-----------------------------------+-----------------------------------------------------+
| [4] đ Bugsy (Alte BrĂŒcke) | đ BUGSY SAGT: |
| backbone (87.106.12.97): | "Im RZ lÀuft PHP stabil unter Apache/MySQL (NIS2- |
| - 9/9 LE-Certs gĂŒltig (35-79d)| sauber). Unser Raum hat vor 12 Min. die neuesten |
| - UFW + fail2ban aktiv | JSONs lesend geholt. `www.crumbforest.io` auf |
| - www.crumbforest.io CNAME | backbone zeigt noch auf den Domainnamen statt IP." |
+-----------------------------------+-----------------------------------------------------+
| [r] Read-Only Pull vom RZ [c] Raum-Cert fĂŒr bekannte MAC erneuern [b] Bugsy [q] Ende |
+-----------------------------------------------------------------------------------------+
Fazit dieser Architektur-Entscheidung:
- Im RZ (und auf Strato): Das Native-PHP RC1.0 (
TLS-Gate) auf Apache + MySQL bleibt das produktive, BSI-/NIS2-taugliche Fundament â portabel von Debian ĂŒber Gentoo und Arch bis FreeBSD. Es verwaltet die echten Registrar-SOAP-Calls, den Katalog und die DB. - Zwischen Raum und RZ: Nur eine einzige, lesende HTTPS-Verbindung mit TLS-Login holt die JSON-Spiegel in den Container oder das OZM-VPN. Das RZ-System ist dadurch zu 100 % vor RĂŒckwirkungen aus den Experimentier- und Museums-RĂ€umen geschĂŒtzt.
- Im Wald / Container / VPN: Rust (
OZM_Nullfeld_v1/tg-tui) spielt seine StĂ€rke genau dort aus, wo es unschlagbar ist: als einzelnes, statisches Terminal-Werkzeug (#clialalazydocker) und lokaler Raum-WĂ€chter, der nur bekannte MAC-Adressen reinlĂ€sst, die lokale Raum-CA (bestĂ€tigt durch die Domain-VPN-CA) fĂŒhrt und von auĂen unsichtbar bleibt. - Borgmatic & der ewige Wald: Ein alter Wald wird niemals kaputtgepatcht â solange Borgmatic ihn pflegt und der SchlĂŒssel existiert, bleibt er als Geschichte lesbar, wĂ€hrend daneben immer ein sauberer neuer Wald wachsen darf. đČđŠđ
7. Nach 24 Monden Vision auf dem Parkplatz: ninja.sh, container01.crumbforest.org & die PoliversitÀt
âAuf dem Parkplatz des OZM HAMMERBROOKLYN Exponats stehen zwei 40-FuĂ-Container. Doch sie sind keine leeren HĂŒllen. Sie sind bereits jetzt aktiv, mit derselben schweren TĂŒr wie das OZM HAMMERBROOKLYN Exponat selbst ⊠Hier beginnt die Zukunft â nicht im Kopf, sondern auf dem Parkplatz.â
â Crumbforest â Die PoliversitĂ€t der Zukunft steht schon da
Mit deinem Mondzeit-Script ninja.sh (ninja-dashboard.html), dem Live-Snapshot von backbone und der Rolle von container01.crumbforest.org laufen jetzt alle FĂ€den aus 24 Monden in ein einziges, widerspruchsfreies Bild zusammen.
7.1 Was der ninja.sh-Lauf auf backbone (2026-10-19 17:12:21) beweist
Dein ninja.sh verkörpert exakt dieselbe Philosophie wie TLS-Gate und Bugsy đ:
1. Capability Probing statt Distro-Raten (probe()): PrĂŒft Werkzeuge und Pfade (systemctl vs. rc-service, apt vs. pacman/emerge), nicht Marketing-Namen.
2. Terminal-Selbstschutz (clean()): Filtert Steuerzeichen aus User-Agent und Request-Pfad, damit kein Angreifer ĂŒber Log-Injection das Admin-Terminal kapert.
3. Read-Only + Guardrail (is_self()): Erkennt automatisch deine eigene SSH-IP (77.3.8.154) und alle lokalen Server-IPs (127.0.0.1, 87.106.12.97, 2a02:...), damit man sich im Gefecht niemals selbst aussperrt, und gibt Kommandos nur als Copy-Paste-Vorschlag fĂŒr die 2. Shell aus.
4. Live-Befund auf backbone:
* Load bei 0.11, 27,8 GiB RAM frei, Platte zu 89 % frei, 0 hÀngende SQL-Queries.
* Im Web-Log (0.0 req/s Grundrauschen) sieht man sofort die ĂŒblichen .env/wp-admin-Scanner (34.34.160.116) und die akademischen Security-Scanner der Ruhr-Uni Bochum (winston/finn/goose.softsec.ruhr-uni-bochum.de), die sauber an 401 (397x) und 444 abprallen.
7.2 Physische PrĂ€senz als SchlĂŒssel: Warum container01.crumbforest.org nur von innen aufgeht
Das ist der entscheidende Punkt, der die PoliversitĂ€t auf dem Parkplatz (die zwei 40-FuĂ-Container mit derselben schweren TĂŒr wie das OZM-Exponat) mit der Kryptographie verbindet:
Wer mit dem Raum sprechen will, muss physisch vor Ort sein â durch einen Besuch im Container, im OZM-Museum oder ĂŒber einen dort verbauten Raspi Zero (crumbzero00, crumbzero01). Von auĂen (aus dem offenen Internet) existiert kein Weg hinein.
+=========================================================================================+
| PHYSISCHE PRAESENZ ALS SCHLUESSEL: DER 40-FUSS-CONTAINER AUF DEM PARKPLATZ |
| (`container01.crumbforest.org` â #lokal) |
+=========================================================================================+
[OFFENES INTERNET]
|
x <--- KEIN OFFENER PORT! (Weder HTTP noch SSH noch API von aussen erreichbar)
|
+==========|==============================================================================+
| DIE SCHWERE TUER (Physischer Raum: Container 1 & 2 / OZM Museum / Raspi Zero vor Ort) |
+=========================================================================================+
|
| Besucher / Kind / Crew steht ECHT im Raum (oder Raspi Zero im OZM-Raum)
v
+-------------------------------------------------------------------------------------+
| 1. SCHICHT: HARDWARE-FUSSABDRUCK (ARP / MAC-WĂ€chter <-> Ansible + NetBox) |
| - Ansible funkt mit NetBox (`seeds.crumbforest.io`) und hÀlt die Liste |
| der erlaubten MAC-Adressen (`dcim/mac-addresses`) synchron. |
| - Taucht am Switch / WLAN im Container eine NEUE, UNBEKANNTE MAC-Adresse auf: |
| +---> SOFORT BLOCKIERT (Kein Cert, kein Route-Zugriff) |
| +---> MONITORING -> ALARM (Checkmk / Ninja-Shield / Bugsy đ meldet Fremd-MAC) |
+-------------------------------------------------------------------------------------+
|
| (MAC ist bekannt & in NetBox als Teil des Raums verifiziert)
v
+-------------------------------------------------------------------------------------+
| 2. SCHICHT: `container01.crumbforest.org` (Lokales Tor / TĂŒr / SchlĂŒssel) |
| - Nginx + Rust/Tokio-Proxy + Lokale Raum-CA (`#lokal`) |
| - Stellt die Verbindung zu den lokalen Raumfahrt-/Roboter-Systemen, |
| zum lokalen `ttyd` / `ninja-dashboard` und zum lokalen RAG her. |
| - BestÀtigt durch die Domain-VPN-CA, aber 100% autark lauffÀhig (Offline-First). |
+-------------------------------------------------------------------------------------+
|
| Kind baut Roboter / bewegt Sensor / stellt Frage -> Datenspur entsteht lokal
| Roboter zieht spÀter als Kunst ins OZM-Exponat ein!
v
+-------------------------------------------------------------------------------------+
| 3. SCHICHT: BEIM NĂCHSTEN ONLINE-FENSTER (Client-initiierter Sync zum RZ / Nullfeld)|
| - `container01.crumbforest.org` meldet sich von innen heraus mit seinem Update: |
| +---> Holt lesend neue JSONs / Certs vom PHP-Core im RZ (`onezeromore.com` / |
| `crumbforest.io`) ĂŒber HTTPS + TLS-Client-Login. |
| +---> Schiebt signierte Lern-/Resonanz-Spuren (ohne Personen-Profile!) |
| und falls eine fremde MAC geklopft hat: den Sicherheits-Event. |
+-------------------------------------------------------------------------------------+
7.3 Wie alle Schnipsel aus 24 Monden jetzt ineinandergreifen (#nullfeld)
Wenn man heute auf den Tisch schaut, ist kein einziges Werkzeug mehr ein isoliertes EinzelstĂŒck â jedes hat seinen festen Platz in der Kette:
| Baustein / Schnipsel | Wo er lebt | Welche Aufgabe er in der Gesamt-Architektur erfĂŒllt |
|---|---|---|
TLS-NativePHP_v1 (Apache + MySQL) |
Im RZ (onezeromore.com, crumbforest.io) |
Das BSI-/NIS2-taugliche HerzstĂŒck fĂŒr Domains, Registrar-SOAP, Katalog, Buchungen und versiegelte tg1:-Secrets. |
Borgmatic |
Im RZ / Backup | Pflegt den âalten Wald" verschlĂŒsselt und rein lesbar, wĂ€hrend vorne der neue Wald wĂ€chst. |
Ansible + NetBox (seeds.crumbforest.io) |
Auf backbone $\rightarrow$ alle RĂ€ume |
Single Source of Truth fĂŒr alle Nodes, IPs und Hardware-MAC-Adressen (dcim/mac-addresses). |
backbone_doktor.sh & ninja.sh |
Auf backbone / jedem Linux-Host |
Read-Only Triage & Gesundheits-Spiegel in Echtzeit (mit clean(), is_self() und Copy-Paste-Empfehlungen statt Blindflug). |
container01.crumbforest.org (Rust / Tokio / Nginx + Raum-CA) |
Lokal im 40-FuĂ-Container / OZM-Museum | Die schwere TĂŒr vor Ort: LĂ€sst nur physisch Anwesende / bekannte Raspi-Zero-MACs rein, schlĂ€gt bei fremder MAC sofort Alarm im Monitoring und synchronisiert sich beim nĂ€chsten Online-Fenster selbststĂ€ndig. |
OZM_Nullfeld_v1 & Hörraum |
Auf nullfeld & lokal im Container (M4 / Zeros) |
Das lebendige GedÀchtnis (Qdrant / pgvector / Ollama) und die Stimmen der Crew (Bugsy, Eule, FunkFox, DeepBit), die Kinderfragen ohne Cloud-Kosten beantworten. |
Ansible-Crumbforest-Rust (#local) |
Auf der lokalen Crumbforest Ansible-Node / im Raum | Der neugeschriebene lokale Prozess: Verbindet die belegbar funktionierenden ansible.builtin-Playbooks (cruncher-tlsgate-env, qdrant, ozm-inbox, wurzelsicherung, vpn-hub) mit einem deterministischen lokalen Rust-Controller (crumb-local) ohne Python-.venv/pynetbox-FragilitÀt. |
8. Von Ansible-Crumbforest zu Ansible-Crumbforest-Rust #local (Der neue lokale Prozess)
Nach der Analyse von Ansible-Crumbforest ist klar, was dort auf der Crumbforest Ansible Node belegbar funktioniert â und warum es fĂŒr Ansible-Crumbforest-Rust #local in den neuen lokalen Prozess ĂŒberfĂŒhrt werden muss:
8.1 Warum der alte Prozess (Ansible-Crumbforest) an seine Grenze stieĂ vs. Der neue lokale Prozess (#local)
+=========================================================================================+
| ALT: `Ansible-Crumbforest` (Zentraler Push + Python/.venv + NetBox-API-Spagat) |
+=========================================================================================+
| 1. Control-Node brauchte `.venv/bin/python` + `pynetbox` + `netbox.netbox` (3.23). |
| 2. NetBox 4.2+ / 4.6 Bruch: `mac_address` ist kein Interface-Feld mehr, sondern ein |
| eigenes Objekt (`/api/dcim/mac-addresses/`). Deshalb mussten Playbooks wie |
| `netbox_sync.yml`, `netbox-raspis.yml`, `netbox-vpn.yml` halb `netbox.*`-Module |
| und halb rohe `ansible.builtin.uri`-POSTs mit `jq`/Jinja mischen. |
| 3. `credentials/netbox_api_token` lag als Schreib-Token fĂŒr `seeds.crumbforest.io` |
| im Playbook-Pfad; `tlsgate-test.yml` zeigte noch auf `TLS-Gate-Mock-Pipeline`. |
+=========================================================================================+
|
| Transformation in den neuen lokalen Prozess
v
+=========================================================================================+
| NEU: `Ansible-Crumbforest-Rust` (`#local` â Auf der lokalen Crumbforest Ansible-Node) |
+=========================================================================================+
| 1. DREIKLANG DER WERKZEUGE (Kein `.venv`/`pynetbox`-Krampf mehr!): |
| * đ BASH (`scripts/crumbconnect.sh`, `inventar.sh`, `ninja.sh`, `bend.sh`): |
| Die lesbare Wurzel vor Ort (âComputer ohne Maus/Klick", Capability-Probing). |
| * đ ANSIBLE (`playbooks/*.yml` â NUR `ansible.builtin.*`!): |
| Die auf der Ansible-Node belegbar funktionierenden Host-VertrÀge mit |
| Vorher/Nachher-Gegenprobe (`--check --diff`), die kein fremdes Python-Modul |
| auf den Zielknoten (`cruncher`, `deepsea`, `snakeview`, `zeros`) verlangen. |
| * đŠ RUST (`crumb-local` Binary in `Ansible-Crumbforest-Rust`): |
| Der deterministische lokale WĂ€chter & Orchestrator im Raum: |
| - PrĂŒft `Wenn eine MAC piepst` (`OBSERVED_PHYSICAL_DEVICE` vs. `NETBOX_RECORD`)|
| - Liest den `TLS-Gate` `DeviceMirror` (Read-Only Pull via `tg1:` / mTLS) |
| - Spricht NetBox 4.6 nativ (2-Stufen-MAC-Modell + `/32` WireGuard-Interfaces) |
| - Erzwingt den Tokio-Serialisierungs-Kanon (`1 Writer`, `sync_all()`). |
+=========================================================================================+
8.2 Die 6 belegbar funktionierenden SĂ€ulen aus Ansible-Crumbforest, die in Ansible-Crumbforest-Rust #local ĂŒbernommen werden
Aus dem bestehenden Repo sind diese 6 Playbook-/Script-Ketten der harte, funktionierende Kern, der im neuen lokalen Prozess erhalten und durch das lokale Rust-Binary (crumb-local) zusammengehalten wird:
00_doktor.yml+inventar.yml(Schnecki-Prinzip: Erst lesen, nie blind schreiben):- PrĂŒft Uptime, Disk, RAM,
wg show wg0, UFW, Fail2ban, Gitea, Qdrant, Ollama und sammelt auf allen Linux-KrĂŒmeln (crumbforest+ozm_linux) reale Hardware-, Disk-, RAM-, WG-Pubkey- und MAC-Fakten. 01_vpn_hub.yml+scripts/crumbconnect.sh(Crumbpage 40 â âDie stille TĂŒr"):- Der Node erzeugt sein SchlĂŒsselpaar lokal (
Private Key bleibt im Baum). - Jede VPN-IP im CrumbVPN ist zwingend eine
/32(10.42.0.11/32deepsea,10.42.0.12/32snakeview,10.42.0.19/32cruncher,10.42.0.20/32crumbzero01). Kein Crossconnect vorab! 02_cruncher_tlsgate_env.yml(Die lokale / VPN-Umgebung fĂŒrTLS-NativePHP_v1):- Baut auf
cruncher(10.42.0.19) die exakte RZ-analoge Umgebung ohne Docker und ohne Reboot:- Apache 2.4 (
mpm_event+proxy_fcgi), gebunden nur an127.0.0.1undwg0(10.42.0.19) (mitAfter=wg-quick@wg0.service). - PHP 8.4 FPM (
packages.sury.orggepinnt auf Priority 100/600 + GPG-Fingerprint-PrĂŒfung). - MySQL 8.4 LTS nativ (
mysql-tlsgate.serviceauf127.0.0.1:3306+auth_socket, GPG-verifiziert). - Tag
kette: Ăbernimmt die Vorlagen ausdeploy/node/bend.shaus unseremTLS-NativePHP_v1-Repo und prĂŒft vorher/nachher per Assert, dass das lebende OZM-Exponat (hexapi,mosquitto,influxdb) keine Sekunde unterbrochen wurde!
- Apache 2.4 (
03_cruncher_qdrant_musl.yml+qdrant-abschottung.yml(16K-Page-Heilung & Loopback-Schutz):- Heilt den
jemalloc-SIGABRTauf dem 16K-Page-Kernel (getconf PAGESIZE = 16384) durch das nativeaarch64-unknown-linux-musl-Binary unter eigenem System-Userqdrant, strikt gebunden an127.0.0.1:6333(IPAddressAllow=127.0.0.0/8,IPAddressDeny=any). 04_ozm_inbox_host.yml(Der Host-Vertrag fĂŒr die Rust-Raum-BrĂŒcke):- Legt User
crumb-inbox,/srv/ozm-inbox/{bin,room}, den on-node erzeugtenintegrity_key_v1(0600) und/etc/ozm-inbox/export.envan â strikt gebunden anwg0(10.42.0.19:8790,IPAddressAllow=10.42.0.0/24,ReadOnlyPaths=/srv/ozm-inbox/room). 05_wurzelsicherung.yml(Die Quellen sichern, nicht das Abgeleitete):- Sichert die echten Quellen (
pg_dump -Fcaufbackbone,gitea-repositories+mysqldumpaufnullfeldsowie die maschinen-eigenen Pfade) mitSHA256SUMSĂŒber den lokalen Knoten auf mindestens zwei Ziele inklusive Off-Site (deepseaim OZM) und meldet am Ende ungeschönt die Off-Site-Wahrheit.
8.3 Die komplette lokale Prozesskette in Ansible-Crumbforest-Rust #local (ASCII-Ablauf)
So greifen MAC-Piepsen, Rust-Gatekeeper (crumb-local), Ansible-Host-Vertrag und TLS-NativePHP_v1 auf der lokalen Crumbforest Ansible-Node ineinander:
+=========================================================================================+
| DER NEUE LOKALE PROZESS: `Ansible-Crumbforest-Rust` (#local) |
| Reihenfolge (Crumbpage 40): 1. BASE -> 2. VPN (/32) -> 3. ERINNERN -> 4. BROT |
+=========================================================================================+
[SCHRITT 0: WENN EINE MAC PIEPST (Neues oder bekanntes GerÀt im Raum / Hotspot)]
Axiom 1: IN_HOTSPOT(device) =/=> ACCESS_GRANT(device)
Axiom 2: RESOLVES(name) =/=> REACHABLE(host)
Axiom 3: NETBOX_RECORD(dev) =/=> OBSERVED_PHYSICAL_DEVICE(dev)
|
v
+-------------------------------------------------------------------------------------+
| đŠ 1. `crumb-local mac-gate` (Rust-Binary auf der lokalen Ansible-Node) |
| - Liest lokale Nachbarschaft (`ip neigh` / Bridge / `wg show wg0 dump`) |
| - Vergleicht gegen den lokalen `TLS-Gate` / NetBox-Spiegel (`netbox_devices`): |
| * FALL A: MAC UNBEKANNT -> Kein WG-Peer, kein Cert, sofortiger |
| Monitoring-Alarm (`ninja.sh` / Checkmk / Bugsy đ)! |
| * FALL B: MAC BEKANNT & `status=active` -> Freigabe fĂŒr Schritt 2. |
+-------------------------------------------------------------------------------------+
|
v
+-------------------------------------------------------------------------------------+
| đ 2. `crumbconnect.sh` + `01_vpn_hub.yml` (Die stille TĂŒr â Jede IP ist `/32`) |
| - GerÀt erzeugt lokal `/etc/wireguard/wg0.private` (verlÀsst NIE das GerÀt!). |
| - Ăbergibt nur `PublicKey` + `10.42.0.x/32`. |
| - Lokale Ansible-Node fĂŒhrt `ansible-playbook playbooks/01_vpn_hub.yml --check` |
| und danach scharf aus -> Handshake steht (`latest handshake: now`). |
+-------------------------------------------------------------------------------------+
|
v
+-------------------------------------------------------------------------------------+
| đ 3. HOST-VERTRĂGE AUSROLLEN (`ansible.builtin.*` mit Exponat-Gegenprobe!) |
| - `00_doktor.yml` -> Read-Only Puls vor jeder Ănderung. |
| - `02_cruncher_tlsgate_env.yml` -> Apache (nur 127.0.0.1 + wg0) + PHP 8.4 + |
| MySQL 8.4 + `TLS-NativePHP_v1` (`bend.sh`). |
| - `03_cruncher_qdrant_musl.yml` -> Natives musl-Qdrant (16K-Page safe, Loopback).|
| - `04_ozm_inbox_host.yml` -> `/srv/ozm-inbox` + `integrity_key_v1` (wg0). |
| - Gegenprobe: `hexapi` / `mosquitto` / `influxdb` liefen ohne Unterbrechung! |
+-------------------------------------------------------------------------------------+
|
v
+-------------------------------------------------------------------------------------+
| đŠ 4. TOKIO-KANON & ERINNERN (`crumb-local netbox-sync` & `inbox-verify`) |
| - Statt fragilem Python-`pynetbox` synchronisiert `crumb-local` direkt gegen |
| NetBox 4.6 (2-Stufen-MAC `/api/dcim/mac-addresses/` + `/32` WG-IP) |
| ODER zieht im Air-Gap-Raum den signierten Read-Only JSON-Spiegel aus dem RZ. |
| - FĂŒr jeden Zero-Node gilt der Tokio-Kanon: |
| * Disjunktes `CRUMB_DATA_DIR` pro Instanz (`zero00` != `zero01`) |
| * Genau 1 Tokio-Task besitzt die State-Domain (`inbox + outbox + receipts`) |
| * `DURABLE_LOCAL`: `File::sync_all()` vor jeder HTTP/WG-Quittung! |
+-------------------------------------------------------------------------------------+
|
v
+-------------------------------------------------------------------------------------+
| đ° 5. `05_wurzelsicherung.yml` (Quellen sichern -> 2 Orte + Off-Site `deepsea`) |
| - `pg_dump -Fc` + `gitea-repositories` + `mysqldump` + `SHA256SUMS` |
| - Ehrlicher Schlussbericht: Liegt die Kopie wirklich auĂerhalb des RZ im OZM? |
+-------------------------------------------------------------------------------------+