Skip to content

Commit a0f4ed3

Browse files
committed
cryptpilot-convert: add --rootfs-no-encryption option to make disk with rootfs volume unencrypted
Signed-off-by: Kun Lai <[email protected]>
1 parent b72423f commit a0f4ed3

File tree

2 files changed

+68
-34
lines changed

2 files changed

+68
-34
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ Here we will encrypt the disk image file with a provided passphrase (`AAAaaawewe
7575
And you can start the encryption with:
7676

7777
```sh
78-
cryptpilot-convert --in ./aliyun_3_x64_20G_nocloud_alibase_20250117.qcow2 --out ./encrypted.qcow2 -c ./config_dir/ --passphrase AAAaaawewe222
78+
cryptpilot-convert --in ./aliyun_3_x64_20G_nocloud_alibase_20250117.qcow2 --out ./encrypted.qcow2 -c ./config_dir/ --rootfs-passphrase AAAaaawewe222
7979
```
8080

8181
> Note: You can also use the --package parameter to install some packages/rpms to the disk, before the encryption.
@@ -112,7 +112,7 @@ For those who wish to encrypt a real system disk, you need to unbind the disk fr
112112
1. Encrypt the disk (assuming the disk is `/dev/nvme2n1`):
113113

114114
```sh
115-
cryptpilot-convert --device /dev/nvme2n1 -c ./config_dir/ --passphrase AAAaaawewe222
115+
cryptpilot-convert --device /dev/nvme2n1 -c ./config_dir/ --rootfs-passphrase AAAaaawewe222
116116
```
117117

118118
Now re-bind the disk to the original instance and boot from it.

cryptpilot-convert.sh

Lines changed: 66 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -158,17 +158,19 @@ disk::umount_wait_busy() {
158158

159159
proc::print_help_and_exit() {
160160
echo "Usage:"
161-
echo " $0 --device <device> --config-dir <cryptpilot_config_dir> --passphrase <rootfs_encrypt_passphrase> [--package <rpm_package>...]"
162-
echo " $0 --in <input_file> --out <output_file> --config-dir <cryptpilot_config_dir> --passphrase <rootfs_encrypt_passphrase> [--package <rpm_package>...]"
161+
echo " $0 --in <input_file> --out <output_file> --config-dir <cryptpilot_config_dir> --rootfs-passphrase <rootfs_encrypt_passphrase> [--package <rpm_package>...]"
162+
echo " $0 --in <input_file> --out <output_file> --config-dir <cryptpilot_config_dir> --rootfs-no-encryption [--package <rpm_package>...]"
163+
echo " $0 --device <device> --config-dir <cryptpilot_config_dir> --rootfs-passphrase <rootfs_encrypt_passphrase> [--package <rpm_package>...]"
163164
echo ""
164165
echo "Options:"
165-
echo " -d, --device <device> The device to operate on."
166-
echo " --in <input_file> The input OS image file (vhd or qcow2)."
167-
echo " --out <output_file> The output OS image file (vhd or qcow2)."
168-
echo " -c, --config-dir <cryptpilot_config_dir> The directory containing cryptpilot configuration files."
169-
echo " --passphrase <rootfs_encrypt_passphrase> The passphrase for rootfs encryption."
170-
echo " --package <rpm_package> Specify an RPM package name or RPM file to install (can be specified multiple times)."
171-
echo " -h, --help Show this help message and exit."
166+
echo " -d, --device <device> The device to operate on."
167+
echo " --in <input_file> The input OS image file (vhd or qcow2)."
168+
echo " --out <output_file> The output OS image file (vhd or qcow2)."
169+
echo " -c, --config-dir <cryptpilot_config_dir> The directory containing cryptpilot configuration files."
170+
echo " --rootfs-passphrase <rootfs_encrypt_passphrase> The passphrase for rootfs encryption."
171+
echo " --rootfs-no-encryption <rootfs_encrypt_passphrase> Skip rootfs encryption, but keep the rootfs measuring feature enabled."
172+
echo " --package <rpm_package> Specify an RPM package name or RPM file to install (can be specified multiple times)."
173+
echo " -h, --help Show this help message and exit."
172174
exit $1
173175
}
174176

@@ -316,9 +318,9 @@ step:update_rootfs_and_initrd() {
316318
yum --installroot="${rootfs_mount_point}" clean all
317319

318320
# copy cryptpilot config
319-
echo "Copying cryptpilot config from /etc/cryptpilot to target rootfs"
321+
echo "Copying cryptpilot config from ${config_dir} to target rootfs"
320322
mkdir -p "${rootfs_mount_point}/etc/cryptpilot/"
321-
cp -a "${config_dir}." "${rootfs_mount_point}/etc/cryptpilot/"
323+
cp -a "${config_dir}/." "${rootfs_mount_point}/etc/cryptpilot/"
322324

323325
# update /etc/fstab
324326
echo "Updating /etc/fstab"
@@ -460,9 +462,9 @@ step::create_lvm_part() {
460462
proc::exec_subshell_flose_fds vgcreate system $lvm_part
461463
}
462464

463-
step::setup_rootfs_lv() {
464-
local passphrase=$1
465-
local rootfs_file_path=$2
465+
step::setup_rootfs_lv_with_encrypt() {
466+
local rootfs_file_path=$1
467+
local rootfs_passphrase=$2
466468

467469
local rootfs_size_in_byte
468470
rootfs_size_in_byte=$(stat --printf="%s" "${rootfs_file_path}")
@@ -471,21 +473,36 @@ step::setup_rootfs_lv() {
471473
proc::hook_exit "[[ -e /dev/mapper/system-rootfs ]] && disk::dm_remove_all ${device}"
472474
proc::exec_subshell_flose_fds lvcreate -n rootfs --size ${rootfs_lv_size_in_bytes}B system # Note that the real size will be a little bit larger than the specified size, since they will be aligned to the Physical Extentsize (PE) size, which by default is 4MB.
473475
# Create a encrypted volume
474-
echo -n "${passphrase}" | cryptsetup luksFormat --type luks2 --cipher aes-xts-plain64 /dev/mapper/system-rootfs -
476+
echo -n "${rootfs_passphrase}" | cryptsetup luksFormat --type luks2 --cipher aes-xts-plain64 /dev/mapper/system-rootfs -
475477
proc::hook_exit "[[ -e /dev/mapper/rootfs ]] && dmsetup remove rootfs"
476-
echo -n "${passphrase}" | cryptsetup open /dev/mapper/system-rootfs rootfs -
478+
479+
echo -n "${rootfs_passphrase}" | cryptsetup open /dev/mapper/system-rootfs rootfs -
477480
# Copy rootfs content to the encrypted volume
478481
dd status=progress "if=${rootfs_file_path}" of=/dev/mapper/rootfs bs=4M
482+
dmsetup remove rootfs
483+
}
484+
485+
step::setup_rootfs_lv_without_encrypt() {
486+
local rootfs_file_path=$1
487+
488+
local rootfs_size_in_byte
489+
rootfs_size_in_byte=$(stat --printf="%s" "${rootfs_file_path}")
490+
local rootfs_lv_size_in_bytes=$((rootfs_size_in_byte + 16 * 1024 * 1024)) # original rootfs partition size plus LUKS2 header size
491+
echo "Creating rootfs logical volume"
492+
proc::hook_exit "[[ -e /dev/mapper/system-rootfs ]] && disk::dm_remove_all ${device}"
493+
proc::exec_subshell_flose_fds lvcreate -n rootfs --size ${rootfs_lv_size_in_bytes}B system # Note that the real size will be a little bit larger than the specified size, since they will be aligned to the Physical Extentsize (PE) size, which by default is 4MB.
494+
# Copy rootfs content to the lvm volume
495+
dd status=progress "if=${rootfs_file_path}" of=/dev/mapper/system-rootfs bs=4M
479496
}
480497

481498
step::setup_rootfs_hash_lv() {
482-
local boot_part=$1
499+
local rootfs_file_path=$1
500+
local boot_part=$2
483501
local rootfs_hash_file_path="${workdir}/rootfs_hash.img"
484-
veritysetup format /dev/mapper/rootfs "${rootfs_hash_file_path}" --format=1 --hash=sha256 |
502+
veritysetup format "${rootfs_file_path}" "${rootfs_hash_file_path}" --format=1 --hash=sha256 |
485503
tee "${workdir}/rootfs_hash.status" |
486504
gawk '(/^Root hash:/ && $NF ~ /^[0-9a-fA-F]+$/) { print $NF; }' \
487505
>"${workdir}/rootfs_hash.roothash"
488-
dmsetup remove rootfs
489506
cat "${workdir}/rootfs_hash.status"
490507

491508
local rootfs_hash_size_in_byte
@@ -518,22 +535,22 @@ main() {
518535
exit 1
519536
fi
520537

538+
local operate_on_device
521539
local device
522540
local input_file
523541
local output_file
524542
local config_dir
525-
local passphrase
543+
local rootfs_passphrase
544+
local rootfs_no_encryption=false
526545
local packages=()
527546

528547
while [[ "$#" -gt 0 ]]; do
529548
case $1 in
530549
-d | --device)
531-
operate_on_device=true
532550
device="$2"
533551
shift 2
534552
;;
535553
--in)
536-
operate_on_device=false
537554
input_file="$2"
538555
shift 2
539556
;;
@@ -545,10 +562,14 @@ main() {
545562
config_dir="$2"
546563
shift 2
547564
;;
548-
--passphrase)
549-
passphrase="$2"
565+
--rootfs-passphrase)
566+
rootfs_passphrase="$2"
550567
shift 2
551568
;;
569+
--rootfs-no-encryption)
570+
rootfs_no_encryption=true
571+
shift 1
572+
;;
552573
--package)
553574
packages+=("$2")
554575
shift 2
@@ -562,26 +583,29 @@ main() {
562583
esac
563584
done
564585

565-
local operate_on_device
566586
if [ -n "${device:-}" ]; then
567587
if [ -n "${input_file:-}" ] || [ -n "${output_file:-}" ]; then
568-
proc::fatal "Cannot specify both --device and --in/--out file"
588+
proc::fatal "Cannot specify both --device and --in/--out"
569589
fi
570590
operate_on_device=true
571591
elif [ -n "${input_file:-}" ] && [ -n "${output_file:-}" ]; then
572592
operate_on_device=false
573593
else
574-
proc::fatal "Must specify either --device or --in/--out file"
594+
proc::fatal "Must specify either --device or --in/--out"
575595
fi
576596

577597
if [ -z "${config_dir:-}" ]; then
578598
proc::fatal "Must specify --config-dir"
579599
elif [ ! -d "${config_dir}" ]; then
580600
proc::fatal "Cryptpilot config dir ${config_dir} does not exist"
601+
else
602+
[ -f "${config_dir}/fde.toml" ] || proc::fatal "Cryptpilot Full-Disk Encryption config file must exist: ${config_dir}/fde.toml"
581603
fi
582604

583-
if [ -z "${passphrase:-}" ]; then
584-
proc::fatal "Must specify --passphrase"
605+
if [ -n "${rootfs_passphrase:-}" ] && ! [ "${rootfs_no_encryption}" = false ]; then
606+
proc::fatal "Cannot specify both --rootfs-passphrase and --rootfs-no-encryption"
607+
elif [ -z "${rootfs_passphrase:-}" ] && [ "${rootfs_no_encryption}" = false ]; then
608+
proc::fatal "Must specify either --rootfs-passphrase or --rootfs-no-encryption"
585609
fi
586610

587611
if [ "${operate_on_device}" = true ]; then
@@ -655,7 +679,7 @@ main() {
655679
echo "Copying ${input_file} to ${work_file}"
656680
proc::hook_exit "rm -f ${work_file}"
657681
cp "${input_file}" "${work_file}"
658-
proc::hook_exit "qemu-nbd --disconnect ${device}"
682+
proc::hook_exit "qemu-nbd --disconnect ${device} >/dev/null"
659683
qemu-nbd --connect="${device}" --discard=on --detect-zeroes=unmap "${work_file}"
660684
sleep 2
661685
echo "Mapped to NBD device ${device}"
@@ -720,13 +744,17 @@ main() {
720744
# 7. Setting up rootfs logical volume
721745
#
722746
echo "[ 7 ] Setting up rootfs logical volume"
723-
step::setup_rootfs_lv "${passphrase}" "${rootfs_file_path}"
747+
if [ "${rootfs_no_encryption}" = false ]; then
748+
step::setup_rootfs_lv_with_encrypt "${rootfs_file_path}" "${rootfs_passphrase}"
749+
else
750+
step::setup_rootfs_lv_without_encrypt "${rootfs_file_path}"
751+
fi
724752

725753
#
726754
# 8. Setting up rootfs hash volume
727755
#
728756
echo "[ 8 ] Setting up rootfs hash volume"
729-
step::setup_rootfs_hash_lv "${boot_part}"
757+
step::setup_rootfs_hash_lv "${rootfs_file_path}" "${boot_part}"
730758

731759
#
732760
# 9. Cleaning up
@@ -736,6 +764,7 @@ main() {
736764
blockdev --flushbufs "${device}"
737765

738766
if [ "${operate_on_device}" == true ]; then
767+
echo "--------------------------------"
739768
echo "Everything done, the device is ready to use: ${device}"
740769
else
741770
#
@@ -756,9 +785,14 @@ main() {
756785
qemu-img convert -p -O qcow2 "${work_file}" "${output_file}"
757786
fi
758787

788+
echo "--------------------------------"
759789
echo "Everything done, the new disk image is ready to use: ${output_file}"
760790
fi
761791

792+
echo
793+
echo "You can calculate reference value of the disk with:"
794+
echo ""
795+
echo " cryptpilot fde show-reference-value --disk ${output_file}"
762796
}
763797

764798
main "$@"

0 commit comments

Comments
 (0)