LUKS (Linux Unified Key Setup) is the standard format for block device encryption on Linux. Data on a LUKS volume is encrypted with a random master key, and that key is itself protected by one or more passphrases or key files stored in key slots. Without one of them, the disk is unreadable, whether it is a detached volume, a leaked snapshot or a decommissioned drive. In this tutorial you will encrypt a secondary data disk on Ubuntu 24.04 with LUKS2, create a filesystem on it, choose between manual and automatic unlocking at boot, and manage key slots and header backups.

Prerequisites

To follow this tutorial, you need:

  • A server running Ubuntu 24.04 LTS, such as a CubePath VPS or a dedicated server.
  • A non-root user with sudo privileges.
  • A secondary, empty disk or partition to encrypt. This guide uses /dev/vdb; yours may be /dev/sdb or /dev/nvme1n1.

This guide encrypts a data disk on a running system. Encrypting the root filesystem requires choosing encryption in the installer, and a server with an encrypted root needs someone to type the passphrase on the console at every boot, which is rarely practical for a remote server.

Step 1 - Installing cryptsetup and identifying the disk

cryptsetup is the tool that creates and opens LUKS volumes. Install it:

sudo apt update
sudo apt install cryptsetup

Check the version and that the kernel supports the default cipher:

cryptsetup --version
cryptsetup 2.7.0 flags: UDEV BLKID KEYRING KERNEL_CAPI

List the block devices to find the disk to encrypt:

lsblk -l -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS
NAME    SIZE TYPE FSTYPE MOUNTPOINTS
vda      40G disk
vda1     39G part ext4   /
vda14     4M part
vda15   106M part vfat   /boot/efi
vda16   913M part ext4   /boot
vdb      50G disk

Here vdb is the empty 50 GB disk: it has no partitions, no filesystem and no mount point. If the disk shows an old filesystem that you no longer need, clear its signatures so tools do not detect stale data:

sudo wipefs -a /dev/vdb

Step 2 - Creating the LUKS volume

Initialise the disk as a LUKS volume. On Ubuntu 24.04, cryptsetup luksFormat creates LUKS2 with aes-xts-plain64 (AES-256 in XTS mode) and the memory-hard argon2id key derivation function by default, which are good choices:

sudo cryptsetup luksFormat /dev/vdb
WARNING!
========
This will overwrite data on /dev/vdb irrevocably.

Are you sure? (Type 'yes' in capital letters): YES
Enter passphrase for /dev/vdb:
Verify passphrase:

Type YES in capitals and choose a strong passphrase, for example five or six random words. Save it in your password manager: there is no way to recover data if you lose every passphrase and key file.

Confirm that the device is now a LUKS volume:

sudo cryptsetup luksDump /dev/vdb | head -n 12
LUKS header information
Version:        2
Epoch:          3
Metadata area:  16384 [bytes]
Keyslots area:  16744448 [bytes]
UUID:           3f6c1a7e-2b9d-4c55-9a1e-6d0b7e4f8c21
Label:          (no label)
Subsystem:      (no subsystem)
Flags:          (no flags)

Data segments:
  0: crypt

Further down, the output shows cipher: aes-xts-plain64 and a Keyslots section with slot 0 using argon2id. Note the UUID; you will use it in Step 5.

Step 3 - Opening the volume and creating a filesystem

Opening a LUKS volume asks for the passphrase and creates a decrypted device under /dev/mapper/ with the name you choose. Everything written to that mapped device is encrypted on its way to /dev/vdb:

sudo cryptsetup open /dev/vdb securedata

Check its status:

sudo cryptsetup status securedata
/dev/mapper/securedata is active.
  type:    LUKS2
  cipher:  aes-xts-plain64
  keysize: 512 bits
  key location: keyring
  device:  /dev/vdb
  sector size:  4096
  offset:  32768 sectors
  size:    104824832 sectors
  mode:    read/write

A 512-bit key in XTS mode means AES-256. Now create an ext4 filesystem on the mapped device, never on /dev/vdb directly:

sudo mkfs.ext4 -L securedata /dev/mapper/securedata

Create a mount point and mount it:

sudo mkdir -p /mnt/securedata
sudo mount /dev/mapper/securedata /mnt/securedata
df -h /mnt/securedata
Filesystem              Size  Used Avail Use% Mounted on
/dev/mapper/securedata   49G   24K   47G   1% /mnt/securedata

The usable size is slightly smaller than the disk because of the 16 MB LUKS header and filesystem overhead.

Step 4 - Closing the volume

To lock the data again, unmount the filesystem and close the mapping. After close, the data is unreadable until someone opens it with a valid key:

sudo umount /mnt/securedata
sudo cryptsetup close securedata
lsblk -f /dev/vdb
NAME FSTYPE      FSVER LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
vdb  crypto_LUKS 2           3f6c1a7e-2b9d-4c55-9a1e-6d0b7e4f8c21

The disk shows only as crypto_LUKS; the ext4 filesystem inside is invisible until the volume is opened.

Step 5 - Configuring mounting at boot

Decide how the volume should be unlocked when the server starts. There are two sensible options:

OptionUnlockProtects against
A: passphrase, manualYou open it after each bootStolen disk, snapshot, server compromised while locked
B: key file on the root diskAutomatic at bootThe data disk alone being detached, leaked or discarded

Option B is convenient, but anyone who can read both the root disk and the data disk can decrypt the data. Choose it when the threat is the data disk leaving your control on its own, not a full server compromise.

In both cases, the volume is described in /etc/crypttab (unlocking) and /etc/fstab (mounting). Use the UUID from Step 2 so that the configuration does not break if device names change. You can print it with sudo cryptsetup luksUUID /dev/vdb.

Option A - Manual unlock with a passphrase

Open /etc/crypttab:

sudo nano /etc/crypttab

Add the volume with the noauto option so boot does not wait for a passphrase that nobody is there to type:

securedata UUID=3f6c1a7e-2b9d-4c55-9a1e-6d0b7e4f8c21 none luks,noauto

Then add the mount to /etc/fstab:

sudo nano /etc/fstab
/dev/mapper/securedata /mnt/securedata ext4 defaults,noauto,nofail 0 2

noauto keeps it from being mounted at boot and nofail ensures a missing volume never blocks startup. Reload systemd so it reads the new entries:

sudo systemctl daemon-reload

After each reboot, unlock and mount the volume with:

sudo cryptsetup open /dev/vdb securedata
sudo mount /mnt/securedata

Option B - Automatic unlock with a key file

Create a random 4 KB key file readable only by root. The umask makes sure it is never created with looser permissions, even briefly:

sudo sh -c 'umask 077; dd if=/dev/urandom of=/root/securedata.key bs=4096 count=1'
sudo ls -l /root/securedata.key
-rw------- 1 root root 4096 Sep 25 11:02 /root/securedata.key

Add the key file to a free key slot of the volume. cryptsetup asks for your existing passphrase to authorise it:

sudo cryptsetup luksAddKey /dev/vdb /root/securedata.key
Enter any existing passphrase:

Add the volume to /etc/crypttab with the key file path in the third field:

sudo nano /etc/crypttab
securedata UUID=3f6c1a7e-2b9d-4c55-9a1e-6d0b7e4f8c21 /root/securedata.key luks

Add the mount to /etc/fstab:

sudo nano /etc/fstab
/dev/mapper/securedata /mnt/securedata ext4 defaults,nofail 0 2

Reload systemd and start the generated unlock unit and the mount to test the configuration without rebooting:

sudo systemctl daemon-reload
sudo systemctl start [email protected]
sudo mount -a
findmnt /mnt/securedata
TARGET          SOURCE                 FSTYPE OPTIONS
/mnt/securedata /dev/mapper/securedata ext4   rw,relatime

Finally, reboot and confirm the volume is mounted automatically with findmnt /mnt/securedata.

Step 6 - Managing key slots

A LUKS2 volume has up to 32 key slots, and any one of them unlocks it. Use this to give each person or system its own key and revoke it independently. List the slots in use:

sudo cryptsetup luksDump /dev/vdb | grep -A1 -E '^\s+[0-9]+: luks2'
  0: luks2
	Key:        512 bits
  1: luks2
	Key:        512 bits

Common operations:

  • Add a passphrase, for example a recovery passphrase stored offline: sudo cryptsetup luksAddKey /dev/vdb
  • Change a passphrase in place: sudo cryptsetup luksChangeKey /dev/vdb
  • Remove a passphrase by typing it: sudo cryptsetup luksRemoveKey /dev/vdb
  • Remove a slot by number when the passphrase is lost or compromised: sudo cryptsetup luksKillSlot /dev/vdb 1

Before removing anything, confirm that the key you are keeping works with a dry run that checks it without opening the device:

sudo cryptsetup open --test-passphrase /dev/vdb && echo "passphrase OK"
Enter passphrase for /dev/vdb:
passphrase OK

Step 7 - Backing up the LUKS header

The header at the start of the disk holds the key slots. If it is damaged, for example by an accidental mkfs on /dev/vdb instead of the mapped device, the data cannot be decrypted even with the right passphrase. Back it up:

sudo cryptsetup luksHeaderBackup /dev/vdb --header-backup-file /root/vdb-luks-header.img
sudo ls -lh /root/vdb-luks-header.img
-r-------- 1 root root 16M Sep 25 11:10 /root/vdb-luks-header.img

Copy the file to secure storage off the server, then delete the local copy. Keep in mind that the backup contains the key slots as they are now: anyone with the backup and a passphrase that is valid today can decrypt the disk, even if you later remove that passphrase. Make a new backup after changing keys and destroy the old one.

To restore a damaged header:

sudo cryptsetup luksHeaderRestore /dev/vdb --header-backup-file /root/vdb-luks-header.img

Troubleshooting

No key available with this passphrase. The passphrase is wrong, or you are opening the wrong device. Check the keyboard layout on consoles, and confirm the device with lsblk -f, which should show crypto_LUKS.

Device securedata is still in use when closing. The filesystem is still mounted or a process has files open in it. Check with findmnt /mnt/securedata and sudo lsof +f -- /mnt/securedata, stop the process, unmount, and close again.

Boot drops to emergency mode after editing crypttab or fstab. An entry is wrong and lacks nofail. Use the VNC console in your CubePath panel to log in, fix the file, and run sudo systemctl daemon-reload. Check the unlock unit with sudo journalctl -u [email protected].

Slow disk performance. Run cryptsetup benchmark to see how fast the CPU encrypts. Modern x86 and ARM CPUs have AES instructions and reach several GB/s with aes-xts, so encryption is rarely the bottleneck.

Conclusion

Your data disk is now encrypted with LUKS2 on Ubuntu 24.04, mounted either on demand or automatically with a key file, with a header backup and a plan for adding and revoking keys. As next steps, replace the key file with network-bound unlocking using Clevis and a Tang server if you manage several servers, encrypt your backups before they leave the server, and make sure the passphrase and header backup are stored where your team can reach them in an emergency.