Skip to content

Keys and security ​

Every lmdb-lws-backup backup is encrypted with a single key that you create and keep. This page explains how to supply the key, how to store it safely, and where sensitive data can and cannot appear.

What is encrypted, and how ​

The tool copies the database through a pipe directly into an encrypted stream (libsodium's XChaCha20-Poly1305 secretstream). This is authenticated encryption: besides hiding the contents, it detects any change to the file, so a damaged or altered backup fails to decrypt instead of producing wrong data.

The plaintext database never touches the disk during a backup:

  • The copy streams through a pipe into the encryption.
  • The check after each backup decrypts into an anonymous memory file (memfd), not a disk file.
  • If the run crashes, only an encrypted .partial file is left, and the next run removes it.

The key ​

The key is exactly 32 random bytes. Create one with:

bash
head -c 32 /dev/urandom | base64

The result is 44 characters of base64 text. The tool refuses to run without a key; there is no unencrypted mode.

DANGER

Losing the key means losing every backup made with it. The encryption cannot be broken or bypassed, and there is no recovery. Keep at least one copy off the server, separate from the backups, for example in a password manager. Test that copy by running --verify with it.

Supplying the key ​

Set exactly one of these in the [encryption] section. Setting both, or neither, stops the tool with an error.

key_env_var: from an environment variable ​

toml
[encryption]
key_env_var = "LWS_BACKUP_KEY"

The tool reads the base64 key from the named variable. This is what the supplied systemd units use: systemd reads /etc/lmdb-lws-backup/key.env (owned by root, mode 600) and passes the variable to the service, so the service user never needs to read the file.

The file holds one line:

text
LWS_BACKUP_KEY=<base64-key>

Avoid typing the key on a command line, as in LWS_BACKUP_KEY=... lmdb-lws-backup ...: it is saved in your shell history and visible to other users in the process list while the command runs.

key_file: from a file ​

toml
[encryption]
key_file = "/etc/lmdb-lws-backup/backup.key"

The file may contain the 32 raw bytes or the base64 text. The tool insists that only its owner can access it: it must be a regular file, and it is refused if any group or other permission is set (must not be group/world accessible (chmod 600 it)). The user that runs the backup must own it or be able to read it.

Create one for the user monero-lws with:

bash
sudo install -m 600 -o monero-lws -g monero-lws /dev/null /etc/lmdb-lws-backup/backup.key
head -c 32 /dev/urandom | base64 | sudo tee /etc/lmdb-lws-backup/backup.key > /dev/null

A key file suits cron, where there is no systemd to load an environment file.

Changing the key ​

Each backup can only be decrypted with the key it was made with. If you switch to a new key, keep the old key for as long as backups made with it exist: with the default retention_days = 30, that is at least 30 days, and longer if you copied backups elsewhere. Label each stored key with the dates it was in use.

What holds sensitive data ​

FileSensitive?Notes
*.lmdbbak.encEncryptedSafe to copy off-site, as long as the key is not stored with it. Mode 600.
*.manifest.jsonNo secretsProfile, table and row counts, account count and scan heights (monero-lws), sizes and the encrypted file's SHA-256. Never key material. Mode 600.
Log fileNo secretsNever contains key material. Mode 600.
key.env or key_fileSecretMode 600, never next to the backups.
A folder made by --restorePlaintextThe decrypted database. Delete it when done.
[verify] scratch_dirPlaintext, brieflyOnly if you set it; see below.

The destination folder is created with mode 700 if it does not exist.

The verify scratch folder ​

The check after each backup needs free memory roughly the size of the compacted database, because it decrypts into RAM. If the server does not have that much, you can set:

toml
[verify]
scratch_dir = "/encrypted-scratch"

The check then decrypts into a file in that folder instead. The file is unlinked (has no name) before use, but its bytes are written to that disk. Only use a folder on an encrypted volume.

Failure alerts ​

With [alerting] on_failure_webhook set, a failed backup or verify sends a small JSON message to that URL with the stage, the error message, the host name and a time stamp. It never includes the key. Use an https:// URL so the message is not sent in clear text.

Next steps ​