Architektur
Wie Kastra arbeitet und mit wem es spricht
Eine Control Plane, ein Agent je Node, eine Datenbank als einzige Wahrheit. Das Bild zeigt jeden Baustein und jede Verbindung. Zeige auf einen Baustein oder tippe ihn an, und eine Tafel sagt, was dort läuft, mit wem er spricht und über welches Protokoll.
Verwaltung und Betrieb Besucher einer Domain Daten unterwegs Zeige auf einen Baustein oder tippe ihn an.
Drei Grundsätze, an denen alles hängt
Die Datenbank ist die einzige Wahrheit
Der Node hält keinen eigenen Zustand. Alles unter den verwalteten Verzeichnissen wird aus PostgreSQL gerendert und überschrieben. Ein neu aufgesetzter Node holt alles nach; ein wiederhergestellter auch.
Der Agent ruft an, nicht die Control Plane
Die Verbindung baut der Agent ausgehend auf, über gRPC mit beidseitigem TLS. Auf dem Node muss dafür kein Port offen sein; der private Schlüssel des Agents verlässt den Node nie, beim Anmelden geht nur die CSR hinaus.
Jede Datei trägt den Marker
MANAGED BY KASTRA - DO NOT EDIT in der ersten Zeile, dazu eine Prüfsumme. Alle fünf Minuten vergleicht der Agent; was abweicht, wird überschrieben und gemeldet. Fremde Dateien ohne Marker bleiben unangetastet.
Der Apply-Zyklus
Jede Änderung an einer Domain, einem Postfach oder einer Firewall-Regel geht diesen Weg. Kein Schritt wird übersprungen, nichts wird direkt nach /etc geschrieben.
- 1RendernDer Agent erzeugt die Dateien aus dem Soll-Zustand in ein Staging-Verzeichnis.
- 2Prüfennginx -t, apache2ctl configtest, php-fpm -t, nft -c: ein Fehler stoppt hier.
- 3SichernDie bisherige Fassung wandert in ein Rollback-Verzeichnis.
- 4SchreibenAtomar mit rename(2): entweder die neue Datei liegt da oder die alte.
- 5Neu ladenDer Dienst lädt die Konfiguration, ohne Verbindungen zu verlieren.
- 6AbrufenJede berührte Domain wird lokal aufgerufen, bis zu viermal.
- 7ZurückrollenAntwortet sie nicht, kommt für diese Domain die alte Fassung zurück — mit der Originalausgabe im Fehler.
Isolation je Subscription
Eine Subscription ist die Grenze, die der Node durchsetzt: ein Unix-Benutzer ohne Shell, ein systemd-Slice mit Grenzen für Speicher, CPU, IO und Prozesse, ein PHP-FPM-Pool je Domain mit open_basedir auf das eigene Verzeichnis, eigener Socket, eigenes Upload-Verzeichnis, Disk-Quota über XFS-Projektquota oder ext4-Benutzerquota. Der Webserver liest die Dateien als Gruppenmitglied, nicht über offene Rechte — andere Subscriptions kommen nicht heran. Node.js-Anwendungen, Container ohne Root und Redis laufen im selben Slice.
Was zwischen Control Plane und Node läuft
| Weg | Protokoll | Wofür |
|---|---|---|
| Browser → Panel | HTTPS, WebAuthn | Oberfläche und REST-API, Anmeldung mit Passkey, WebSocket für Terminal und Protokolle |
| Agent → Control Plane | gRPC über mTLS, Port 8444 | Bidirektionaler Strom: Soll-Zustand und Kommandos hin, Ergebnis, Herzschlag, Abweichungen und Messwerte zurück |
| Agent → Control Plane, einmalig | TLS, Port 8445 | Anmeldung mit Bootstrap-Token und CSR; die interne CA stellt das Client-Zertifikat aus. Der Fingerabdruck der CA ist Pflicht |
| Node → Let's Encrypt | ACME, HTTP-01 | Zertifikate je Domain; DNS-01 läuft über die Control Plane und den DNS-Anbieter |
| Node → Sicherungsspeicher | restic über SFTP oder S3, Mount für CIFS und NFS | Sicherung je Subscription, auf Wunsch durch WireGuard |
| Control Plane → kastra.softwelop.com | HTTPS, täglich | Versionsauskunft je Kanal; das Update selbst holt der Agent per apt aus dem signierten Repository |
Fehler haben eine Form
Jede Fehlerantwort trägt einen Code, eine deutsche Meldung mit der Auswirkung — was jetzt gilt —, einen Hinweis, wenn sich etwas tun lässt, und die unveränderte Originalausgabe des Systembefehls. Wenn nginx eine Zusatzkonfiguration ablehnt, steht die Zeile aus nginx -t im Panel, und der Editor markiert sie. Keine nackten Statuscodes, keine Stacktraces.
Woraus es gebaut ist
| Teil | Technik |
|---|---|
| Control Plane | Spring Boot 4.1, Java 21, PostgreSQL 16, Flyway, gRPC |
| Agent und kastractl | Go 1.26, ein statisches Binary, Systemaufrufe nur mit Zeitgrenze |
| Oberfläche | Angular 22, Material 3, Signals, eigener Icon-Satz, Handbuch im Panel |
| Contract | Protobuf 3, proto/kastra/v1 — jede Änderung beginnt dort |
| Auslieferung | Debian-Pakete aus einem signierten apt-Repository, Selbstupdate mit Bestätigung, Rollout Node für Node |
| Prüfung | 75 Reihen nachts auf der Testanlage, Testmatrix über Debian 12, 13 und Ubuntu 22.04, 24.04 in Incus |