Migrating to an encrypted LVM physical volume

Read about a method for integrating unencrypted data into the infrastructure for protected volume encryption for an environment which uses LVM for volume management.

Before you begin

Prerequisite is an existing LVM volume group called MIGR_VOLGROUP as shown in Figure 1. This volume group at first comprises disk5 and disk6 with a capacity of 20 GB each, which are the unencrypted LVM physical volumes. The total available capacity of MIGR_VOLGROUP therefore comprises 40 GB. The space available on the new encrypted disks enc_disk7 and enc_disk8 is somewhat less than 40 GB, because the LUKS2 header occupies some physical space on them, which is not accessible from LV1 and LV2. Therefore, the total space of the LVM logical volumes LV1 and LV2 must be less than 40 GB. In our example, only 35 GB are allocated for LV1 and LV2, which leaves 5 GB free space. This is of course, much more than the LUKS2 headers will occupy.
Note: Check the physical block sizes of your source physical volumes. If the block sizes are smaller than the block sizes of your target physical volumes, the file systems on the logical volumes that reside on the source physical volumes might get corrupted during migration and your data might be lost. This is, because the file systems of the logical volumes are aligned to the block size of the source physical volumes. When moved to a target physical volume with a larger block size, the alignment is now incorrect and the data might become corrupt.

New LVM versions perform this check and reject actions that may corrupt the data.

The --sector-size parameter of a dm-crypt volume influences the physical block size. A dm-crypt volume encrypted with a sector size larger than the default 512 bytes results in a device with a physical block size of either the used sector size or the block size of the underlying device, whatever is higher. Therefore, take care to format your target volume with a sector size equal to the block size of your source volume.

To query the physical block size of a device, use the following command:

# blockdev --getpbsz <device>

For information about valid block size combinations between volumes involved in the infrastructure for protected volume encryption refer to Valid physical block size combinations of LVM physical volumes.

Use the pvs, lvs, and cat commands as shown to verify the existing sample set up:

# pvs
  PV                    VG            Fmt  Attr PSize   PFree
  /dev/mapper/disk5     MIGR_VOLGROUP lvm2 a--  <20.00g     0
  /dev/mapper/disk6     MIGR_VOLGROUP lvm2 a--  <20.00g  4.99g

# lvs
  LV   VG            Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  LV1  MIGR_VOLGROUP -wi-a----- 20.00g
  LV2  MIGR_VOLGROUP -wi-a----- 15.00g

# cat /etc/fstab
/dev/mapper/MIGR_VOLGROUP-LV1 /migr_lv1 ext4 defaults 0 0
/dev/mapper/MIGR_VOLGROUP-LV2 /migr_lv2 ext4 defaults 0 0

About this task

In step 7 of this scenario you create two new encrypted LVM physical volumes enc_disk7 and enc_disk8 as a target for the encrypted data and integrate them into the MIGR_VOLGROUP LVM volume group. Then you migrate the unencrypted volumes disk5 and disk6 to the encrypted ones. Finally, you remove the unencrypted volumes from the volume group.
Figure 1. Migration scenario
Migrating to an encrypted LVM physical volume

Procedure

  1. Create a new secure key in the secure key repository for encrypting volumes for use as LVM physical volumes in the volume group MIGR_VOLGROUP.
    To do so, issue the following commands:
    # zkey generate --name secure_xtskey7 --key-type CCA-AESCIPHER --keybits 256 --xts \
    --volumes /dev/mapper/disk7:enc-disk7 --volume-type LUKS2 \
    --apqns 03.0039,04.0039  
    
    # zkey generate --name secure_xtskey8 --key-type CCA-AESCIPHER --keybits 256 --xts \
    --volumes /dev/mapper/disk8:enc-disk8 --volume-type LUKS2 \
    --apqns 03.0039,04.0039
    Note: In this procedure, it is assumed that the unencrypted source volumes have a physical block size of 512 bytes. Therefore, you should format the encrypted target volumes enc-disk7 and enc-disk8 with sector size 512, too, to ensure a successful migration. Only if you are sure that the unencrypted source volumes already have a physical block size of 4096 bytes (or more), you can add parameter
    --sector-size 4096
    to both shown zkey generate commands.
  2. Generate the commands to format the volumes to be encrypted using cryptsetup. The formatting process writes the LUKS2 header onto the volumes.
    Invoke the zkey cryptsetup command for the first volume as follows:
    
    # zkey cryptsetup --volumes /dev/mapper/disk7
    
    cryptsetup luksFormat --type luks2 --pbkdf pbkdf2 
    --master-key-file '/etc/zkey/repository/secure_xtskey7.skey'
    --key-size 2176 --cipher paes-xts-plain64 /dev/mapper/disk7
    
    zkey-cryptsetup setvp /dev/mapper/disk7
    Two commands are generated:
    • the cryptsetup luksFormat command to format the volume
    • the zkey-cryptsetup setvp command to set the verification pattern into the LUKS2 header. The verification pattern is used to identify the valid effective key during recovery actions.
  3. Run the generated commands.
    Copy and paste the generated commands into the command line. Alternatively, you can skip this step if you run the zkey cryptsetup command from step 2 using the --run.
    Note: If the you use an older distribution, the --pbkdf pbkdf2 option may be missing in the generated command. In such a case, edit the command by adding option --pbkdf pbkdf2. This is to avoid an out-of-memory error for a LUKS2 volume during automated opening via /etc/crypttab at system startup. For more information, see Out-of-memory errors when opening a LUKS2 volume.
    # cryptsetup luksFormat --type luks2 --pbkdf pbkdf2 \ 
    --master-key-file '/etc/zkey/repository/secure_xtskey7.skey' \
    --key-size 2176 --cipher paes-xts-plain64 /dev/mapper/disk7
    
    WARNING!
    ========
    This will overwrite data on /dev/mapper/disk7 irrevocably.
    
    Are you sure? (Type uppercase yes): YES
    Enter passphrase for /dev/mapper/disk7: disk7pw 
    Verify passphrase: disk7pw
    
    # zkey-cryptsetup setvp /dev/mapper/disk7
    Enter passphrase for '/dev/mapper/disk7': disk7pw
    
    When you type the passphrases, these are not displayed.

    Repeat this for disk8 accordingly.

  4. Open the volumes:
    
    # cryptsetup luksOpen /dev/mapper/disk7 enc-disk7
    # cryptsetup luksOpen /dev/mapper/disk8 enc-disk8
    
    
    Alternatively, you can use the zkey cryptsetup command with option --open (and with option --run) to generate (and run) the luksOpen commands:
    # zkey cryptsetup --volumes /dev/mapper/disk7 --open [--run]
    # zkey cryptsetup --volumes /dev/mapper/disk8 --open [--run]
  5. Create a key file and specify it in an entry in /etc/crypttab to persistently configure the opening at system startup.
    1. Create the key file named disk7.key in directory /etc/luks_keys/ with random content with a size of 4096 bytes, specified by bs=1024 count=4. If the directory does not yet exist, you must create it first.
      # dd if=/dev/urandom of=/etc/luks_keys/disk7.key bs=1024 count=4
      # chmod 0400 /etc/luks_keys/disk7.key

      The second command makes the key file readable by the root user only. Repeat these commands for each volume appropriately.

    2. Add a key slot with the previously generated key file.
      # cryptsetup luksAddKey --pbkdf pbkdf2 /dev/mapper/disk7 /etc/luks_keys/disk7.key
      You must also specify option --pbkdf pbkdf2 with the luksAddKey command to avoid an out-of-memory error for a LUKS2 volume during automated opening via /etc/crypttab at system startup. For more information, see Out-of-memory errors when opening a LUKS2 volume.
    3. Edit /etc/crypttab and add one entry for each encrypted volume:
      
      # /etc/crypttab
      #
      # See crypttab(5) for more information.
      #
      # <target name> <source device>         <key file>                  <options>
        enc-disk7     /dev/mapper/disk7       /etc/luks_keys/disk7.key    luks       
        enc-disk8     /dev/mapper/disk8       /etc/luks_keys/disk8.key    luks
       
      The format of the /etc/crypttab file depends on your Linux® distribution. See the crypttab man page for more details.

      Alternatively you can have a skeleton for a crypttab entry automatically generated by the zkey crypttab command:

      # zkey crypttab --volumes /dev/mapper/disk<n>

      You only need to add the <key file> column manually. You can, however, specify the key file with the command, then you do not need to add the<key file> column manually:

      # zkey crypttab --volumes /dev/mapper/disk<n> --key-file /etc/luks_keys/disk<n>.key
  6. Create the target LVM physical volumes to which you want to migrate the encrypted data.
    
    # pvcreate /dev/mapper/enc-disk7
    # pvcreate /dev/mapper/enc-disk8
  7. Extend the volume group MIGR_VOLGROUP by adding the two encrypted physical volumes. Display the result using the pvs command.
    # vgextend MIGR_VOLGROUP /dev/mapper/enc-disk7 /dev/mapper/enc-disk8
    
    # pvs
      PV                    VG            Fmt  Attr PSize   PFree
      /dev/mapper/disk5     MIGR_VOLGROUP lvm2 a--  <20.00g     0
      /dev/mapper/disk6     MIGR_VOLGROUP lvm2 a--  <20.00g  4.99g
      /dev/mapper/enc-disk7 MIGR_VOLGROUP lvm2 a--   19.99g 19.99g
      /dev/mapper/enc-disk8 MIGR_VOLGROUP lvm2 a--   19.99g 19.99g
    
     
    The physical size (PSize) of 19.99 GB for enc-disk7 and enc-disk8 (instead of 20.00 GB) is due to the LUKS2 header information stored on these volumes.
  8. Move the content from the unencrypted physical volumes disk5 and disk6 to the encrypted physical volumes enc-disk7 and enc-disk8 using the pvmove command.
    This step requires several sub-steps. This is due to the fact that the encrypted physical volumes enc_disk7 and enc_disk8 are somewhat smaller than disk5 and disk6, because the LUKS2 header occupies a small amount of space that is not available to the encrypted physical volume. Thus, trying to move disk5 onto enc_disk7 would fail. Instead, use the approach described in the following sub-steps that allows LVM to move the data to any available space on the physical volumes belonging to the MIGR_VOLGROUP volume group.
    Note: The described scenario only works if the total space occupied on the unencrypted physical volumes (disk5 and disk6) is less or equal to the space available on the encrypted physical volumes enc_disk7 and enc_disk8; that is, if the MIGR_VOLGROUP volume group uses less than two times 19.99 GB (= 39.98 GB). In this scenario, only 35 GB are used. If the volume group would occupy the full 40 GB, then another encrypted physical volume (for example, /dev/mapper/enc-disk9) would be required or disk7 and disk8 must be larger 20 GB.
    1. Move the physical content from disk5 onto some other physical volume somewhere within the same LVM volume group.
      Type the following pvmove command without specifying a target. If you verify the result with the pvs command, and compare it with the pvs output from step 7, you see that in our scenario, the biggest portion of disk5 was moved to enc_disk7, which no longer has physical free space (PFree = 0). The rest of disk5 was moved to disk6, whose free space decreased from PFree = 4.99g to PFree <4.99g.
      # pvmove /dev/mapper/disk5
      
      /dev/mapper/disk5: Moved: 0.04%
      /dev/mapper/disk5: Moved: 9.53%
      ...
      /dev/mapper/disk5: Moved: 100.00%
      
      # pvs
        PV                    VG            Fmt  Attr PSize   PFree
        /dev/mapper/disk5     MIGR_VOLGROUP lvm2 a--  <20.00g <20.00g
        /dev/mapper/disk6     MIGR_VOLGROUP lvm2 a--  <20.00g  <4.99g
        /dev/mapper/enc-disk7 MIGR_VOLGROUP lvm2 a--   19.99g      0
        /dev/mapper/enc-disk8 MIGR_VOLGROUP lvm2 a--   19.99g  19.99g
      
      
    2. Remove disk5 from the MIGR_VOLGROUP volume group.
      # vgreduce MIGR_VOLGROUP /dev/mapper/disk5
        Removed "/dev/mapper/disk5" from volume group "MIGR_VOLGROUP"
    3. Now move disk6 onto some other physical volume within MIGR_VOLGROUP and verify the result as shown in step 8.a:
      # pvmove /dev/mapper/disk6
      /dev/mapper/disk6: Moved: 0.03%
      /dev/mapper/disk6: Moved: 0.05%
      ...
      /dev/mapper/disk6: Moved: 100.00%
      
    4. Remove disk6 from the MIGR_VOLGROUP volume group:
      vgreduce MIGR_VOLGROUP /dev/mapper/disk6
        Removed "/dev/mapper/disk6" from volume group "MIGR_VOLGROUP"
      
      Verify the result with the pvs command to see that disk5 and disk6 are free and the encrypted volumes enc_disk7 and enc_disk8 are used ( PFree = 0 / PFree = 4.98g
      # pvs
        PV                    VG            Fmt  Attr PSize  PFree
        /dev/mapper/disk5                   lvm2 ---  20.00g 20.00g
        /dev/mapper/disk6                   lvm2 ---  20.00g 20.00g
        /dev/mapper/enc-disk7 MIGR_VOLGROUP lvm2 a--  19.99g     0
        /dev/mapper/enc-disk8 MIGR_VOLGROUP lvm2 a--  19.99g  4.98g

Results

After migrating all unencrypted physical volumes to encrypted ones, you achieve a transparent encryption of all data in the MIGR_VOLGROUP LVM volume group. The pvs command from step 8.d shows that the source LVM physical volumes disk5 and disk6 are now completely free (20.00g in both PFree and PSize), and the corresponding encrypted target LVM physical volumes enc-disk7 and enc-disk8 are respectively written with data.

What to do next

For security reasons you should next remove the unencrypted source volumes disk5 and disk6 from LVM:

pvremove /dev/mapper/disk5
pvremove /dev/mapper/disk6

Finally, you should securely delete all data from these unencrypted volumes.