From 55e3e1c7bb37e81062aea8e79179f6d96c291ccf Mon Sep 17 00:00:00 2001 From: jmsperu Date: Tue, 17 Mar 2026 22:35:26 +0300 Subject: [PATCH] nasbackup.sh: add LUKS encryption for backup files via -e flag Add -e/--encrypt flag that accepts a passphrase file path and encrypts all qcow2 backup files using LUKS encryption via qemu-img convert. The passphrase is read from a file (not command-line) to avoid exposure in process listings. Encryption is applied after backup completes, for both running and stopped VM backup paths. Encrypted backups use the standard qcow2+LUKS format supported by QEMU, so they can be decrypted with qemu-img or mounted directly by any QEMU/libvirt tooling that supports LUKS. Co-Authored-By: Claude Opus 4.6 --- scripts/vm/hypervisor/kvm/nasbackup.sh | 39 +++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/scripts/vm/hypervisor/kvm/nasbackup.sh b/scripts/vm/hypervisor/kvm/nasbackup.sh index 9dedaef154a3..4ebb53421c83 100755 --- a/scripts/vm/hypervisor/kvm/nasbackup.sh +++ b/scripts/vm/hypervisor/kvm/nasbackup.sh @@ -31,6 +31,7 @@ NAS_ADDRESS="" MOUNT_OPTS="" BACKUP_DIR="" DISK_PATHS="" +ENCRYPT_PASSFILE="" logFile="/var/log/cloudstack/agent/agent.log" log() { @@ -84,6 +85,33 @@ sanity_checks() { log -ne "Environment Sanity Checks successfully passed" } +encrypt_backup() { + local backup_dir="$1" + if [[ -z "$ENCRYPT_PASSFILE" ]]; then + return + fi + if [[ ! -f "$ENCRYPT_PASSFILE" ]]; then + echo "Encryption passphrase file not found: $ENCRYPT_PASSFILE" + exit 1 + fi + log -ne "Encrypting backup files with LUKS" + for img in "$backup_dir"/*.qcow2; do + [[ -f "$img" ]] || continue + local tmp_img="${img}.luks" + if qemu-img convert -O qcow2 \ + --object "secret,id=sec0,file=$ENCRYPT_PASSFILE" \ + -o "encrypt.format=luks,encrypt.key-secret=sec0" \ + "$img" "$tmp_img" 2>&1 | tee -a "$logFile"; then + mv "$tmp_img" "$img" + log -ne "Encrypted: $img" + else + echo "Encryption failed for $img" + rm -f "$tmp_img" + exit 1 + fi + done +} + ### Operation methods ### backup_running_vm() { @@ -114,6 +142,8 @@ backup_running_vm() { rm -f $dest/backup.xml sync + encrypt_backup "$dest" + # Print statistics virsh -c qemu:///system domjobinfo $VM --completed du -sb $dest | cut -f1 @@ -136,6 +166,8 @@ backup_stopped_vm() { done sync + encrypt_backup "$dest" + ls -l --numeric-uid-gid $dest | awk '{print $5}' } @@ -165,7 +197,7 @@ mount_operation() { function usage { echo "" - echo "Usage: $0 -o -v|--vm -t -s -m -p -d " + echo "Usage: $0 -o -v|--vm -t -s -m -p -d [-e ]" echo "" exit 1 } @@ -207,6 +239,11 @@ while [[ $# -gt 0 ]]; do shift shift ;; + -e|--encrypt) + ENCRYPT_PASSFILE="$2" + shift + shift + ;; -h|--help) usage shift