- PHP 48.3%
- Shell 24.9%
- Dockerfile 18.8%
- Makefile 8%
|
|
||
|---|---|---|
| .forgejo/workflows | ||
| .github | ||
| docker | ||
| docs | ||
| server | ||
| .dockerignore | ||
| .editorconfig | ||
| .gitignore | ||
| Caddyfile | ||
| CHANGELOG.md | ||
| CONTRIBUTING.md | ||
| docker-compose.yml | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| lionbackup.yaml.example | ||
| Makefile | ||
| openapi.yaml | ||
| README.md | ||
| SECURITY.md | ||
| test_lionbackup.sh | ||
| VERSION | ||
lionbackup-client
Ein einziges Go-Binary mit vier Modi: Schlüssel erzeugen, lokal verschlüsseln, hochladen, wiederherstellen.
| Aufruf | Was passiert |
|---|---|
--generate-key / --keygen |
Post-Quantum-Schlüsselpaar erzeugen und beenden |
--compress-only / --encrypt-only |
Quellen verschlüsseln (.lbk), nicht hochladen |
--autotune |
Kompressionsverfahren vergleichen und das optimale empfehlen |
| (kein Modus) | Verschlüsseln + Chunk-Upload an genau einen Server (Ziele aus environment, mit Failover) |
--restore <file_id> |
Datei holen, prüfen, entschlüsseln, entpacken |
--list |
Auf den Servern verfügbare Backups auflisten |
--help gibt den vollständigen Hilfetext aus. Weitere Flags: --key-name,
--output, --target, --quiet, --verbose, --debug, --progress-bar.
Weitere Dokumentation:
docs/user-guide.md— ausführliche Benutzerdokumentation (Deutsch)docs/security-concept.md— Sicherheitskonzept (English)SECURITY.md— Vulnerability-Reporting-Policy
Datei-Format: explizite Hybrid-Verschlüsselung
.lbk-Datei:
┌──────────────────────────────────────────────────────────┐
│ "LIONBKP1" │ ver │ hdrLen │ age-verschlüsselter Header │ asymmetrisch (KEM)
├──────────────────────────────────────────────────────────┤
│ 32-Byte-DEK │ JSON-Metadaten │ ← nur DEK ist asym
├──────────────────────────────────────────────────────────┤
│ Chunk 0 │ Chunk 1 │ … │ Chunk N (isLast) │ symmetrisch (DEM)
└──────────────────────────────────────────────────────────┘
Chunk = [len|nonce|ciphertext+tag]
- KEM: age (X25519 + ChaCha20-Poly1305) verschlüsselt ausschließlich einen frisch erzeugten 32-Byte-DEK und einen JSON-Metadaten-Block.
- DEM: XChaCha20-Poly1305, 64 KiB Klartext-Chunks, je 24-Byte-Nonce zufällig. AAD pro Chunk =
chunk_index (uint64 BE) || isLast (1 byte)— damit kippen Reordering- und Truncation-Versuche als AEAD-Fehler aus.
Der private Schlüssel sieht nur den DEK, niemals direkt die Nutzdaten.
Kompression (vor der Verschlüsselung)
compression_method in der Config:
| Methode | Threads | Hinweis |
|---|---|---|
ZSTD |
multi-threaded | bestes Verhältnis Tempo/Rate, empfohlen |
GZIP |
multi-threaded (pgzip) |
breit kompatibel, Standard-gzip-Format |
LZMA2 / XZ |
single-threaded | höchste Rate, aber langsam |
Die Parallelität nutzt runtime.NumCPU() Kerne. Beim Restore wird die Methode automatisch am Magic der dekomprimierten Daten erkannt (gzip 1f 8b, zstd 28 b5 2f fd, xz fd 37 7a 58 5a 00) — die Metadaten werden dafür nicht benötigt.
- Die Zielserver ergeben sich aus der Zielumgebung (
environment+storagezone, siehe unten). Die Liste wird beim Start zufällig permutiert (Lastverteilung über viele Clients). - Beim Backup wird lazy genau ein Server gewählt: der erste der (zufällig sortierten) Liste, der
GET /healthmit 200 beantwortet, wird zum aktiven Server. Die übrigen Server werden dabei nicht geprüft. Übersprungen wird ein Kandidat bei jeder Fehlerklasse (dns:no such host,net:dial,timeout,http_5xx/4xx). - Die Datei wird an genau diesen einen Server übertragen. Fällt er während der Übertragung aus, wird der nächste Server geprüft (Failover) und die Datei dort vollständig (in Chunks) neu übertragen.
- Existiert kein erreichbarer Server (z. B. weil keiner der Hostnamen auflöst), bricht der Client mit einer klaren Fehlermeldung ab (Exit ≠ 0).
- Beim Restore/
--listwerden die Server abgefragt, bis die gesuchte Datei gefunden ist bzw. der Katalog steht (eine Datei liegt clientseitig auf genau einem Server, da die Replikation serverseitig erfolgt).
Zielserver: environment & storagezone
Die Backup-/Restore-Ziele werden aus der Config abgeleitet:
environment |
Ziele | Transport |
|---|---|---|
localhost |
http://localhost:8080, :8081, :8082 |
HTTP (kein TLS) |
dev / test / prod |
c0..c49.<storagezone>.<environment>.lionbackup.cloud |
HTTPS |
environmentist weglassbar; Default istprod.- Für
dev/test/prodwirdstoragezoneim Format<ISO-Land><Region>-<AZ>benötigt, z. B.de01-1→c0.de01-1.dev.lionbackup.cloud,it02-7→c32.it02-7.prod.lionbackup.cloud. - Der Ländercode muss ein europäischer ISO-3166-Alpha-2-Code sein (de, it, fr, es, …); andernfalls bricht der Client mit Fehler ab.
localhostzielt auf das lokale Test-Compose (drei Server hinter Caddy, unverschlüsselt) — siehedocs/test-server-compose.md.- Per CLI überschreibbar:
--environment dev --zone de01-1. - Optionaler Override: eine explizite
servers:-Liste in der Config hat Vorrang.
Sicherheit & Verfügbarkeit
- Post-Quantum-Schlüssel: Neue Schlüssel sind ML-KEM-768 + X25519 (Hybrid). Bestehende X25519-Schlüssel funktionieren weiter.
- Authentifizierung:
tokenwird alsAuthorization: Bearergesendet; der Server erzwingt es bei Start mitAUTH_TOKEN./healthbleibt offen. - Transport:
dev/test/prodnur über HTTPS;localhostüber HTTP. - Upload-Ziel & Failover: Jede Datei wird an genau einen Server übertragen. Fällt dieser während der Übertragung aus, wechselt der Client auf den nächsten gesunden Server und überträgt die Datei dort vollständig (in Chunks) neu. Die Replikation über mehrere Standorte erfolgt serverseitig.
Details im Sicherheitskonzept docs/security-concept.md,
Bedienung in docs/user-guide.md.
Server-API (OpenAPI)
Das Gegenstück (Storage-Server) ist OpenAPI-3.1-kompatibel. Die vollständige
Spezifikation liegt unter openapi.yaml und wird vom Server
zusätzlich unter GET /openapi.yaml ausgeliefert (ohne Token abrufbar). Sie
beschreibt alle Endpunkte: /health, /upload, /list, /status/{file_id},
/download/{file_id} samt Auth, Schemata und Response-Headern. Damit lassen
sich Clients, Mock-Server und Tests generieren.
Optimale Kompression finden (--autotune)
lionbackup-client --autotune --config lionbackup.yaml
Führt für jede Quelle alle Verfahren (ZSTD, GZIP, LZMA2) einmal aus und gibt eine Vergleichstabelle aus – Ausgabegröße, Kompressionsrate, Laufzeit und Durchsatz – plus eine Empfehlung (bestes Verhältnis aus Größe und Zeit). Es findet weder Verschlüsselung noch Upload statt.
Bestandteile
.
├── cmd/lionbackup-client/ # Client (Go): main.go, keys_pq.go, keys_legacy.go
├── server/ # PHP-Mock-Server (Test) + Dockerfile + Spec-Kopie
├── docs/ # Sicherheitskonzept, Benutzerdoku, Compose- & Release-Doku
├── openapi.yaml # kanonische OpenAPI-3.1-Spezifikation
├── Caddyfile # Reverse-Proxy fürs Test-Compose (8080/8081/8082, HTTP)
├── docker-compose.yml # NUR Client-Entwicklung: c0/c1/c2 + Caddy + Build-Profile
├── go.mod
├── lionbackup.yaml.example
├── Makefile
└── .github/workflows/ # ci.yml (Tests) + release.yml (Linux/Windows-Releases)
Lokal testen (Test-Compose)
Hinweis: Das Compose-Setup ist ein Mock-Server nur für die Client-Entwicklung – nicht der echte lionbackup-Server. Details und Disclaimer:
docs/test-server-compose.md.
# Drei Mock-Backends (c0/c1/c2) hinter Caddy starten; Caddy bietet 8080/8081/8082 (HTTP)
docker compose --profile server up -d --build
curl http://localhost:8080/health # -> {"status":"ok","server":"c0"}
# Client bauen (oder via 'make build')
docker compose --profile build up build-linux
BIN=./dist/linux/lionbackup-client
# E2E-Test
./test_lionbackup.sh
Passende Client-Config: environment: localhost (zielt auf die drei lokalen
HTTP-Server). Beispiel siehe docs/test-server-compose.md.
DNS-/Failover-Verhalten
- Nicht auflösbare Hosts: In
dev/test/prodexistieren nur die real bereitgestelltencN-Hostnamen. Bei der Backup-Serverwahl werden die (zufällig sortierten) Kandidaten der Reihe nach geprüft, bis einer gesund ist; nicht auflösbare Hosts (dns:no such host) werden dabei übersprungen. Existiert kein erreichbarer Server, bricht der Client klar ab (Exit ≠ 0). - Ausfall im Betrieb: Im lokalen Setup lässt sich Failover testen, indem man
ein Backend stoppt (
docker compose stop c1) oder es über die Marker-Dateiuploads/c1/.unhealthyauf/health 503zwingt.
Config-Beispiel
Siehe lionbackup.yaml.example. Die Zielserver
ergeben sich aus environment/storagezone (siehe oben); eine explizite
servers:-Liste ist als Override möglich.
Pfad-Validierung
- Auf Linux: Quellpfade dürfen kein
\und keinC:-Prefix enthalten. - Auf Windows: müssen Windows-Format haben.
- Beim Restore: tar-Einträge mit
..oder absoluten Pfaden werden abgewiesen, Symlinks außerhalb--targetwerden übersprungen.
Build ohne go.sum
Das Repo enthält bewusst keine go.sum. Der Docker-Build nutzt -mod=mod und ergänzt die Hashes zur Build-Zeit. Für reproduzierbare Builds einmalig lokal:
go mod tidy && git add go.sum
Versionen & Sicherheit (Stand Juni 2026)
Aktuell gepinnte Versionen:
| Komponente | Version |
|---|---|
| Go (Build-Image) | 1.26 |
| filippo.io/age | v1.3.1 |
| github.com/klauspost/compress (zstd) | v1.18.6 |
| github.com/klauspost/pgzip | v1.2.6 |
| github.com/ulikunitz/xz | v0.5.15 |
| go.yaml.in/yaml/v3 | v3.0.4 |
| golang.org/x/crypto | v0.52.0 |
| PHP (Server-Image) | 8.4 |
Hinweise:
ulikunitz/xzwurde wegen CVE-2025-58058 (DoS beim Dekomprimieren, behoben in v0.5.14) auf v0.5.15 gehoben.gopkg.in/yaml.v3ist archiviert; ersetzt durch den gepflegten Forkgo.yaml.in/yaml/v3.- age v1.3 bietet einen Post-Quantum-
HybridRecipient(ML-KEM-768 + X25519). Da nur der DEK gewrappt wird, lässt sich das ohne Formatänderung am Body nachrüsten.
Vor jedem Release empfohlen:
go mod tidy
go build ./...
go vet ./...
govulncheck ./... # Schwachstellen-Scan gegen die Go-Vuln-DB
Releases
Versionierung nach SemVer, Start bei 0.1.0. Ein Tag vX.Y.Z löst den
Workflow .github/workflows/release.yml aus,
der den Client für Linux (amd64, arm64) und Windows (amd64) baut, die
Versionsnummer einbrennt und die Artefakte samt SHA-256-Summen an ein
GitHub-Release hängt:
git tag -a v0.1.0 -m "lionbackup-client 0.1.0"
git push origin v0.1.0
lionbackup-client --version gibt die eingebrannte Version aus. Details:
docs/releasing.md.
Mitwirken
Siehe CONTRIBUTING.md. Kurz:
go mod tidy
make check # gofmt, vet, spec-check, php-lint
make test
Sicherheitslücken bitte vertraulich melden – siehe SECURITY.md.
Lizenz
MIT © 2026 lionbackup authors. Den Copyright-Inhaber vor der Veröffentlichung anpassen.