We will create a LVM snapshot and store it on a remote SFTP server. The archive will be encrypted with a GPG key to secure it outside of our network.
#!/bin/sh set -e # Create snapshot of LVM volume and tar its content # Thomas Leuxner <tlx@leuxner.net> 16-04-2024 . sftp_login.inc gpg_key='backups@example.com' if [ $# -eq 0 ]; then echo "usage: $0 lvm" >&2 exit 1 fi # Snapshot definitions that will be passed to function create_lvm_snapshot lvm_vol="/dev/mapper/$1" lvm_vg=${1%-*} lvm_name=${1#*-} lvm_snap_name="s.$lvm_name" lvm_snap_vol="/dev/$lvm_vg/$lvm_snap_name" lvm_snap_mount="/media/$lvm_snap_name" # Day of week for our file dow=$(date +%u) filename="s.$lvm_vg-$lvm_name-lvm.$dow.tar.gz" create_lvm_snapshot () { lvcreate -L512M -s -n $2 $1 >/dev/null 2>&1 mount $3 $4 -oro } remove_lvm_snapshot () { umount $1 yes | lvremove $1 >/dev/null 2>&1 } # Create snapshot of LVM [ -L $lvm_snap_vol ] && { printf "Snapshot exists. Exiting!\n" >&2; exit 1; } [ -d $lvm_snap_mount ] || { printf "Creating mountpoint for snapshot.\n" >&2; mkdir -m 500 $lvm_snap_mount; } create_lvm_snapshot "$lvm_vol" "$lvm_snap_name" "$lvm_snap_vol" "$lvm_snap_mount" # Tar everything and encrypt the file nice -n 19 tar -cSzf - -C $lvm_snap_mount . 2> /dev/null | \ gpg --trust-model always --recipient $gpg_key --encrypt | \ curl -s -u "$sftp_user:$sftp_password" "sftp://$sftp_server/$filename" -T - 2>&1 # Remove snapshot remove_lvm_snapshot "$lvm_snap_vol"
sftp_server='<url>' sftp_user='<user>' sftp_password='<password>'
Create GPG key
We will create a dedicated key to encrypt our backups. Make sure to extract this key and store it safely.
gpg --full-generate-key gpg (GnuPG) 2.2.40; Copyright (C) 2022 g10 Code GmbH This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) (14) Existing key from card Your selection? 1 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (3072) 4096 Please specify how long the key should be valid. 0 = key does not expire = key expires in n days w = key expires in n weeks m = key expires in n months y = key expires in n years Key is valid for? (0) Key does not expire at all Is this correct? (y/N) GnuPG needs to construct a user ID to identify your key. Real name: Backups Example.com Email address: backups@example.com Comment: You selected this USER-ID: "Backups Example.com <backups@example.com>"
Back up key
Export the key in plain text format.
gpg --output backups.gpg --armor--export-secret-keys --export-options export-backup backups@example.com gpg --import backups.gpg
Up our game
Alternatively we can use an elliptic curve Ed25519 key instead.
gpg2 --expert --full-generate-key gpg (GnuPG) 2.2.40; Copyright (C) 2022 g10 Code GmbH This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) (7) DSA (set your own capabilities) (8) RSA (set your own capabilities) (9)ECC and ECC (10) ECC (sign only) (11) ECC (set your own capabilities) (13) Existing key (14) Existing key from card Your selection? 9 Please select which elliptic curve you want: (1)Curve 25519 (3) NIST P-256 (4) NIST P-384 (5) NIST P-521 (6) Brainpool P-256 (7) Brainpool P-384 (8) Brainpool P-512 (9) secp256k1 Your selection? 1