4.5 KiB
Backup and restore
Current status
The owner requires that a complete production archive never be written to the
VPS, even temporarily. The reviewed implementation in PR #59 streams stopped
Compose state directly from the root receiver to the owner's Windows client;
the client stores it only under D:\Dev\akyldash\.backups. The VPS retains
only a secret-free identity (backup ID, size, archive and manifest hashes,
manifest) in root-owned release state. The Windows rerun passed 12 synthetic
client checks, 8 protocol checks, and a disposable real-NTFS private owner-ACL
fixture. The production D: path, SSH connection, VPS installation, and
full production backup remain unverified. There is no verified production
backup, so production deployment remains blocked.
External backup flow
- The release receiver takes the shared deployment lock and stops the stack.
- It streams a tar/gzip archive through a bounded binary SSH session. It does not create a local archive or temporary full-size copy on the VPS.
- The Windows receiver requires the exact D: repository, a real NTFS path,
restrictive ACLs, and the exact
/.backups/rule in that checkout's local.git/info/exclude. Before SSH connects, it also requires at least 100 GiB plus 1 MiB of free D: space, matching the protocol's maximum archive size. The ACL owner and every allowed full-control entry must be the current user, SYSTEM, or local Administrators; other and deny entries fail closed. It writes into a private staging directory, checks the stream size and SHA-256, verifies the archive and manifest, then publishes the complete backup directory without overwriting an existing ID. It checks the published ACL before acknowledging; on failure it removes only the same verified staging directory, and refuses cleanup if its identity or contents have changed. - Only after Windows confirms the stored archive identity does the VPS proceed with image cutover. If backup transport or verification fails, it attempts to restart the previous services and records a recovery journal if restart fails.
- Rollback first challenges Windows with the root-pinned previous backup identity. Windows verifies the local archive and streams it back; the VPS compares its exact size and SHA-256 before stopping services. Rollback then creates a fresh external backup of the current state before changing image references. It restores images only, never application data or OpenSearch state.
Windows PowerShell is the intended client. The Windows checks exercised the destination and ACL rules, including a disposable real-NTFS private owner-ACL fixture. The actual production D: destination and SSH path remain unverified. An owner must separately test archive restore on an isolated target before relying on this path. Do not restore over production as a test.
Backup contents and limits
The existing infra/backup/archive.py manifest records the Git revision,
deployment-file hashes, image references and IDs, and the components included
in the archive: application data, OpenSearch, Caddy data/configuration,
production.env, and the review secret. Secret-bearing files and SQLite files
are archived with restrictive modes. The archive verifier rejects unsafe
members and checks SQLite integrity. SSH encrypts archive bytes in transit.
The destination contains secrets and private keys; D: encryption at rest (for
example, BitLocker) has not been verified. This PR adds no client-side
encryption or signing, so the owner must verify storage encryption and retain
the restrictive ACLs before using it.
The external protocol caps control frames at 64 KiB, chunks at 1 MiB, and the archive at 100 GiB. SSH provides transport encryption and server host-key verification. The receiver uses a fixed SSH command and does not accept a caller-supplied path or shell command. It relies on the existing owner SSH configuration; no key, host entry, sudo rule, or VPS setting is added here.
Restore
Use infra/backup/archive.py restore only with an archive already present in a
protected owner-controlled location, and target a new staging directory on an
isolated recovery host. Review recovery and
deployment first. This PR does not perform or authorize a
production restore, data migration, or VPS operation. Keep the previous
external archive until the owner has verified the replacement and explicitly
approved its retention period.
The former /var/backups/akyldash create/verify procedure is superseded and
must not be used for a full production archive on the VPS.