How to create an encrypted LVM logical volume

An encrypted LVM logical volume keeps the storage layout flexible while requiring a LUKS passphrase before the filesystem can be mounted. Use this when a data volume needs LVM resizing or snapshot workflows without leaving the filesystem readable from the raw block device.

A new encrypted LV starts as a standard logical volume inside an existing volume group. The LUKS2 header lives on that LV, cryptsetup opens it as a dm-crypt mapper, and the filesystem is built on the mapper instead of on the raw LV. Applications mount /dev/mapper/securedata_crypt, while /dev/vgdata/securedata remains the encrypted backing device.

Choose the volume group, LV name, mapper name, filesystem type, and mount point before starting. Formatting with cryptsetup luksFormat and mkfs.xfs destroys data on the target device, so use a newly created LV or a device whose contents are intentionally being replaced, and keep the passphrase in the same password manager, vault, or recovery procedure used for other storage secrets.

Steps to create an encrypted LVM logical volume:

  1. Check free space in the target volume group.
    $ sudo vgs vgdata --options vg_name,vg_size,vg_free
      VG     VSize   VFree
      vgdata 100.00g 64.00g

    Replace vgdata with the existing volume group that should hold the encrypted logical volume.
    Related: How to create an LVM volume group

  2. Create a new logical volume for the encrypted data.
    $ sudo lvcreate --size 20G --name securedata vgdata
      Logical volume "securedata" created.

    Use a size that leaves enough free extents for future LVM changes. The new block device appears as /dev/vgdata/securedata.

  3. Confirm the new logical volume path.
    $ sudo lvs vgdata/securedata --options lv_name,lv_size,lv_path
      LV         LSize  Path
      securedata 20.00g /dev/vgdata/securedata
  4. Initialize a LUKS2 header on the logical volume.
    $ sudo cryptsetup luksFormat --type luks2 /dev/vgdata/securedata
    
    WARNING!
    ========
    This will overwrite data on /dev/vgdata/securedata irrevocably.
    
    Are you sure? (Type 'yes' in capital letters): YES
    Enter passphrase for /dev/vgdata/securedata:
    Verify passphrase:

    This step replaces any existing data on /dev/vgdata/securedata with a new encrypted container. Confirm the LV path before typing YES.

  5. Open the encrypted logical volume as a mapper device.
    $ sudo cryptsetup open /dev/vgdata/securedata securedata_crypt
    Enter passphrase for /dev/vgdata/securedata:

    The mapper name creates /dev/mapper/securedata_crypt for the current open session. Use the same mapper name in the filesystem and mount commands below.

  6. Check that the LUKS mapper is active and writable.
    $ sudo cryptsetup status securedata_crypt
    /dev/mapper/securedata_crypt is active.
      type:    LUKS2
      cipher:  aes-xts-plain64
      keysize: 512 [bits]
      device:  /dev/mapper/vgdata-securedata
      mode:    read/write
  7. Create the filesystem on the opened mapper device.
    $ sudo mkfs.xfs -L securedata /dev/mapper/securedata_crypt
    meta-data=/dev/mapper/securedata_crypt isize=512    agcount=4, agsize=1310720 blks
    ##### snipped #####
    realtime =none                   extsz=4096   blocks=0, rtextents=0

    Format the mapper device, not the raw /dev/vgdata/securedata LV. Formatting the raw LV after luksFormat would overwrite the LUKS header.

  8. Create the mount point.
    $ sudo mkdir --parents /srv/securedata
  9. Mount the encrypted filesystem.
    $ sudo mount /dev/mapper/securedata_crypt /srv/securedata

    Manual mounts do not survive reboot unless saved separately. For boot-time use, pair a crypttab entry for the encrypted LV with an /etc/fstab entry for the unlocked mapper.

  10. Confirm that the mount point uses the encrypted mapper device.
    $ findmnt --target /srv/securedata --output TARGET,SOURCE,FSTYPE
    TARGET          SOURCE                       FSTYPE
    /srv/securedata /dev/mapper/securedata_crypt xfs
  11. Write a test file through the mounted encrypted filesystem.
    $ echo "encrypted volume ready" | sudo tee /srv/securedata/status.txt
    encrypted volume ready
  12. Verify the encrypted backing LV and the filesystem layer.
    $ sudo blkid /dev/vgdata/securedata /dev/mapper/securedata_crypt
    /dev/vgdata/securedata: UUID="0ef33d66-4f5e-4f20-9273-693fdaed48cb" TYPE="crypto_LUKS"
    /dev/mapper/securedata_crypt: LABEL="securedata" UUID="fad3df77-ce1c-455d-b2ca-5a94945d22e5" BLOCK_SIZE="512" TYPE="xfs"

    The raw LV should report TYPE=“crypto_LUKS”, while the mapper device should report the filesystem type and label.