This guide walks you through encrypting a bootable OS disk with full disk encryption.
- cryptpilot-fde-host installed on your system
- A bootable qcow2 disk image, or an unmounted real disk
Before encrypting, you need to prepare a configuration directory with at least one fde.toml file. The configuration directory structure is similar to /etc/cryptpilot/.
For this demo, we'll use the exec key provider with a hardcoded passphrase:
Important
The exec key provider below is only for demo purposes. Use kbs or kms in production.
mkdir -p ./config_dir
cat << EOF > ./config_dir/fde.toml
[rootfs]
delta_location = "disk"
[rootfs.encrypt.exec]
command = "echo"
args = ["-n", "AAAaaawewe222"]
[delta]
integrity = true
[delta.encrypt.exec]
command = "echo"
args = ["-n", "AAAaaawewe222"]
EOF
tree ./config_dirThe configuration directory structure:
./config_dir
└── fde.tomlConfiguration Explanation:
[rootfs]: Root filesystem configurationdelta_location = "disk": Store writable overlay on delta partition (survives reboot)encrypt.exec: Use exec provider with passphrase "AAAaaawewe222"
[delta]: Delta partition configurationintegrity = true: Enable dm-integrity for data authenticityencrypt.exec: Use exec provider with passphrase "AAAaaawewe222"
Check if your configuration is valid:
cryptpilot-fde-host -c ./config_dir/ config check --keep-checkingThis example shows how to encrypt an existing bootable disk image.
We'll use the Alibaba Cloud Linux 3 disk image:
wget https://alinux3.oss-cn-hangzhou.aliyuncs.com/aliyun_3_x64_20G_nocloud_alibase_20251030.qcow2Encrypt the disk image with the prepared configuration:
cryptpilot-convert --in ./aliyun_3_x64_20G_nocloud_alibase_20251030.qcow2 \
--out ./encrypted.qcow2 \
-c ./config_dir/ \
--rootfs-passphrase AAAaaawewe222What happens during encryption:
- Reads the original disk image
- Creates encrypted rootfs partition with dm-verity
- Creates encrypted delta partition with dm-integrity
- Installs the cryptpilot-fde-guest RPM into the guest rootfs (includes dracut module for initrd)
- Configures boot loader for encrypted boot
- Writes the encrypted disk to output file
Optional: You can install additional packages during encryption:
cryptpilot-convert --in ./source.qcow2 --out ./encrypted.qcow2 \
-c ./config_dir/ \
--rootfs-passphrase AAAaaawewe222 \
--package /path/to/package.rpmLaunch a VM to test the encrypted disk:
# Install qemu-kvm
yum install -y qemu-kvm
# Download seed image for cloud-init
wget https://alinux3.oss-cn-hangzhou.aliyuncs.com/seed.img
# Launch VM
/usr/libexec/qemu-kvm \
-m 4096M \
-smp 4 \
-nographic \
-drive file=./encrypted.qcow2,format=qcow2,if=virtio,id=hd0,readonly=off \
-drive file=./seed.img,if=virtio,format=rawLogin credentials: Username:
alinux, Password:aliyun
Exit QEMU: Press Ctrl-A then C to enter QEMU console, then type quit.
For attestation purposes, calculate cryptographic reference values:
cryptpilot-fde-host show-reference-value --disk ./encrypted.qcow2This outputs measurement values that can be uploaded to Reference Value Provider Service (RVPS).
Upload the encrypted disk image to your cloud provider (e.g., Alibaba Cloud) and boot from it.
For some scenarios, you may only need integrity protection and measurement for rootfs without encryption. In this case, rootfs uses dm-verity protection but is not encrypted.
Note
This mode is suitable for scenarios where:
- rootfs contains no sensitive data
- Only integrity validation and measurement are needed, not confidentiality
- Reduced performance overhead during boot is desired
Create configuration without rootfs encryption:
mkdir -p ./config_dir
cat << EOF > ./config_dir/fde.toml
[rootfs]
delta_location = "disk"
# Note: No encrypt configuration in rootfs section
[delta]
integrity = true
[delta.encrypt.exec]
command = "echo"
args = ["-n", "AAAaaawewe222"]
EOFConfiguration Explanation:
[rootfs]: Root filesystem configurationdelta_location = "disk": Store writable overlay on delta partition- No
encryptconfiguration: rootfs is not encrypted, only dm-verity integrity protection
[delta]: Delta partition configurationintegrity = true: Enable dm-integrityencrypt.exec: Delta partition is still encrypted
Use the --rootfs-no-encryption parameter:
cryptpilot-convert --in ./aliyun_3_x64_20G_nocloud_alibase_20251030.qcow2 \
--out ./encrypted.qcow2 \
-c ./config_dir/ \
--rootfs-no-encryptionWhat happens:
- rootfs uses dm-verity for integrity protection (not encrypted)
- Delta partition is encrypted normally
- System still performs measurement and attestation during boot
- rootfs is mounted read-only with writable overlay layer
This configuration is suitable for:
- ✅ rootfs contains only public system files
- ✅ Need to verify system integrity (tamper detection)
- ✅ Need remote attestation to confirm system is unmodified
- ✅ Want to reduce decryption performance overhead for rootfs
- ❌ Not suitable when rootfs contains sensitive configurations or keys
Calculate reference values for measure-only mode:
cryptpilot-fde-host show-reference-value --disk ./encrypted.qcow2The output contains multiple measurement values (kernel, initrd, cmdline, etc.), all of which need to be imported to RVPS.
UKI (Unified Kernel Image) mode packages the kernel, initrd, and boot parameters into a single EFI executable. Combined with measure-only rootfs (no encryption), it enables fast boot and simplified remote attestation.
Note
UKI Mode Features:
- Single UKI file contains all boot components
- Measure-only without encryption for faster boot
- Reference value contains only UKI measurement, simpler verification
- Suitable for scenarios requiring fast boot and simplified attestation
Create UKI mode configuration (rootfs not encrypted, delta encrypted):
mkdir -p ./config_dir
cat << EOF > ./config_dir/fde.toml
[rootfs]
delta_location = "disk"
# rootfs not encrypted, measure only
[delta]
integrity = true
[delta.encrypt.exec]
command = "echo"
args = ["-n", "AAAaaawewe222"]
EOFConfiguration Explanation:
[rootfs]: Root filesystem measure-only without encryptiondelta_location = "disk": Writable overlay stored on delta partition- No
encryptconfiguration: rootfs uses dm-verity integrity protection
[delta]: Delta partition encrypted- Protects user data and system changes
cryptpilot-convert --in ./aliyun_3_x64_20G_nocloud_alibase_20251030.qcow2 \
--out ./uki-encrypted.qcow2 \
-c ./config_dir/ \
--rootfs-no-encryption \
--ukiParameter Explanation:
--rootfs-no-encryption: rootfs measure-only without encryption--uki: Generate UKI unified kernel image
UKI mode reference values contain only UKI measurement, making verification simpler:
cryptpilot-fde-host show-reference-value --disk ./uki-encrypted.qcow2Example output:
{
"measurement.uki.SHA-384": [
"a46e162a57e072be7f660e65504477c646acf6b3bfea4ffc0e3a8ee4f2c2726c2284c8bf1ec2b3bd95b204fe7f4e899c"
]
}For production systems, you need to encrypt a real disk.
Important
DO NOT encrypt the active disk you are booting from!
You must:
- Unbind the disk from the instance
- Bind it to another instance as a data disk
- Encrypt it
- Re-bind it to the original instance
- Prepare configuration (same as above):
mkdir -p ./config_dir
cat << EOF > ./config_dir/fde.toml
[rootfs]
delta_location = "disk"
[rootfs.encrypt.exec]
command = "echo"
args = ["-n", "AAAaaawewe222"]
[delta]
integrity = true
[delta.encrypt.exec]
command = "echo"
args = ["-n", "AAAaaawewe222"]
EOF- Validate configuration:
cryptpilot-fde-host -c ./config_dir/ config check --keep-checking- Encrypt the disk (assuming the disk is
/dev/nvme2n1):
cryptpilot-convert --device /dev/nvme2n1 \
-c ./config_dir/ \
--rootfs-passphrase AAAaaawewe222- Re-bind the disk to the original instance and boot from it.
For production environments, use Key Broker Service with remote attestation.
mkdir -p ./config_dir
cat << EOF > ./config_dir/fde.toml
[rootfs]
delta_location = "disk"
[rootfs.encrypt.kbs]
url = "https://kbs.example.com"
resource_path = "/secrets/rootfs-key"
[delta]
integrity = true
[delta.encrypt.kbs]
url = "https://kbs.example.com"
resource_path = "/secrets/data-key"
EOF# For disk images
cryptpilot-convert --in ./original.qcow2 --out ./encrypted.qcow2 \
-c ./config_dir/ --rootfs-passphrase <actual-rootfs-key>
# For real disks
cryptpilot-convert --device /dev/nvme2n1 \
-c ./config_dir/ --rootfs-passphrase <actual-rootfs-key>When booting, the system will:
- Generate attestation evidence in TEE
- Send evidence to KBS
- KBS verifies the evidence
- If verified, KBS returns the decryption key
- System decrypts and boots
For Alibaba Cloud users, use KMS for centralized key management.
mkdir -p ./config_dir
cat << EOF > ./config_dir/fde.toml
[rootfs]
delta_location = "disk"
[rootfs.encrypt.kms]
kms_instance_id = "kst-****"
client_key_id = "LTAI****"
client_key_password_from_kms = "alias/ClientKey_****"
[delta]
integrity = true
[delta.encrypt.kms]
kms_instance_id = "kst-****"
client_key_id = "LTAI****"
client_key_password_from_kms = "alias/ClientKey_****"
EOFcryptpilot-convert --in ./original.qcow2 --out ./encrypted.qcow2 \
-c ./config_dir/ --rootfs-passphrase <from-kms>If you're not on a supported distribution, use Docker:
modprobe nbd max_part=8docker run -it --privileged --ipc=host \
-v /run/udev/control:/run/udev/control \
-v /dev:/dev \
alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/alinux3:latest bashNote: The additional parameters (
--privileged --ipc=host -v /run/udev/control:/run/udev/control -v /dev:/dev) are required to make/devwork properly in the container.
Inside the container, download and install cryptpilot-fde from the Release page:
# Download the latest RPM package
wget https://github.com/openanolis/cryptpilot/releases/download/vX.Y.Z/cryptpilot-fde-X.Y.Z-1.x86_64.rpm
# Install
rpm -ivh cryptpilot-fde-X.Y.Z-1.x86_64.rpmTip: Replace
X.Y.Zwith the actual version number.
cryptpilot-fde-host --help
cryptpilot-convert --helpNow you can run any cryptpilot-fde-host commands inside the container.
If config check reports errors:
cryptpilot-fde-host -c ./config_dir/ config check --keep-checkingCommon issues:
- Missing required fields in configuration
- Invalid key provider settings
- Incorrect file paths
If cryptpilot-convert fails:
- Check disk format: Only qcow2 images are supported for disk images
- Check disk size: Ensure enough space for encryption overhead
- For real disks: Ensure the disk is unmounted and not in use
- Device already exists error: If you see errors like
/dev/cryptpilot: already exists in filesystem, it may be leftover from a previous failed convert. Trydmsetup remove_allto clean up - Check logs: The last convert's detailed log is saved at
/tmp/.cryptpilot-convert.log
If the encrypted system fails to boot:
- Check key provider: Ensure network/attestation is working
- Check reference values: Verify measurements match expected values
- Check console output: Look for error messages during boot
- Configuration Guide - Detailed configuration options
- Boot Process - How cryptpilot-fde integrates with boot
- Key Providers - Key provider configuration details
- cryptpilot-enhance - Harden images before encryption
- cryptpilot-crypt Quick Start - Encrypt delta volumes
- Development Guide - Build and test instructions