Sari la conținutul principal

Pregătirea pentru recuperare

Libre WebUI oferă un inventar de recuperare numai pentru citire, ca primă poartă de siguranță pentru backup și restaurare. Acesta raportează starea cunoscută și condițiile care blochează snapshot-ul, dar nu obține un maintenance lock și nu copiază, criptează, încarcă, șterge, repară sau restaurează date.

libre-webui recovery-check --json > recovery-inventory.json

Dintr-un checkout source, rulați o dată npm run build:backend și înlocuiți libre-webui recovery-check cu npm run recovery:check --. Instalările npx și Homebrew inspectează implicit ~/.libre-webui; DATA_DIR și opțiunile explicite de cale schimbă locația.

Comanda recovery-check verifică pregătirea; pentru arhiva completă folosiți libre-webui backup.

Statusul 0 înseamnă că nu există blocaje, 1 că raportul este complet dar există blocaje, iar 2 indică argumente invalide sau un eșec neașteptat de colectare. Folosiți --data-dir PATH sau --database PATH pentru o locație diferită. Inventarul implicit acceptă numai DATA_DIR/data.sqlite și respinge hardlink-uri, symlink-uri și fișiere database/WAL/SHM care nu sunt obișnuite. Un --database explicit poate fi în afara DATA_DIR, dar trebuie să fie fișier obișnuit, fără symlink; fără --data-dir, directorul părinte devine rădăcina datelor.

Runtime-ul citește și definițiile istorice din folderul plugins al backend-ului și locația veche, relativă la backend, pentru un PLUGINS_DIR relativ. Definițiile personalizate de acolo blochează un backup numai al volumului. O instalare împachetată poate transmite de mai multe ori --legacy-plugins-dir PATH.

Pentru deployment-ul Compose privat, rulați în container:

docker exec libre-webui \
libre-webui recovery-check --json --data-dir /app/backend/data

Ce verifică inventarul

Raportul JSON versionat înregistrează:

  • versiunile aplicației și Node.js, sistemul de operare și arhitectura;
  • dimensiunile SQLite/WAL/SHM, quick_check, foreign keys, amprenta schemei, versiunea utilizatorului, tabelele lipsă și validarea no-follow;
  • posibilitatea de citire/scriere a directorului de date, numărul fișierelor și octeții;
  • sursa cheii, o amprentă ireversibilă de 16 caractere și verificarea .encryption_key;
  • pluginuri personalizate, blob-uri locale criptate, media, referințe vocale, textul documentelor și vectori legacy/platform cu ACL;
  • certificarea completă, în limite, a blob-urilor canonice, envelope-urilor vectoriale, chunk-urilor și checksum-urilor cu cheile disponibile;
  • certificarea envelope-urilor AES-GCM legacy recunoscute în chat-uri, notițe, documente, preferințe, secrete de plugin, media, e-mail și câmpuri vocale legate prin AAD;
  • sarcini/execuții/preview-uri Work și volume Docker, PVC-uri Kubernetes sau căi host hash-uite așteptate, cu proprietarul corect;
  • job-uri media, job-uri durabile/încercări, fluxuri de evenimente și cursorul global;
  • certificarea payload-urilor criptate și validarea sintactică a referințelor opace; și
  • blocaje, avertismente și date din afara directorului de date.

Raportul nu include chei, secrete JWT/sesiune, credentials, conținut de plugin/utilizator sau căi reale ale host-ului. Un mount numai pentru citire produce avertisment, nu blocaj, dar nu porniți aplicația pe snapshot.

Blocaje

Orice blocaj închide poarta. Cauzele obișnuite includ o bază lipsă/coruptă, o schemă incompletă, o cheie lipsă sau conflictuală, ciphertext corupt, depășirea limitelor, un director ilizibil, SQLite legat, un job Work/media/durabil activ, un spațiu lipsă ori etichetat greșit, nepotrivirea head-ului de evenimente sau o discontinuitate de secvență, un plugin personalizat în afara directorului de date ori un control plane care nu poate verifica spațiile externe. Opriți activitatea și remediați dependențele; nu modificați raportul.

Payload-urile criptate sunt certificate folosind identitatea job-ului/evenimentului și JSON canonic, limitat. Referințele opace sunt verificate numai ca dimensiune și sintaxă, deoarece nu există un repository autoritativ. referenceTargetsVerified devine false și apare un avertisment fără valorile payload-ului.

Câmpurile text legacy preced markerul envelope, astfel încât textul simplu vechi și autentic rămâne lizibil și nu este numărat ca ciphertext autentificat. Envelope-urile canonice sunt certificate întotdeauna; valorile tripartite deformate închid accesul în siguranță. Câmpurile vocale au un envelope binar distinct, legat de profil/proprietar/câmp. encryption.legacyCiphertext raportează numere și octeți, fără text clar.

Cu schema v4 și users.email_lookup, fiecare adresă de e-mail este certificată și tokenul keyed, separat pe domeniu, este recalculat. Un token lipsă, greșit sau prezent pentru un e-mail null blochează; bazele vechi fără coloană rămân compatibile.

Limita curentă a backup-ului

Helper-ul deployment-ului privat oprește aplicația dacă este necesar și creează o arhivă solo integrată din imaginea, volumul și mediul exacte. Manifestul este semnat Ed25519, iar payload-ul criptat AES-256-GCM cu o cheie a operatorului. Conține SQLite, blob-uri locale, vectori integrați, selectoare runtime și configurație protejată. Semnătura, checksum-ul ciphertext-ului și payload-ul decriptat sunt verificate înainte de publicare. libre-webui-restore acceptă numai un volum Docker nou și scrie configurația ca fișiere private într-un director nou.

Configurația protejată include pool-ul și timeout-urile PostgreSQL, timeout-ul Redis, cotele blob, selectoarele platformei și prefixul/adresarea S3. Se află în payload-ul semnat și criptat și este publicată cu permisiuni 0600.

Arhiva solo nu include volume Work, PVC-uri Kubernetes, foldere host, modele Ollama sau starea furnizorilor externi. Păstrați backup-uri separate. Fluxul team sigilează exportul PostgreSQL, obiectele S3 versionate exacte, inventarul PGVector, configurația runtime și identitatea cheii și verifică ținte curate. Cache-ul, prezența, wake-up-urile și lease-urile Redis sunt reconstruite din SQL.

Backup-ul team certifică toate payload-urile criptate și limitate ale job-urilor/evenimentelor. Fiecare flux trebuie să conțină 1..last_sequence, iar cursorul global nu trebuie să rămână în urmă. Restaurarea compară rezultatul complet cu inventarul source semnat. Discontinuitățile dintre cursori globali sunt permise, deoarece alocarea identity PostgreSQL nu este tranzacțională; continuitatea per flux este contractul.

Dacă PLUGINS_DIR se află în afara DATA_DIR, este marcat ca exclus, iar definițiile blochează backup-ul volumului până când există un snapshot corespunzător. Symlink-urile, JSON-ul neobișnuit sau ilizibil sunt blocaje. Job-urile/evenimentele durabile sunt active în ambele profiluri; recuperarea blochează încercările și Work active, validează payload-ul/secvența și păstrează SQL. Solo are worker integrat, team worker extern, iar Redis este folosit numai pentru wake-up/fan-out.

În producție, păstrați secretele de criptare/JWT într-un secret manager, arhive criptate în afara host-ului și testați restaurarea într-un mediu curat, compatibil. Inventarul este un snapshot preflight, nu un lock sau o dovadă completă pentru resursele externe.

Comenzi pentru backup semnat și criptat

Folosiți libre-webui instalat; fără instalare globală, folosiți npx --yes libre-webui@latest, iar din source npm run recovery:backup --. Imaginea de producție include /usr/local/bin/libre-webui. Team necesită pg_dump și pg_restore din PostgreSQL 16.

Creați cheile într-un director privat:

install -d -m 0700 /absolute/private/libre-backup-keys
libre-webui backup keygen \
--directory /absolute/private/libre-backup-keys

Creați și verificați o arhivă solo:

libre-webui backup create \
--offline \
--data-dir /absolute/path/to/libre-data \
--output /absolute/backups/libre-solo.lwbackup \
--encryption-key /absolute/private/libre-backup-keys/backup-encryption.key \
--signing-private-key /absolute/private/libre-backup-keys/backup-signing-private.pem

libre-webui backup verify \
--archive /absolute/backups/libre-solo.lwbackup \
--encryption-key /absolute/private/libre-backup-keys/backup-encryption.key \
--signing-public-key /absolute/private/libre-backup-keys/backup-signing-public.pem

Rulați preflight și apply numai într-un director nou și gol:

libre-webui backup restore-preflight \
--archive /absolute/backups/libre-solo.lwbackup \
--target /absolute/restore/libre-data \
--encryption-key /absolute/private/libre-backup-keys/backup-encryption.key \
--signing-public-key /absolute/private/libre-backup-keys/backup-signing-public.pem

libre-webui backup restore-apply \
--archive /absolute/backups/libre-solo.lwbackup \
--target /absolute/restore/libre-data \
--encryption-key /absolute/private/libre-backup-keys/backup-encryption.key \
--signing-public-key /absolute/private/libre-backup-keys/backup-signing-public.pem

libre-webui backup restore-verify \
--target /absolute/restore/libre-data

Pentru team, opriți replicile și worker-ele:

libre-webui backup create-team \
--offline \
--output /absolute/backups/libre-team.lwbackup \
--encryption-key /absolute/private/libre-backup-keys/backup-encryption.key \
--signing-private-key /absolute/private/libre-backup-keys/backup-signing-private.pem

Încărcați mediul pentru un PostgreSQL separat și gol și un bucket S3 versionat. Preflight dovedește că țintele sunt goale fără să publice nimic; apply restaurează și verifică schema, obiectele S3 exacte și PGVector și scrie configurația protejată:

libre-webui backup restore-team-preflight \
--archive /absolute/backups/libre-team.lwbackup \
--encryption-key /absolute/private/libre-backup-keys/backup-encryption.key \
--signing-public-key /absolute/private/libre-backup-keys/backup-signing-public.pem

libre-webui backup restore-team-apply \
--archive /absolute/backups/libre-team.lwbackup \
--configuration-output /absolute/restore/libre-team-config \
--encryption-key /absolute/private/libre-backup-keys/backup-encryption.key \
--signing-public-key /absolute/private/libre-backup-keys/backup-signing-public.pem

Nu restaurați în baza/bucket-ul source sau într-un director de date/configurație existent. Cheia publică de semnare nu este suficientă pentru decriptare. Dacă rollback-ul team este incomplet, considerați ambele ținte contaminate: curățați PostgreSQL și toate versiunile/marcajele de ștergere S3 de sub prefixul exact, apoi rulați din nou restore-team-preflight.

Exerciții de recuperare programate și verificate

Un backup care nu a fost restaurat este doar o speranță. Un exercițiu:

  1. Obține un snapshot SQLite quiescent prin API-ul online de backup și copiază blob-urile/fișierele; refuză un job durabil activ.
  2. Creează o arhivă AES-256-GCM semnată, cu chei temporare și inventar complet.
  3. Verifică, restaurează izolat și verifică din nou.
  4. Înregistrează durata ca RTO, intervalul dintre succese ca RPO și șterge artefactele/cheile.

Activați cu RECOVERY_DRILL_INTERVAL_HOURS (de exemplu 24). Un lease de coordonare previne execuția dublă. System afișează istoricul și „Run drill now” prin GET /api/recovery/drills și POST /api/recovery/drills/run. Un eșec nesupravegheat notifică administratorii; RECOVERY_DRILL_HISTORY limitează istoricul (60).

Exercițiile acoperă solo/SQLite. Pentru team se folosesc în continuare backup create-team și runbook-ul operatorului.