LUKS (Linux Unified Key Setup) is the standard disk encryption format on RHEL 9, providing robust full-disk and partition-level encryption using the dm-crypt kernel subsystem. The cryptsetup utility is the primary tool for creating, managing, and auditing LUKS containers. LUKS2, the default format since RHEL 8, offers improved metadata resilience, Argon2 key derivation, and per-sector authentication. This tutorial covers advanced LUKS management tasks on RHEL 9, from creating encrypted volumes to network-bound disk encryption with Clevis and Tang.

Prerequisites

  • RHEL 9 system with a spare block device or partition (e.g., /dev/sdb1)
  • Root or sudo access
  • cryptsetup installed (dnf install -y cryptsetup)
  • Basic familiarity with partitioning and the Linux block device model

Step 1 — Create a LUKS2 Encrypted Container

Format a partition as LUKS2. You will be prompted to enter a passphrase that becomes key slot 0.

sudo cryptsetup luksFormat --type luks2 /dev/sdb1

# Confirm by typing YES (uppercase) when prompted
# Verify the format
sudo cryptsetup luksDump /dev/sdb1

luksDump prints the LUKS2 header, including the UUID, cipher (aes-xts-plain64), key size, and the status of all 32 available key slots (LUKS2 supports up to 32 slots, compared to LUKS1’s 8).

Step 2 — Add Additional Passphrases and Key Files

LUKS allows multiple key slots so that different passphrases or key files can each unlock the volume independently — useful for recovery scenarios or automated unlocking at boot.

# Add a second passphrase (you must supply an existing passphrase first)
sudo cryptsetup luksAddKey /dev/sdb1

# Add a key file as an alternative unlock method
sudo dd if=/dev/urandom of=/root/sdb1.keyfile bs=512 count=4
sudo chmod 400 /root/sdb1.keyfile
sudo cryptsetup luksAddKey /dev/sdb1 /root/sdb1.keyfile

# Remove a passphrase from a specific slot (slot 0)
sudo cryptsetup luksKillSlot /dev/sdb1 0

# Rotate/change an existing passphrase
sudo cryptsetup luksChangeKey /dev/sdb1

Step 3 — Back Up and Restore the LUKS Header

The LUKS header contains all key slot metadata. Corruption or accidental overwrite of the first sector permanently destroys access to the encrypted data. Always back it up immediately after creation.

# Back up the header to a file
sudo cryptsetup luksHeaderBackup /dev/sdb1 
    --header-backup-file /root/sdb1-luks-header.bak

# Secure the backup (store it off-device)
sudo chmod 400 /root/sdb1-luks-header.bak

# Restore the header if it becomes corrupted
sudo cryptsetup luksHeaderRestore /dev/sdb1 
    --header-backup-file /root/sdb1-luks-header.bak

Store the header backup in a separate physical location or encrypted offsite storage — never on the same disk you are protecting.

Step 4 — Configure Auto-Unlock at Boot with a Key File

Edit /etc/crypttab to instruct the initramfs to unlock a LUKS device automatically using a key file, avoiding an interactive passphrase prompt at boot.

# /etc/crypttab format:    
# Append the following line:
data_crypt  /dev/sdb1  /root/sdb1.keyfile  luks

# Open the LUKS container manually for testing
sudo cryptsetup luksOpen /dev/sdb1 data_crypt --key-file /root/sdb1.keyfile

# Create a filesystem and add to /etc/fstab
sudo mkfs.xfs /dev/mapper/data_crypt
echo "/dev/mapper/data_crypt  /mnt/data  xfs  defaults  0 2" | sudo tee -a /etc/fstab

# Rebuild initramfs so changes take effect
sudo dracut --force

Step 5 — Encrypt a Swap Partition

Swap can hold sensitive data from RAM. Encrypt it with a randomly generated key on each boot so no persistent passphrase is required.

# Disable the current swap partition
sudo swapoff /dev/sdc1

# Add to /etc/crypttab using /dev/urandom for ephemeral key
swap_crypt  /dev/sdc1  /dev/urandom  swap,cipher=aes-xts-plain64,size=256

# Update /etc/fstab to reference the mapped device
/dev/mapper/swap_crypt  none  swap  sw  0 0

# Rebuild initramfs
sudo dracut --force

Step 6 — Network-Bound Disk Encryption with Clevis and Tang

Clevis and Tang enable automatic LUKS unlocking when a server is on a trusted network, eliminating passphrase prompts without storing a key file on disk. The Tang server holds a portion of the key; the disk cannot be unlocked if it is removed from the network.

# On the Tang server
sudo dnf install -y tang
sudo systemctl enable --now tangd.socket

# On the RHEL 9 client
sudo dnf install -y clevis clevis-luks clevis-dracut

# Bind the LUKS device to Tang (replace IP with your Tang server)
sudo clevis luks bind -d /dev/sdb1 tang 
    '{"url":"http://192.168.1.10"}'

# Confirm binding (shows Clevis token in key slot)
sudo clevis luks list -d /dev/sdb1

# Rebuild initramfs to include Clevis hooks
sudo dracut --force

LUKS2’s token mechanism stores the Clevis binding metadata in the header itself, making it fully self-describing — a key advantage over LUKS1, which required external configuration files for the same functionality.

Conclusion

You have covered the full LUKS2 management lifecycle on RHEL 9: creating encrypted containers, managing multiple key slots and key files, protecting and restoring headers, configuring auto-unlock in /etc/crypttab, encrypting swap, and binding volumes to a Tang server with Clevis for network-bound disk encryption. LUKS2’s expanded slot count, improved key derivation with Argon2id, and native token support make it a significant upgrade over LUKS1 for production environments requiring both security and operational flexibility.

Next steps: How to Configure DRBD for High-Availability Storage on RHEL 9, How to Use Bacula for Enterprise Backup on RHEL 9, and How to Manage LVM Thin Provisioning on RHEL 9.