Skip to content

Commit 55e3e1c

Browse files
jmsperuclaude
andcommitted
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 <noreply@anthropic.com>
1 parent 61afb4c commit 55e3e1c

File tree

1 file changed

+38
-1
lines changed

1 file changed

+38
-1
lines changed

scripts/vm/hypervisor/kvm/nasbackup.sh

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ NAS_ADDRESS=""
3131
MOUNT_OPTS=""
3232
BACKUP_DIR=""
3333
DISK_PATHS=""
34+
ENCRYPT_PASSFILE=""
3435
logFile="/var/log/cloudstack/agent/agent.log"
3536

3637
log() {
@@ -84,6 +85,33 @@ sanity_checks() {
8485
log -ne "Environment Sanity Checks successfully passed"
8586
}
8687

88+
encrypt_backup() {
89+
local backup_dir="$1"
90+
if [[ -z "$ENCRYPT_PASSFILE" ]]; then
91+
return
92+
fi
93+
if [[ ! -f "$ENCRYPT_PASSFILE" ]]; then
94+
echo "Encryption passphrase file not found: $ENCRYPT_PASSFILE"
95+
exit 1
96+
fi
97+
log -ne "Encrypting backup files with LUKS"
98+
for img in "$backup_dir"/*.qcow2; do
99+
[[ -f "$img" ]] || continue
100+
local tmp_img="${img}.luks"
101+
if qemu-img convert -O qcow2 \
102+
--object "secret,id=sec0,file=$ENCRYPT_PASSFILE" \
103+
-o "encrypt.format=luks,encrypt.key-secret=sec0" \
104+
"$img" "$tmp_img" 2>&1 | tee -a "$logFile"; then
105+
mv "$tmp_img" "$img"
106+
log -ne "Encrypted: $img"
107+
else
108+
echo "Encryption failed for $img"
109+
rm -f "$tmp_img"
110+
exit 1
111+
fi
112+
done
113+
}
114+
87115
### Operation methods ###
88116

89117
backup_running_vm() {
@@ -114,6 +142,8 @@ backup_running_vm() {
114142
rm -f $dest/backup.xml
115143
sync
116144

145+
encrypt_backup "$dest"
146+
117147
# Print statistics
118148
virsh -c qemu:///system domjobinfo $VM --completed
119149
du -sb $dest | cut -f1
@@ -136,6 +166,8 @@ backup_stopped_vm() {
136166
done
137167
sync
138168

169+
encrypt_backup "$dest"
170+
139171
ls -l --numeric-uid-gid $dest | awk '{print $5}'
140172
}
141173

@@ -165,7 +197,7 @@ mount_operation() {
165197

166198
function usage {
167199
echo ""
168-
echo "Usage: $0 -o <operation> -v|--vm <domain name> -t <storage type> -s <storage address> -m <mount options> -p <backup path> -d <disks path>"
200+
echo "Usage: $0 -o <operation> -v|--vm <domain name> -t <storage type> -s <storage address> -m <mount options> -p <backup path> -d <disks path> [-e <passphrase file>]"
169201
echo ""
170202
exit 1
171203
}
@@ -207,6 +239,11 @@ while [[ $# -gt 0 ]]; do
207239
shift
208240
shift
209241
;;
242+
-e|--encrypt)
243+
ENCRYPT_PASSFILE="$2"
244+
shift
245+
shift
246+
;;
210247
-h|--help)
211248
usage
212249
shift

0 commit comments

Comments
 (0)