Skip to content

LUKS Disk Encryption

Every tool covered in LVM: Resizing and Snapshots — RAID, LVM, filesystems — helps organize and manage data, but none of them protect it once the disk itself falls into the wrong hands. If a laptop is stolen or an old disk is discarded, any file on an unencrypted disk can be read with a plain mount command. LUKS (Linux Unified Key Setup) — Linux's standard block-level disk encryption system — solves exactly this problem.

Where LUKS sits relative to other layers matters: encryption can be applied either below or above LVM. This article covers both approaches and their trade-offs, then bridges to how an ordinary filesystem is created on top of an encrypted device, continuing in Filesystem Types.

What You Will Learn

By the end of this article you will be able to:

  • explain how LUKS block-level encryption works and what it protects against;
  • create a new encrypted device with cryptsetup luksFormat;
  • open and close an encrypted device with cryptsetup open/close;
  • configure automatic unlocking at boot through /etc/crypttab;
  • manage keys through a passphrase and a keyfile, including adding multiple keys;
  • judge the difference between LUKS-on-LVM and LVM-on-LUKS and when to choose each.

What LUKS Is and What It Protects Against

LUKS is an encryption standard that operates at the block device level: it encrypts an entire partition or LV, not a specific file. An encrypted device becomes a usable, ordinary block device only after being "unlocked" with the correct key (a passphrase or keyfile).

LUKS protects against:

  • a stolen or lost disk or laptop — the disk can't be read without the key, even if attached to another computer;
  • discarding an old disk — a disk can be safely thrown away without wiping it first, since the data can't be read without the key.

LUKS does not protect against:

  • an attacker (for example, over SSH) while the system is running and the disk is unlocked — in that state, data is exposed just like an ordinary filesystem;
  • data theft through malware or misconfigured permissions;
  • data loss (disk failure, accidental deletion) — that's the job of RAID and backups.

Info

LUKS protects data at rest, not data in transit. While the system is running and the disk is unlocked, LUKS operates transparently — every write/read operation is automatically encrypted/decrypted, unnoticed by the user.

Required Package

On the Debian/Ubuntu family:

sudo apt update
sudo apt install cryptsetup

cryptsetup is the primary tool for working with LUKS; subcommands like luksFormat, open, close, and luksAddKey all run under this program.

Creating an Encrypted Device

Suppose /dev/sdb1 is an empty partition to be encrypted.

Danger

cryptsetup luksFormat irreversibly erases existing data on the disk (once the LUKS header is written, access to the old data is gone). Run this command only on an empty, unused partition, ideally in a disposable test VM. Double-check the device name (lsblk, blkid) before using this on a production disk, and confirm any needed data is backed up.

1. Inspection (read-only)

lsblk
sudo cryptsetup luksDump /dev/sdb1

luksDump shows whether the partition has a LUKS header — if it returns an error (Device /dev/sdb1 is not a valid LUKS device), the partition isn't encrypted yet.

2. Formatting with LUKS

sudo cryptsetup luksFormat /dev/sdb1

The command asks for a passphrase and its confirmation. cryptsetup requires typing the confirmation in capital letters (Are you sure? (Type 'yes' in capital letters)), which prevents an accidental run.

Checking the result:

sudo cryptsetup luksDump /dev/sdb1

The result shows the LUKS version (usually LUKS2, the default on modern distributions), the encryption algorithm (e.g. aes-xts-plain64), and the list of key slots.

3. Opening the Encrypted Device

sudo cryptsetup open /dev/sdb1 crypt_data
  • /dev/sdb1 — the raw encrypted partition;
  • crypt_data — the name assigned to the device once opened (the mapping name).

Once the correct passphrase is entered, the decrypted device appears at:

/dev/mapper/crypt_data

Checking:

lsblk

An extra layer named crypt_data appears under sdb1 — the same device-mapper mechanism as /dev/mapper/vg_data-lv_app in LVM.

4. Creating a Filesystem and Mounting It

A filesystem is created on the decrypted device just like on an ordinary partition:

sudo mkfs.ext4 /dev/mapper/crypt_data
sudo mkdir -p /mnt/secure
sudo mount /dev/mapper/crypt_data /mnt/secure

Once done, close the device securely:

sudo umount /mnt/secure
sudo cryptsetup close crypt_data

After close, /dev/mapper/crypt_data disappears, and /dev/sdb1 goes back to being an encrypted, unreadable raw partition.

Key Management: Passphrase and Keyfile

LUKS can hold multiple keys (key slots) — LUKS2 typically supports up to 32. This allows a single device to be unlocked by several users, or by several methods (passphrase + keyfile).

Adding an Additional Passphrase

sudo cryptsetup luksAddKey /dev/sdb1

The command first asks for an existing passphrase (to confirm), then the new one.

Creating and Adding a Keyfile

A keyfile is a random file used in place of a passphrase, convenient for unattended, automated unlocking:

sudo dd if=/dev/urandom of=/root/luks-keyfile bs=1024 count=4
sudo chmod 400 /root/luks-keyfile
sudo cryptsetup luksAddKey /dev/sdb1 /root/luks-keyfile

The device can now also be opened with the keyfile:

sudo cryptsetup open /dev/sdb1 crypt_data --key-file /root/luks-keyfile

Danger

Every key slot independently grants full access to the device. A keyfile is as sensitive as a password — store it with root-only read permission (chmod 400), and never on another, unencrypted disk or in a version control system (git).

Revoking a Key

If a key is lost or suspected to be compromised, it can be removed — but confirm at least one other working key still exists first:

sudo cryptsetup luksRemoveKey /dev/sdb1

Danger

LUKS has no "forgot password" recovery function. If every passphrase and keyfile across every key slot is lost, the data on the encrypted device is gone completely and irreversibly — there's no backdoor or recovery method. This is exactly why passphrase and keyfile copies need to be kept separately, in a secure place (a password manager or a physical safe).

/etc/crypttab: Automatic Unlocking at Boot

For permanent devices where typing cryptsetup open by hand every time is impractical, /etc/crypttab configures automatic unlocking at boot (or via systemd).

Format:

<mapping_name>  <source_device>  <key_file>  <options>

For example, with a passphrase (entered manually at boot):

crypt_data  UUID=1234-5678-...  none  luks

With a keyfile (automatic, no user interaction):

crypt_data  UUID=1234-5678-...  /root/luks-keyfile  luks

Finding the UUID:

sudo blkid /dev/sdb1

The recommended entry in crypttab uses the UUID, not the device name (/dev/sdb1), since disk names can change across reboots.

The mapping described in crypttab is later used in /etc/fstab as /dev/mapper/crypt_data — covered further in fstab.

Warning

If crypttab points to a keyfile stored on the same, unencrypted system disk, LUKS's protective value drops: if the disk is stolen as a whole, the keyfile goes with it. Automatic unlocking is convenient, but it can undercut the core goal of "data stays safe if the disk is stolen" — this trade-off should be weighed deliberately (for example, TPM-backed key storage is a more secure alternative).

LUKS-on-LVM and LVM-on-LUKS

Encryption and LVM layers can be arranged in two different orders, each with its own advantage.

LVM-on-LUKS (one large LUKS device, LVM inside)

/dev/sdb  →  LUKS (cryptsetup)  →  /dev/mapper/crypt_lvm  →  PV → VG → LV1, LV2, ...

The whole disk is encrypted once, and multiple LVs are carved out inside it via LVM. This is the most common approach, especially on laptops and desktops (for example, this is exactly what the Ubuntu installer sets up when "Encrypt the new Ubuntu installation" is selected):

  • Advantage: entering just one passphrase unlocks all the LVs (/, /home, swap) automatically.
  • Drawback: every LV shares the same key — no flexibility if different LVs need different security levels.

LUKS-on-LVM (LVM first, each LV encrypted separately)

/dev/sdb, /dev/sdc  →  PV → VG → LV1, LV2  →  each encrypted separately with LUKS
  • Advantage: a separate passphrase/keyfile per LV, and resizing an LV (lvextend) is simpler (the LUKS header layer adds less complexity at the VG level);
  • Drawback: each LV needs its own unlock, and the setup is more complex.
Criterion LVM-on-LUKS LUKS-on-LVM
Setup simplicity Simple, one unlock More complex, separate per LV
Protecting LVs individually No Yes
Typical use case Laptop/desktop full-disk encryption Server, multi-user environment

TRIM/Discard on an Encrypted SSD: a Deliberate Trade-off

By default, LUKS blocks TRIM/discard requests from reaching the underlying SSD. That's a security choice, not an oversight: without it enabled, an attacker examining the raw disk sees uniform encrypted data everywhere. Passing TRIM through tells the SSD which blocks are unused — which leaks the pattern of used vs. free space (roughly, how full the filesystem is and where data sits), and can reveal that a filesystem exists at all.

The cost of leaving it off is that the SSD can't reclaim freed blocks, so write performance and drive lifetime degrade over time. Enabling it is a conscious decision:

# one-off at open time:
sudo cryptsetup open --allow-discards /dev/sdb1 crypt_data

To make it permanent, add discard to the device's options in /etc/crypttab:

crypt_data  UUID=1234-5678-...  none  luks,discard

Warning

Enabling discard on a LUKS device weakens its "the disk looks like uniform random data" guarantee. On a laptop or a throwaway cloud SSD the performance win usually justifies it; on a high-security host where hiding filesystem structure matters, leave it off. Either way, it should be a decision you can explain — not a default someone copy-pasted.

LUKS1 vs. LUKS2

cryptsetup luksFormat defaults to LUKS2 on modern distributions, and it's the right default: LUKS2 stores a redundant header (a second copy, so a single corrupted header no longer bricks the device), supports the memory-hard Argon2id key-derivation function (far harder to brute-force than LUKS1's PBKDF2), and allows online reencryption. Stick with LUKS2 unless a specific bootloader or an older system that only understands LUKS1 forces --type luks1. Confirm which one a device uses with cryptsetup luksDump (the Version: line).

Practical Scenario: Creating an Encrypted LV and Automating Unlock

Problem: in a disposable test VM, create a new, encrypted LV inside an existing VG (vg_data) and configure it to unlock automatically at boot via a keyfile.

1. Create a new LV (as in the LVM Basics article):

sudo lvcreate -n lv_secure -L 5G vg_data

2. Format the LV with LUKS:

sudo cryptsetup luksFormat /dev/vg_data/lv_secure

3. Open it and create a filesystem:

sudo cryptsetup open /dev/vg_data/lv_secure crypt_secure
sudo mkfs.ext4 /dev/mapper/crypt_secure

4. Create and add a keyfile:

sudo dd if=/dev/urandom of=/root/lv_secure.key bs=1024 count=4
sudo chmod 400 /root/lv_secure.key
sudo cryptsetup luksAddKey /dev/vg_data/lv_secure /root/lv_secure.key

5. Write to crypttab:

crypt_secure  /dev/vg_data/lv_secure  /root/lv_secure.key  luks

6. Verify — reboot the VM and confirm automatic unlock happened:

lsblk
df -hT | grep crypt_secure

Conclusion: the LV is created at the LVM level, then encrypted with LUKS (LUKS-on-LVM order) and unlocked automatically via a keyfile through crypttab. The keyfile is stored only on the root-readable system disk — a convenience trade-off, keeping in mind that protection drops if the disk is stolen entirely.

Common Mistakes

Running luksFormat on the Wrong Device

cryptsetup luksFormat erases data with no confirmation beyond the "yes" prompt. Always check the device name with lsblk before running the command.

Storing a Key in Only One Place

If the single copy of a passphrase or keyfile is lost, the data is gone entirely. At least two independent keys (for example, two passphrases, or a passphrase plus a keyfile) and a secure backup of each are recommended.

Storing a Keyfile Referenced in crypttab on an Unencrypted Disk

This makes automatic unlocking convenient, but effectively cancels LUKS's protection if the entire disk is stolen. TPM-based key storage (e.g. systemd-cryptenroll --tpm2-device) is a better fit for such cases.

Forgetting to Back Up the LUKS Header

If the LUKS header is damaged, the device can't be opened even with the correct passphrase. Taking a separate copy of the header with cryptsetup luksHeaderBackup is recommended:

sudo cryptsetup luksHeaderBackup /dev/sdb1 --header-backup-file /root/luks-header-backup.img

Exercises

  1. In a disposable VM, format an empty partition with LUKS and open/close it using a passphrase.
  2. Add a second passphrase and a keyfile to the same device (luksAddKey), then try opening it with each separately.
  3. Configure automatic unlock via crypttab with a keyfile and confirm it after rebooting the VM.
  4. Take a header backup with luksHeaderBackup and check the number of key slots with luksDump.

Verification criterion: you should be able to explain, for a disk stolen while powered off versus while running and unlocked, which of the two LUKS actually protects.

Summary

LUKS provides transparent, block-level encryption: a device created with cryptsetup luksFormat appears decrypted as /dev/mapper/... after open, and returns to a secure, unreadable state after close. Key management (passphrase, keyfile, luksAddKey/luksRemoveKey) and automation via crypttab all define the trade-off between protecting data if a disk is stolen and everyday convenience. LUKS combines with LVM in two orders — LVM-on-LUKS (simple, one unlock) or LUKS-on-LVM (flexible, separate protection per LV) — and the choice depends on the environment's requirements. Which filesystem to choose on top of an encrypted device, and how to configure it, continues in Filesystem Types.

References