You need encryption before the drive leaves your hands
You are provisioning a new Fedora system, or you just added a secondary drive to your workstation. You want that data encrypted at rest. If the hardware is lost or stolen, you need the drive to be unreadable without the key. You also need the system to unlock automatically during boot so you don't have to type a passphrase every time you log in.
Fedora uses LUKS (Linux Unified Key Setup) for block device encryption. LUKS handles the key management and the header format. The actual encryption happens via dm-crypt, a kernel-level device mapper target. Fedora integrates LUKS with systemd so encrypted volumes can unlock early in the boot process using keys stored on the system.
How LUKS protects your data
LUKS does not encrypt the whole disk in one blob. It writes a header at the start of the partition. The header contains the cipher parameters, the salt, and the key slots. Each key slot holds an encrypted copy of the master key. You can have multiple passphrases or key files, each unlocking a different slot. When you provide a valid passphrase, LUKS decrypts the master key from the slot and feeds it to dm-crypt. dm-crypt then creates a virtual block device that exposes the decrypted data.
Think of the LUKS header as a safe deposit box registry. The registry lists which keys open the box. The master key is the combination inside the box. dm-crypt is the mechanism that actually opens the box and reveals the contents. If the header is corrupted, the registry is gone. You cannot open the box, even if you have the right key.
Back up the LUKS header before you make changes. A corrupted header means zero data recovery. Run cryptsetup luksHeaderBackup immediately after formatting. Store the backup on a separate device or in a secure offline location.
Encrypt a partition manually with cryptsetup
When you are setting up a drive on a running system, you use cryptsetup directly. This gives you full control over the partition layout and key management. The process involves formatting the device with a LUKS header, opening the device to create a mapper node, creating a filesystem, and configuring systemd to unlock the volume at boot.
Identify the target partition. Do not run these commands on your root filesystem unless you are following a migration guide. This procedure destroys all data on the target partition.
Here's how to format the partition with a LUKS header and set a passphrase.
# Wipe existing signatures to prevent confusion with old filesystems
sudo wipefs -a /dev/sdb1
# Format the partition with LUKS2. The --type luks2 flag ensures modern features.
# You will be prompted for a passphrase. Use a strong passphrase.
sudo cryptsetup luksFormat /dev/sdb1 --type luks2
The device is now encrypted. You cannot write data to it yet. You must open the LUKS container to create a virtual device in /dev/mapper.
Here's how to open the encrypted volume and create a filesystem inside it.
# Open the LUKS container and name the mapper device 'securedata'.
# You will be prompted for the passphrase you set during formatting.
sudo cryptsetup luksOpen /dev/sdb1 securedata
# Create an ext4 filesystem on the decrypted mapper device.
# The -L flag sets the volume label for easier identification.
sudo mkfs.ext4 -L securedata /dev/mapper/securedata
# Create a mount point for the decrypted volume.
sudo mkdir -p /mnt/securedata
# Mount the filesystem to verify it works.
sudo mount /dev/mapper/securedata /mnt/securedata
The volume is mounted and usable. To make this persistent across reboots, you need to configure /etc/crypttab and /etc/fstab. crypttab tells systemd how to unlock the LUKS volume. fstab tells the system where to mount the resulting filesystem.
Edit /etc/crypttab. Never edit files in /usr/lib/. Those files ship with packages and get overwritten on updates. User configuration always lives in /etc/.
Here's the crypttab entry that unlocks the volume using the passphrase prompt or a key file.
# <name> <device> <key file> <options>
# 'securedata' is the mapper name. /dev/sdb1 is the partition.
# 'none' means systemd will prompt for a passphrase at boot.
# Use a path like /etc/luks/keyfile instead of 'none' for automatic unlock.
# luks option tells systemd to use LUKS key management.
securedata /dev/sdb1 none luks
Add the corresponding entry to /etc/fstab.
# Mount the decrypted mapper device at the target path.
# x-systemd.device-timeout=30s prevents boot hangs if the device is missing.
/dev/mapper/securedata /mnt/securedata ext4 defaults,x-systemd.device-timeout=30s 0 2
Reboot the system to test the configuration. If the boot stops asking for a passphrase, the setup is working. If the system drops into emergency mode, check journalctl -xe for cryptsetup errors. A typo in crypttab locks you out of your own system.
Configure LUKS for automated provisioning
When you are deploying immutable images like Silverblue, or provisioning cloud instances, you cannot run commands interactively. You define the storage layout in an Ignition configuration file. Ignition runs on the first boot and applies the configuration before the operating system starts.
The Ignition luks object defines encrypted volumes. You specify the target device, the mapper name, and the key material. Ignition handles the formatting and unlocking automatically.
The luks array defines the encrypted volumes. Each object needs a name for the mapper device, a device path pointing to the raw partition, and a keyFile resource. The keyFile contains the base64-encoded passphrase or key material. The mode sets the file permissions on the key file after Ignition writes it. Fedora uses Ignition to apply this configuration on the first boot of immutable images.
{
"storage": {
"filesystems": [
{
"device": "/dev/mapper/root",
"format": "ext4",
"wipeFilesystem": true,
"path": "/"
}
],
"luks": [
{
"name": "root",
"device": "/dev/sda2",
"wipeVolume": true,
"keyFile": {
"source": "data:text/plain;base64,Y2hhbmdlLW1l",
"mode": 420
}
}
]
}
}
The keyFile in this example uses a data URI. In production, you would inject the key file via a secure mechanism like a TPM or a remote key server. The mode value 420 is octal 0644. For key files, you should use 0600 to restrict access to root only. Ignition writes the key file to disk, unlocks the volume, and then the filesystem mounts as defined in the filesystems array.
Validate your Ignition config before burning it to a disk. Use ignition-validate to catch syntax errors. A bad config can leave the system unbootable.
Verify the encryption is active
After setup, confirm that the encryption layer is functioning. Check the block device hierarchy and the LUKS status.
Here's how to verify the mapper device exists and the filesystem is mounted correctly.
# List block devices with filesystem types. Look for crypt under the partition.
lsblk -f
# Check the LUKS status of the mapper device.
# This shows the cipher, key size, and active key slots.
sudo cryptsetup status securedata
# Verify the mount point and options.
findmnt /mnt/securedata
The lsblk output should show the partition with crypto_LUKS type, and a child device under /dev/mapper with your filesystem type. The cryptsetup status command confirms the device is open and shows the active cipher. If the status command fails with No such device or directory, systemd did not open the volume. Check journalctl -xeu cryptsetup@securedata.service for the failure reason.
Run journalctl -xe first. Read the actual error before guessing. The x flag adds explanatory text and the e flag jumps to the end. Most sysadmins type journalctl -xeu <unit> muscle-memory style to isolate service failures.
Common pitfalls and recovery
Encryption errors usually fall into three categories: wrong key, missing device, or SELinux denial.
If you see Device /dev/sdb1 is not a valid LUKS device, the header is missing or corrupted. You likely ran luksFormat on the wrong device, or the partition table changed. Check the partition UUIDs. If the header is truly gone, restore from your backup.
# Restore the LUKS header from a backup file.
# This overwrites the current header. Ensure the backup matches the device.
sudo cryptsetup luksHeaderRestore /dev/sdb1 --header-backup-file /path/to/backup.img
If you see No key available with the given parameters, the passphrase is wrong, or the key file path in crypttab is incorrect. Verify the key file exists and has the right permissions. SELinux can block access to key files if the context is wrong.
SELinux denials show up in journalctl -t setroubleshoot with a one-line summary. Read those before disabling SELinux. If cryptsetup cannot read the key file, you might see an AVC denial. Fix the context with restorecon.
# Restore the default SELinux context for the key file directory.
sudo restorecon -v /etc/luks/
# Reload the firewall if you are using a remote key server.
# firewall-cmd --reload after every rule change. Otherwise the runtime config and the persistent config diverge.
sudo firewall-cmd --reload
If the system drops into emergency mode because the encrypted volume failed to unlock, you can unlock it manually from the shell.
# Open the volume manually in the emergency shell.
sudo cryptsetup luksOpen /dev/sdb1 securedata
# Mount the filesystem to access data.
sudo mount /dev/mapper/securedata /mnt/securedata
# Fix the configuration, then reboot.
sudo reboot
Backup the header after every major change. Future-you will thank you.
Choose the right encryption path
Use the Anaconda installer when you are setting up a fresh desktop or server and want the GUI to handle partitioning and encryption automatically.
Use cryptsetup manually when you need to encrypt a specific partition on a running system or script a custom layout that the installer does not support.
Use Ignition configuration when you are provisioning immutable images like Silverblue or cloud instances where the disk layout must be defined before the first boot.
Use fscrypt when you only need file-level encryption for a home directory and don't want to encrypt the entire block device.
Trust the package manager. Manual file edits drift, snapshots stay.