Skip to content
Backups and restore

Backups and restore

lasboltd makes backups by itself. This page shows how to set them up, how to keep copies away from the server, and how to restore. A backup that you did not test is not a backup. Test the restore.

How backups work

  • lasboltd makes a consistent copy of the database with SQLite VACUUM INTO. The server keeps running.
  • The default is one backup each 24 hours, in <data-dir>/backups. The server keeps the newest 14.
  • After each backup the server opens the copy. It checks the schema version and PRAGMA integrity_check. It also proves that the copy has the same wrapped data key as the live database. A backup that fails is deleted and logged as an error.
  • The first backup is made at start only if the newest backup is older than the interval.
  • File names are lasbolt-<UTC time>-<epoch>.db. A sealed backup ends in .db.pwbk. Files have mode 0600 and the folder has mode 0700.
  • Backups include everything in the database: users, ciphertext, audit rows, settings.
FlagVariableDefault
--backup-intervalLASBOLT_BACKUP_INTERVAL24h (0 turns backups off)
--backup-keepLASBOLT_BACKUP_KEEP14 (0 keeps all)
--backup-dirLASBOLT_BACKUP_DIR<data-dir>/backups
--backup-recipientLASBOLT_BACKUP_RECIPIENTnone
--backup-identityLASBOLT_BACKUP_IDENTITYnone
With --backup-interval 0 the server makes no backup and logs a warning at start. The folder backups is on the same disk as the database. It does not protect you from a lost disk. Copy backups to another place.

Seal backups to a key

A plain backup holds the database as the server holds it. Server-readable values are encrypted with the data key. The data key is wrapped with the KEK. With the passphrase provider, a person who gets a backup can guess the unseal passphrase offline. Argon2id makes each guess slow, but a short passphrase is weak.

A sealed backup adds a second encryption. It uses a public key on the server. Only the private key, which you keep away from the server, opens the backup.

Make a key pair

Run this on a trusted computer, not on the server:

lasboltd backup keygen --out backup.key
Private key: backup.key (keep it away from the server)
Public key:  backup.key.pub (use it with --backup-recipient)

The command refuses to replace a file that exists. The private key file has mode 0600.

Copy the public key to the server

sudo install -m 0644 -o root -g lasbolt backup.key.pub /etc/lasbolt/backup.key.pub

Set the recipient and restart

Add this line to /etc/lasbolt/lasboltd.env:

LASBOLT_BACKUP_RECIPIENT=/etc/lasbolt/backup.key.pub
sudo systemctl restart lasboltd

The log line backups on now shows sealed=true.

Store the private key

Keep backup.key in a password manager or on offline media. Without it, you cannot restore a sealed backup. Do not keep it on the server.

Commands

The commands use the same data folder and unseal settings as the server. To run them by hand, load the settings file (see Configuration).

CommandWhat it does
lasboltd backup nowMakes a backup now. It works while the server runs.
lasboltd backup listLists the backups with date, kind (plain or sealed) and size.
lasboltd backup verify <file>Checks a backup file. For a sealed file add --backup-identity backup.key.
lasboltd backup keygen --out <file>Makes a key pair for sealed backups.
lasboltd restore <file>Restores a backup. The server must be stopped.
sudo -u lasbolt sh -c 'set -a; . /etc/lasbolt/lasboltd.env; set +a; exec lasboltd backup now'
Backup made: /var/lib/lasbolt/backups/lasbolt-20261021T102721Z-7b1ddefcea1594a7b588c8a5fe5cca9f.db.pwbk

backup now and backup verify need the unseal secret, because they check that the data key opens. backup list does not.

Copy backups off the server

Copy the files from backups/ to a place on another host. Do this on a schedule. Examples:

# on the backup host, pull with rsync over SSH
rsync -a --ignore-existing backup-user@vault.example.org:/var/lib/lasbolt/backups/ /srv/lasbolt-backups/
  • Give the account that reads the folder read access only. The folder has mode 0700 and belongs to lasbolt. Use a group or an ACL for the reader, or run a copy job as lasbolt.
  • Prefer sealed backups for copies that leave the server. Then the storage provider cannot read them, and a stolen copy needs the private key.
  • Keep the private key and the unseal secret in two other places. A restore needs both: the private key to open the file, and the unseal secret to unwrap the data key.
  • A file in the folder that does not match the name pattern is never deleted by the retention job.

Restore

A restore replaces the database with a backup. Use it after a disk loss or a bad change.

Stop the server

sudo systemctl stop lasboltd

lasboltd restore refuses to run while the database is in use (the database is in use: stop lasboltd first).

Run the restore

For a sealed backup, give the private key. For any backup, give the same unseal secret as the server.

sudo -u lasbolt sh -c 'set -a; . /etc/lasbolt/lasboltd.env; set +a; exec lasboltd restore /path/to/backup.db.pwbk --backup-identity /path/to/backup.key'
Old database kept as: /var/lib/lasbolt/lasbolt.db.before-restore-20261021T102734Z
New database epoch: f52b8bc6372fd45b5a13627f9ee1e8ac
Restore is done. A new database epoch is set.
...

The command checks that the backup opens with your unseal secret. It refuses a backup with a newer schema than the program. It keeps the old database as lasbolt.db.before-restore-<time> and copies the backup to lasbolt.db. The backup file stays.

Start the server

sudo systemctl start lasboltd
sudo -u lasbolt lasboltctl users list

What clients do after a restore. The restore sets a new database epoch. A client that sees a new epoch reads everything again and pushes its local changes again. Most data that is newer than the backup comes back from the devices. Purges that you made after the backup are lost: purged items can come back from clients. A client that sees an older state of an end-to-end folder than it knows stops writes to that folder. The user then accepts the new state, for example with lasbolt e2e accept-rollback <folder>.

The restore also brings back the state of the users at the time of the backup. A user who was disabled after that is active again. Check lasboltctl users list.

Test the restore

Do this each month, and after each change of the unseal secret or the backup key.

  1. Copy the newest backup to a test place.

  2. Check the file:

    lasboltd backup verify lasbolt-<time>-<epoch>.db.pwbk --backup-identity backup.key

    The output is OK: schema <n>, epoch <id>.

  3. Restore it into an empty folder, with the unseal secret of the server:

    mkdir -m 700 /tmp/restore-test
    lasboltd restore lasbolt-<time>-<epoch>.db.pwbk --data-dir /tmp/restore-test --backup-identity backup.key
  4. Start a test server on it, with the control socket on a different path and no backups, and list the users:

    lasboltd --data-dir /tmp/restore-test --addr 127.0.0.1:18082 --backup-interval 0 --ctl-socket /tmp/restore-test.sock &
    lasboltctl --socket /tmp/restore-test.sock users list
    kill %1
  5. Delete /tmp/restore-test.

If any step fails, fix the cause now: a lost private key, a wrong passphrase or a damaged copy.

Last updated on