- Shell 100%
- fix MOUNT_PONT typo (mount point check was never reached) - set -euo pipefail, proper .env sourcing via set -a - rsync_if_exists helper: skip missing dirs gracefully - USB copy: auto-detect /media/$USER, /run/media/$USER or via USB_MOUNT/USB_LABEL from .env - remote SCP: non-fatal if host unreachable - add ~/.step, ~/.kube, ~/.config/gh, ~/.config/borg to backup sources - remove dead commented-out cp -r code - add README.md with setup/usage/restore notes - fill env.example with all variables - gitignore: *.img glob, encrypted-key-backup.html |
||
|---|---|---|
| .gitignore | ||
| env.example | ||
| keystore.sh | ||
| README.md | ||
keystore-backup
Encrypted local backup of sensitive key material — SSH, GPG, passwords, certs, VPN configs.
Creates a LUKS-encrypted disk image, syncs key directories into it, then ships the image to a remote server and/or USB flash drive.
What gets backed up
| Source | Contents |
|---|---|
~/.ssh |
SSH keys and config |
~/.gnupg |
GPG keyring |
~/.password-store |
pass password store |
~/.borg / ~/.config/borg |
BorgBackup keys and config |
~/.step |
step-ca client certs and config |
~/.kube |
Kubernetes config |
~/.config/gh |
GitHub CLI auth |
~/.local/share/MikroTik |
WinBox addresses and workspaces |
~/.local/share/remmina |
Remmina connection profiles |
~/.ga-cmd |
ga-cmd config |
~/.nx |
NoMachine sessions (no cache/logs) |
Setup
cp env.example .env
$EDITOR .env
Required variables:
REMOTE_SRV — SSH alias (from ~/.ssh/config) or user@host
REMOTE_HOST — IP for reachability check (nmap)
REMOTE_DIR — destination path on remote
PORT1/2/3 — ports to probe for availability check
Optional for USB:
USB_MOUNT — explicit mount point (e.g. /media/user/FLASHDRIVE)
USB_LABEL — volume label (alternative to USB_MOUNT)
If neither is set, script auto-detects from /media/$USER and /run/media/$USER.
Usage
sudo ./keystore.sh
Needs sudo for cryptsetup, mount, umount.
First run: creates keystore.img (64MB LUKS + ext4), prompts for passphrase.
Subsequent runs: opens existing image, re-syncs all sources, closes, ships.
Destinations
-
Remote server — SCP to
$REMOTE_SRV:$REMOTE_DIR/keystore.imgBefore sending, probes$REMOTE_HOSTports via nmap. If remote is unreachable — warns and skips (non-fatal). -
USB flash — copies
keystore.imgto detected USB mount. If no USB found — warns and skips (non-fatal).
Files
keystore.sh — main script
env.example — config template (copy to .env)
encrypted-key-backup.html — BorgBackup paper key printable template (offline, self-contained)
keystore.img and .env are gitignored — never commit them.
Paper key backup
Open encrypted-key-backup.html in a browser (no internet needed).
Load your BorgBackup keyfile → generates printable paper key + QR code.
Print and store offline.
Notes
- LUKS passphrase is the only protection — choose a strong one and store it separately
keystore.imgis portable: open on any Linux withcryptsetup luksOpen- Test restore periodically: mount the image and verify contents