10.10. Managing Container Virtual Hard Disk Encryption¶
Virtuozzo Hybrid Server offers container virtual hard disk encryption capabilities based on dm-crypt
and cryptsetup
. The current implementation uses the AES-256 encryption algorithm. The encryption mechanism is separated from encryption key management, enabling you to use your own key management system (KMS) to issue and manage encryption keys.
Important
Only the root user must have access to encryption operations on the host.
The overall encryption procedure may be described as follows. An end user requests encryption for their container disk (create a new container with an encrypted disk, encrypt an existing disk, etc.). The KMS stores a secret encryption key and a public encryption key ID assigned to the end user. The administrator (or an automation tool) obtains the end user’s encryption key ID from the KMS and passes it to the corresponding prlctl
command. The prlctl
command passes the key ID to the getkey
executable that accesses the KMS and returns the encryption key which is passed to cryptsetup
. The cryptsetup
tool issues a master key unique for the container disk, encrypts the disk contents with the master key, then encrypts the master key stored in container disk’s LUKS header with the encryption key passed from getkey
.
The double encryption saves host resources in situations when the encryption key has to be changed (e.g., for key rotation purposes). In such cases, only the master key in the LUKS header has to be re-encrypted instead of the entire disk contents.
The only configuration step required to start using container disk encryption capabilities in Virtuozzo Hybrid Server is to set up the encryption key requester as described further to be able to obtain encryption keys by their IDs for corresponding prlctl
commands.
10.10.1. Setting Up Encryption Key Requester¶
The encryption mechanism communicates with the KMS as follows: executes the file /usr/libexec/ploop/crypt.d/getkey
with the only string parameter–encryption key ID–and reads the returned encryption key value from the standard output. The getkey
executable can be a script that calls the KMS binary and passes the specified encryption key ID to it.
On success, the executable is expected to exit with zero code and the key value is expected to be printed to the standard output in the binary form. On failure, the script is expected to exit with non-zero code.
Note
Key value may contain arbitrary bytes (e.g., \x00
, \n
, and such) that may be treated differently by various scripting languages. For example, assigning the key value to a Bash variable would strip the zero bytes from it, e.g., key_va\x00lue
would become key_value
.
To set up the encryption key requester on a Virtuozzo Hybrid Server host, place the script to /usr/libexec/ploop/crypt.d/getkey
and make it executable and only accessible by the root user:
# chown root:root /usr/libexec/ploop/crypt.d/getkey
# chmod 700 /usr/libexec/ploop/crypt.d/getkey
10.10.2. Encrypting and Decrypting Container Virtual Hard Disks¶
Following is a list of encryption-related operations you can perform on container virtual hard disks. All operations except decrypt require an encryption key ID obtained from your KMS.
Note
PFCache is disabled for encrypted disks.
Create a container with an encrypted root disk.
# prlctl create <CT_name|CT_UUID> --vmtype ct --encryption-keyid <key_id>
Add a new encrypted disk to a container.
# prlctl set <CT_name|CT_UUID> --device-add hdd --encryption-keyid <key_id>
Encrypt an unencrypted disk. During this operation, a new empty encrypted disk is created, the data is moved to it from the unencrypted disk which is then securely erased with
shred
(unless--no-wipe
is added). For this operation, the host needs free disk space equal to the size of the container disk being encrypted.# prlctl set <CT_name|CT_UUID> --device-set hdd0 --encrypt --encryption-keyid <key_id> \ [--no-wipe]
Change the encryption key ID of an encrypted disk with or without re-encrypting the entire disk contents. By default, only the LUKS header of an encrypted disk is re-encrypted to save host resources. The entire disk contents can be re-encrypted by adding
--reencrypt
to the command. During this operation, a new empty encrypted disk is created, the data is moved to it from the old encrypted disk which is then securely erased withshred
(unless--no-wipe
is added). For this operation, the host needs free disk space equal to the size of the container disk being re-encrypted.# prlctl set <CT_name|CT_UUID> --device-set hdd0 --encryption-keyid <key_id> [--reencrypt] \ [--no-wipe]
Decrypt an encrypted container disk. During this operation, a new empty unencrypted disk is created and the data is moved to it from the encrypted disk. If the operation completes successfully, the encrypted disk is deleted. If the operation fails, the partially decrypted data is securely erased with
shred
(unless--no-wipe
is added) and the encrypted disk remains intact. For this operation, the host needs free disk space equal to the size of the container disk being decrypted.# prlctl set <CT_name|CT_UUID> --device-set hdd0 --decrypt [--no-wipe]
10.10.3. Encrypting System Swap¶
Even if containers are encrypted, their memory may still be swapped to an unencrypted system swap partition. On nodes intended to run encrypted containers, consider encrypting the swap partition as well.
To encrypt a swap partition with a random encryption key, do the following:
Identify swap partitions in the system:
# swapon -s Filename Type Size Used Priority /dev/<partition> partition XXXXXXX 0 -1
Add a swap partition’s entry to the
/etc/crypttab
file. For example:swap /dev/<partition> /dev/urandom swap,noearly
Once the encryption is initiated, this will map the
/dev/<partition>
to/dev/mapper/swap
as an encrypted swap partition.Note
To create an encryption key, you may use
/dev/random
instead of/dev/urandom
. However, in this case, the system may take a long time to boot.Find out the UUID of the swap partition:
# blkid /dev/<partition> /dev/<partition>: UUID="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" TYPE="swap"
Comment the swap partition’s entry in the
/etc/fstab
file and add an entry for the mapped/dev/mapper/swap
file. For example:#UUID=<partition_UUID> swap swap defaults 0 0 /dev/mapper/swap none swap sw 0 0
Reboot to initiate the encryption.
Run the
lsblk
command to ensure the swap is encrypted. In the output, the swap partition’sTYPE
should becrypt
.# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT ... └─<swap_partition> X:X 0 XG 0 crypt [SWAP] ...
The output of
swapon -s
will show a different filename:# swapon -s Filename Type Size Used Priority /dev/dm-X partition XXXXXXX 0 -1