Disk Encryption
Topic 57

Disk Encryption

Security

Disk encryption at rest scrambles the bytes on a block device so a powered-off disk reveals nothing without a key. On Linux the standard is LUKS — the Linux Unified Key Setup — an on-disk header format and key-management scheme layered on dm-crypt, the kernel's device-mapper crypto target. LUKS encrypts a whole disk or a whole partition below the filesystem, so every file, every directory entry, and the free space between them is ciphertext. The userspace tool that drives it is cryptsetup, and it ships identically on Debian, Ubuntu, and the Red Hat family — the kernel does the work, cryptsetup manages the header.

The operational consequence is narrow and worth stating plainly: encryption protects against physical theft of the disk, not against a running compromised host. Once the volume is unlocked and mounted, the master key lives in kernel memory and the data is plaintext to anyone with root. A stolen laptop or a decommissioned drive pulled from a rack is protected; a server someone has logged into as root is not. The cryptography is the easy part — AES-XTS has been solid for years and rides hardware AES-NI on any modern CPU. Key management is where deployments fail: where the key lives, who can produce it at boot, and whether you can still recover the volume after the header is damaged.

Block-Level Encryption

LUKS splits the problem into two layers. dm-crypt is the kernel device-mapper target that does the actual work: it maps an encrypted block device to a cleartext virtual device under /dev/mapper/, encrypting each sector on write and decrypting on read, with no notion of passphrases. LUKS sits on top as a header that stores a randomly generated master key, wrapped (encrypted) by one or more passphrase-derived keys. The master key never changes for the life of the volume; passphrases only unwrap it. Because the encryption sits below the filesystem, it is filesystem-agnostic — ext4, XFS, or Btrfs all live unmodified inside the mapped device.

What LUKS protects and what it does not follows directly from this layering. At rest, the whole device is opaque: filenames, sizes, directory structure, and free space all encrypt together, leaking no metadata. In use, after cryptsetup open, the data is ordinary plaintext to the running kernel and to root. LUKS is an at-rest control, full stop. It does nothing against malware on a booted host, a leaked SSH key, or a memory-scraping attacker — those are problems for other layers.

Setup and Unlocking

Formatting a device with luksFormat writes the LUKS header and a fresh random master key, destroying any existing data on the target. After that, open prompts for a passphrase, unwraps the master key, and creates the cleartext device. You then put a filesystem on the mapped device, never on the raw partition — writing to the raw device would bypass encryption entirely. LUKS2 has been the cryptsetup default since version 2.1 in 2019 and uses the Argon2id key-derivation function, a memory-hard KDF that resists GPU and ASIC brute-forcing far better than the PBKDF2 of the older LUKS1 format.

# Format the partition as a LUKS2 volume (DESTROYS existing data)
cryptsetup luksFormat --type luks2 /dev/sdb1

# Open it: unwraps the master key, creates /dev/mapper/secure
cryptsetup open /dev/sdb1 secure

# Make a filesystem on the MAPPED device, not /dev/sdb1
mkfs.ext4 /dev/mapper/secure
mount /dev/mapper/secure /mnt/data

# Inspect slots, KDF, and cipher
cryptsetup luksDump /dev/sdb1

Closing reverses it: unmount the filesystem, then cryptsetup close secure tears down the mapping and evicts the master key from kernel memory. Persistent unlock at boot is driven by /etc/crypttab, which names each encrypted device and its key source, paired with /etc/fstab, which mounts the resulting /dev/mapper device. On Debian and Ubuntu, systemd reads crypttab and generates the unlock units; RHEL uses the same mechanism.

Key Management

Because passphrases wrap the master key rather than being the key, you can add and remove them without re-encrypting a single byte. A LUKS2 header holds up to 32 independent key slots (LUKS1 held 8), each carrying its own wrapped copy of the master key; any one passphrase or keyfile that fills a slot can unlock the volume. luksAddKey fills a free slot and luksRemoveKey empties one. This is how you rotate credentials, provision a per-host keyfile, and keep a printed recovery passphrase in a slot of its own.

# Add a second passphrase / recovery key into a free slot
cryptsetup luksAddKey /dev/sdb1

# Revoke a compromised passphrase
cryptsetup luksRemoveKey /dev/sdb1

# Back up the header — without this, header damage = total data loss
cryptsetup luksHeaderBackup /dev/sdb1 \
  --header-backup-file /root/secure-header.img

The header is the single point of failure. It holds the only copies of the wrapped master key; if the first sectors of the disk are overwritten or corrupted, the data is gone even when you know every passphrase, because there is nothing left to unwrap. Run luksHeaderBackup after every format and every key change, and store the image off the encrypted volume. Changing a passphrase only re-wraps the master key — it does not re-encrypt the data — so a leaked master key stays valid; to truly replace it, cryptsetup reencrypt rewrites the data online with a new master key.

Unattended Boot

A headless server has a chicken-and-egg problem: it must unlock the root volume before any human can reach it, but the key cannot simply sit in plaintext on the same disk or the encryption is pointless. There are three real answers. Bind the key to the TPM with systemd-cryptenroll --tpm2-device=auto, so the chip releases it only when the boot measurements (PCRs) match a known-good state. Use network-bound disk encryption with Clevis and a Tang server, where the client fetches a decryption shard over the LAN and self-unlocks only on a trusted network. Or install dropbear-initramfs, a minimal SSH server inside the initramfs you connect to at boot to type the passphrase by hand.

Each option trades a different risk. TPM-only unlock means a thief who steals the whole powered-off chassis still boots straight past the encryption, so pair it with a TPM PIN. Clevis/Tang depends on the keyserver being reachable and trusted — useful inside a datacenter, useless for a stolen laptop. The wrong move is the lazy one: a none entry in crypttab that prompts on a console no one watches, or a keyfile on an unencrypted partition beside the encrypted volume, which hands the key to anyone who takes the disk.

Full-Disk LUKS vs Filesystem-Level Encryption

LUKS / dm-crypt — encrypts an entire block device below the filesystem, so filenames, sizes, and free space are all ciphertext. One passphrase unlocks everything at once. Choose it for whole-disk and data-partition protection against a stolen or decommissioned drive — the default for laptops and servers.

fscrypt (native ext4/F2FS) — encrypts individual directories with per-directory keys tied to a user's login, leaving file sizes and directory structure visible. Choose it for per-user home directories on a shared host where different users hold different keys, not for blanket at-rest protection.

eCryptfs — a stacked per-file encryption layer (the old Ubuntu encrypted-home option), now largely superseded by fscrypt. Useful only where you must encrypt a subtree on top of an existing unencrypted filesystem and cannot reformat.

Common Mistakes
  • Never running luksHeaderBackup. If the header sectors get corrupted, the wrapped master key is gone and the volume is unrecoverable even with the correct passphrase.
  • Assuming encryption protects a running server. Root on a booted, unlocked host reads every file in plaintext; LUKS only defends powered-off disks.
  • A single key slot with no recovery key. Lose or mistype the one passphrase and the data is gone — there is no vendor backdoor.
  • Storing the unattended-unlock keyfile on an unencrypted partition beside the encrypted volume — a thief who takes the disk takes the key with it, defeating the entire purpose.
  • Forgetting to encrypt swap. The kernel pages anonymous memory, including secrets and key material, to swap; an unencrypted swap device leaks it straight to disk.
  • Choosing LUKS1 for a new deployment. Its PBKDF2 KDF is far weaker against brute force than LUKS2's memory-hard Argon2id.
  • Rebooting a remote server before testing the unlock path. A typo in crypttab or a missing keyfile locks you out with no console to recover from.
Best Practices
  • Format new volumes with cryptsetup luksFormat --type luks2 to get the Argon2id memory-hard KDF by default.
  • Run cryptsetup luksHeaderBackup after every format and key change, and store the image off the encrypted disk.
  • Keep at least two key slots filled — a primary passphrase plus a recovery key stored in a password manager, never on the host.
  • Encrypt swap, either with a random-key crypttab entry or a swap file inside the encrypted volume, so paged-out secrets never hit plaintext disk.
  • Confirm AES-NI is active (cryptsetup benchmark) so throughput stays near raw-disk speed rather than bottlenecking on software AES.
  • Automate headless unlock with systemd-cryptenroll --tpm2-device=auto plus a PIN, or Clevis/Tang — not a typed passphrase or a plaintext keyfile.
  • Test the unlock and recovery path on the console before deploying to a machine you can only reach over the network.
Comparable toolsWindows — BitLocker, full-volume encryption keyed to the TPM and an optional PINmacOS — FileVault, full-disk encryption tied to the user's login and a recovery keyBSD — GELI on FreeBSD, the equivalent block-device encryption layer

Knowledge Check

An attacker gains root on your running web server, where a LUKS volume is mounted at /mnt/data. What does the encryption protect?

  • Nothing on this host — once unlocked and mounted, the data is plaintext to root; LUKS is an at-rest control only
  • Every file under /mnt/data stays encrypted on disk and is returned as ciphertext even to a logged-in root user
  • Only files owned by other users stay protected, since LUKS derives a separate per-user key from each login session and keeps them isolated
  • The header and key slots stay protected, but the file contents are exposed only until the next reboot

The first sectors of a LUKS disk are corrupted, but you still know the correct passphrase. What is the outcome?

  • The data is unrecoverable unless you restore a header backup — the wrapped master key lived in the damaged header
  • The data is fine, because the passphrase derives the master key directly through the KDF, so no intact header is needed
  • cryptsetup rebuilds the damaged header automatically from the correct passphrase on the next open
  • Only the most recently added key slot is lost; the original slot still opens the volume normally

You change the passphrase on a LUKS volume after suspecting the old one leaked. Why might the data still be at risk?

  • A passphrase only re-wraps the master key; the data is not re-encrypted, so a previously leaked master key remains valid
  • Changing the passphrase silently downgrades the slot's KDF from Argon2id back to the weaker PBKDF2
  • The old passphrase stays active in its key slot until the next reboot finally clears the stale entry, leaving a window where both still open the volume
  • LUKS retains a plaintext copy of every former passphrase in a reserved area of the header

For a headless server that reboots with no one at the console, which unattended-unlock choice keeps the threat model intact?

  • TPM2 enrollment via systemd-cryptenroll with a PIN, releasing the key only when boot measurements match
  • A keyfile stored on the unencrypted boot partition and referenced from /etc/crypttab so boot never blocks
  • A none entry in crypttab that prompts for the passphrase on a console no one is watching
  • Switching the volume from LUKS2 back to LUKS1 so the header opens at boot without needing a key

You got correct