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