Initial commit

This commit is contained in:
Codex
2026-01-23 11:12:31 +01:00
commit 0c420a8697
27 changed files with 1767 additions and 0 deletions

158
SPEC.md Normal file
View File

@@ -0,0 +1,158 @@
# Backup Orchestrator (Windows Client + Proxmox Server)
## Sommario esecutivo
- Client Windows PySide6 con selezione cartelle, log/progresso e switch di schedulazione chiama API FastAPI sul server.
- Server Proxmox esegue un job che, tramite SSH verso lhelper OpenSSH del client, avvia un `rsync` pull verso `/srv/backup/current`, mantenendo una history di 20 versioni.
- Infrastruttura hardening: HTTPS, SSH, least privilege, logging strutturato, retention/lock e opzioni per compressione e task scheduling.
## Requisiti principali
### Funzionali
1. Il client permette di taggare 1+ cartelle per backup e abilita il bottone “Esegui” solo quando la selezione è valida.
2. Il pulsante invia credenziali SSH (utente/password) e percorsi al backend FastAPI.
3. Il server connette via SSH al client e lancia `rsync` con `--backup --backup-dir=/srv/backup/.history/<run_id>` e senza `--delete` (pull incrementale).
4. Non si propagano cancellazioni lato client; i file eliminati restano disponibili in `/current` o nello storico.
5. Mantiene fino a 20 esecuzioni storiche per file sovrascritti, archiviando le versioni anteriori.
6. Interfaccia GUI mostra log in tempo reale, barra di progresso, e notifica finale “Backup completato” o dettagli errore.
7. Configurazione locale (es. `config.json`) risiede accanto alleseguibile e supporta profili, credenziali, toggle Task Scheduler (per lon/off di `schtasks`).
8. Il client può attivare/disattivare uno scheduler che richiama lAPI server in autonomia.
### Non funzionali
- Affidabilità: i job sono idempotenti e ripetibili, evitando corruzione dello stato se rilanciati.
- Performance: trasferimento differenziale (`rsync` con `-a --info=progress2 --compress` opzionale, `--partial`) e compressione configurabile.
- Manutenibilità: separazione GUI, orchestratore e runner `rsync`/logging.
- Sicurezza LAN: autenticazione token su API, canali HTTPS/SSH, criteri di privilegio ridotti, protezione credenziali (DPAPI o prompt ad ogni esecuzione), log/rotazioni.
## Architettura proposta
### Componenti critici
- **Client GUI (PySide6)**: gestisce profili, selezione cartelle, switch Task Scheduler e visualizzazione del log/polling di stato; comunica via HTTPS con token JWT.
- **Configurazione locale (`config.json`)**: profili, cartelle, endpoint API, preferenze di compressione, flag scheduler.
- **Windows OpenSSH Server (`sshd`) + `rsync.exe` portable**: riceve connessioni SSH dal server e invoca `rsync --server` per eseguire i transfer.
- **Orchestrator API (FastAPI + Uvicorn)**: espone `/auth/login`, `/profiles`, `/backup/start`, `/backup/status/{job_id}`, `/backup/log/{job_id}`, `/health`.
- **Job Runner (systemd o servizio)**: serializza job, acquisisce lock per non sovrapporsi, gestisce il comando SSH/rsync, archivia log e progressi in DB, aggiorna stato API.
- **Metadata Store (SQLite/Postgres)**: conservazione job, log, stato, retention history.
- **Backup Storage**: `/srv/backup/current` e `/srv/backup/.history/<run_id>`; possibilità di snapshot ZFS opzionale.
### Interazioni chiave
```mermaid
componentDiagram
component "Windows Client GUI\n(PySide6)" as GUI
component "Local Config\n(config.json)" as CFG
component "Windows OpenSSH Server\n(sshd)" as SSHD
component "Rsync Binary\n(rsync.exe portable)" as RSYNCW
component "Backup Orchestrator API\n(FastAPI + Uvicorn)" as API
component "Job Runner\n(systemd service)" as RUNNER
component "Metadata Store\n(SQLite/Postgres)" as DB
component "Backup Storage\n/current + /.history" as STORE
GUI --> CFG : read/write
GUI --> API : HTTPS (LAN)\nStart/Status
API --> DB : store jobs/log
API --> RUNNER : enqueue/trigger
RUNNER --> SSHD : SSH connect (pull)
SSHD --> RSYNCW : remote rsync command
RUNNER --> STORE : write backup data
```
### Flusso operativo (quando lutente preme “Esegui”)
```mermaid
sequenceDiagram
participant U as Utente
participant GUI as Client GUI (Win)
participant API as Orchestrator API (Server)
participant RUN as Job Runner (Server)
participant SSH as SSH (Win sshd)
participant STO as Storage (Server)
U->>GUI: Seleziona cartelle
GUI->>GUI: Valida cartelle (>=1) e abilita "Esegui"
U->>GUI: Click "Esegui"
GUI->>API: POST /backup/start (profilo, cartelle, credenziali)
API->>API: Crea job_id + stato QUEUED
API->>RUN: Avvia job(job_id)
RUN->>SSH: ssh user@client "rsync --server ..."
SSH->>RUN: Stream stdout/stderr (progress/log)
RUN->>STO: Scrive su /current + versioni su /.history/<run_id>
RUN->>API: Aggiorna stato COMPLETED/FAILED + summary
GUI->>API: GET /backup/status/{job_id} (poll/stream)
API->>GUI: stato + progress + log
GUI->>U: "Backup completato" (o errore)
```
### Deployment
```mermaid
deploymentDiagram
node "LAN" {
node "PC Windows 11 (Client)" {
artifact "BackupClient.exe\n(PySide6 packaged)" as EXE
artifact "config.json" as CJSON
node "Windows Feature" {
artifact "OpenSSH Server (sshd)" as WSSHD
}
artifact "rsync.exe portable" as WRSYNC
}
node "Proxmox Host" {
node "VM Debian (Backup Server)" {
artifact "backup-orchestrator\n(FastAPI)" as SAPI
artifact "job-runner\n(systemd)" as SJR
artifact "rsync" as SRSYNC
artifact "db (sqlite/postgres)" as SDB
artifact "/srv/backup/...\n(current/.history)" as SST
}
}
}
EXE --> SAPI : HTTPS 443 (LAN)
SJR --> WSSHD : SSH 22 (LAN)
SJR --> SST : local filesystem
```
```
## API e sicurezza
- **Autenticazione**: `/auth/login` restituisce JWT con scadenza, rate limit + lockout.
- **Profiling**: `/profiles` CRUD (nome, cartelle, scheduling).
- **Backup**: `/backup/start` richiama job(principale), `GET /backup/status/{job_id}`, `GET /backup/log/{job_id}`.
- **Health**: `/health` (autenticata o solo LAN) restituisce stato/versione.
### Protezioni
- HTTPS con cert self-signed o CA locale.
- Token scaduti/e refresh.
- Validazione path (no path traversal, esistenza cartelle); permetti solo cartelle allow-list.
- SSH dai soli IP server e utente `backupsvc` con shell limitata e permessi su `/srv/backup`.
- Log strutturati (JSON), rotazione via `logrotate`, niente password nei log.
## Retention e rsync
- Ogni esecuzione crea un `run_id`, `rsync` esegue `--backup --backup-dir=/srv/backup/.history/<run_id>` e `--info=progress2`.
- `current/` contiene lo stato attivo; `.history/<run_id>` conserva vecchie versioni per i file diversificati.
- Un task di cleanup mantiene solo le ultime 20 esecuzioni, cancellando `.history` più vecchie.
## Strategia scheduling e configurazione
- Client: switch Task Scheduler che attiva/disattiva una `schtasks` che lancia `BackupClient.exe --auto` (o simile) con token.
- Config facoltativa per credenziali salvate (nemmeno nel file in chiaro) tramite Windows DPAPI, ma luso di prompt password ogni job rimane default.
- API: job queue con lock, `systemd` service per runner; `rsync` timeout/retry configurabili.
## Fasi di implementazione e stime
1. **Setup server** (0.51 giorno): Debian su Proxmox, storage dedicato `/srv/backup`, user/permessi, `rsync`, OpenSSH client e service.
2. **Orchestrator FastAPI + runner** (1.52.5 giorni): API start/status/log, gestione DB (SQLite default, Postgres opzione), job queue, retention automatica.
3. **Client PySide6** (24 giorni): GUI selezione cartelle/profili, log/progress, switch Task Scheduler, config.json, packaging PyInstaller.
4. **Integrazione Windows** (12 giorni): script abilitazione OpenSSH/rsync, firewall rules, test permessi lunghi.
5. **Hardening + QA** (12 giorni): logging, rate limit, E2E manuali/schedulati, threat modeling leggero.
## Checklist sicurezza e operatività
- SSH solo da server, firewall Windows limitato ad IP del backup server.
- Password SSH non loggata, prompt per ogni job (DPAPI opzionale).
- HTTPS interno con cert gestione.
- Validazione input (allowlist, no path traversal, sanitizzazione).
- User Linux dedicato `backupsvc`, directory `700`, log `640`.
- Lock job per evitare duplicati, timeout `rsync`.
## Deliverable attesi
- Repo server: FastAPI + runner, script provisioning, doc installazione, test base.
- Repo client: PySide6 GUI, config schema, Task Scheduler script, rsync portable bundle.
- Documentazione: manuale utente, runbook admin, threat model + checklist.
- Pipeline CI: lint/test/build/release.
## Note aggiuntive
- Password SSH passata al server solo in memoria per job; non persistita nel DB.
- Il bottone sul client rimane il trigger UX, ma la copia vera è un pull orchestrato dal server grazie allSSH.