How to Encrypt Disk Partitions with LUKS on RHEL 7

Linux Unified Key Setup (LUKS) is the standard for disk encryption on Linux, providing a robust, well-documented format for encrypted block devices. By encrypting partitions with LUKS, you ensure that data remains unreadable if physical drives are removed or a server is decommissioned without proper data sanitisation. LUKS is tightly integrated with the Linux device-mapper infrastructure through dm-crypt and is supported natively in RHEL 7’s kernel. This tutorial covers installing the cryptsetup package, formatting a partition with LUKS, mapping it to a device-mapper device, creating a filesystem, configuring automatic decryption at boot via /etc/crypttab, managing multiple passphrases, backing up the LUKS header, and inspecting encryption parameters with luksDump.

Prerequisites

  • RHEL 7 server with root or sudo access
  • An unformatted block device or partition available (e.g., /dev/sdb or /dev/sdb1) — all data on it will be destroyed
  • cryptsetup package (usually installed by default; install if missing)
  • Kernel device-mapper support (enabled by default on RHEL 7)
  • Secure storage for passphrases and LUKS header backup

Step 1: Install cryptsetup

Check whether cryptsetup is already present, and install it if not:

rpm -q cryptsetup
sudo yum install -y cryptsetup cryptsetup-libs

Verify the installed version:

cryptsetup --version
# cryptsetup 1.7.4

Ensure the dm-crypt kernel module is loaded:

sudo modprobe dm-crypt
lsmod | grep dm_crypt
# dm_crypt   23569  0

Step 2: Identify and Prepare the Target Device

List available block devices to identify the target partition. Double-check the device path carefully — LUKS format is destructive and will overwrite all existing data:

lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,FSTYPE
# Example output:
# NAME   SIZE TYPE MOUNTPOINT FSTYPE
# sda     50G disk
# ├─sda1   1G part /boot      xfs
# └─sda2  49G part            LVM2_member
# sdb     20G disk
# └─sdb1  20G part

In this tutorial, the target device is /dev/sdb1. If you are working with a raw disk rather than a partition:

sudo fdisk /dev/sdb
# Create a new partition: n → p → 1 → default start → default end → w

Optionally, overwrite the partition with random data before formatting to make cryptanalysis harder (this step takes time proportional to device size):

sudo dd if=/dev/urandom of=/dev/sdb1 bs=4096 status=progress

Step 3: Format the Partition with LUKS

Use cryptsetup luksFormat to initialise the LUKS container on the partition. This step sets up the LUKS header and encrypts the volume with the passphrase you provide:

sudo cryptsetup luksFormat /dev/sdb1

You will see a warning and confirmation prompt:

WARNING!
========
This will overwrite data on /dev/sdb1 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter passphrase for /dev/sdb1: **********************
Verify passphrase: **********************

To specify explicit cipher parameters (RHEL 7 default is aes-xts-plain64 with SHA-256 for PBKDF2):

sudo cryptsetup luksFormat 
  --cipher aes-xts-plain64 
  --key-size 256 
  --hash sha256 
  --iter-time 2000 
  /dev/sdb1

The --iter-time parameter sets the PBKDF2 iteration time in milliseconds; higher values slow down brute-force attacks but also slow down legitimate unlock operations. 2000ms is a reasonable production balance.

Step 4: Open the LUKS Container

Use cryptsetup luksOpen to decrypt and map the container to a device-mapper device. The name you provide (here encrypted_data) becomes the dm-crypt device name:

sudo cryptsetup luksOpen /dev/sdb1 encrypted_data

Enter the passphrase when prompted. The decrypted device is now available at:

/dev/mapper/encrypted_data

Verify the mapping was created:

ls -lh /dev/mapper/encrypted_data
sudo dmsetup status encrypted_data
# encrypted_data: 0 41943040 crypt

Step 5: Create a Filesystem and Mount It

Create an XFS filesystem on the decrypted device-mapper device (use ext4 if preferred):

sudo mkfs.xfs /dev/mapper/encrypted_data
# Or for ext4:
# sudo mkfs.ext4 /dev/mapper/encrypted_data

Create a mount point and mount the filesystem:

sudo mkdir -p /mnt/encrypted_data
sudo mount /dev/mapper/encrypted_data /mnt/encrypted_data

Verify the mount and available space:

df -hT /mnt/encrypted_data
# Filesystem               Type  Size  Used Avail Use% Mounted on
# /dev/mapper/encrypted_data xfs   20G   33M   20G   1% /mnt/encrypted_data

Step 6: Configure Automatic Decryption at Boot with /etc/crypttab

To have the system automatically open the LUKS container during boot (and optionally prompt for the passphrase), add an entry to /etc/crypttab. The format is: name device keyfile options.

First, get the UUID of the raw LUKS partition (use the LUKS partition UUID, not the filesystem UUID):

sudo cryptsetup luksUUID /dev/sdb1
# Output example: a1b2c3d4-e5f6-7890-abcd-ef1234567890

# Or use blkid:
sudo blkid /dev/sdb1 | grep -o 'UUID="[^"]*"'

Add the entry to /etc/crypttab:

sudo vi /etc/crypttab

Add a line using the UUID. Using none as the key file means the system will prompt for a passphrase at boot:

# /etc/crypttab
# name              device                                    keyfile  options
encrypted_data      UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890  none     luks

For a headless server where you want to use a key file instead of an interactive passphrase (storing the key file on an encrypted root or USB drive):

# Generate a random key file:
sudo dd if=/dev/urandom of=/etc/luks-keys/encrypted_data.key bs=4096 count=1
sudo chmod 400 /etc/luks-keys/encrypted_data.key

# Add the key to the LUKS container (adds key slot):
sudo cryptsetup luksAddKey /dev/sdb1 /etc/luks-keys/encrypted_data.key

# Update crypttab to use the key file:
# encrypted_data  UUID=a1b2c3d4-...  /etc/luks-keys/encrypted_data.key  luks

Step 7: Configure /etc/fstab for Automatic Mounting

After the LUKS container is opened at boot (via crypttab), the device at /dev/mapper/encrypted_data needs to be mounted automatically. Add an entry to /etc/fstab. Use the filesystem UUID of the decrypted device (obtained after opening the LUKS container):

sudo blkid /dev/mapper/encrypted_data
# /dev/mapper/encrypted_data: UUID="f9e8d7c6-b5a4-3210-fedc-ba9876543210" TYPE="xfs"

Add to /etc/fstab:

sudo vi /etc/fstab
# Device                                     Mountpoint         Type  Options        Dump Pass
UUID=f9e8d7c6-b5a4-3210-fedc-ba9876543210   /mnt/encrypted_data  xfs   defaults,_netdev  0    0

The _netdev option ensures the filesystem is mounted after network initialisation is complete, which is important for LUKS volumes managed by systemd. Test the fstab entry without rebooting:

sudo umount /mnt/encrypted_data
sudo cryptsetup luksClose encrypted_data
sudo systemctl daemon-reload
sudo mount -a

Step 8: Add Additional Passphrases with luksAddKey

LUKS supports up to 8 independent key slots. This allows you to add a recovery passphrase, a key file for automated systems, or passphrases for multiple administrators — without needing to know any existing passphrase beyond the one used during the addition:

sudo cryptsetup luksAddKey /dev/sdb1

You will be prompted to enter an existing passphrase to authenticate, then to enter and confirm the new passphrase:

Enter any existing passphrase: **********************
Enter new passphrase for key slot: **********************
Verify passphrase: **********************

To add a key file directly to a new slot:

sudo cryptsetup luksAddKey /dev/sdb1 /path/to/keyfile.key

To remove a passphrase (by key slot number):

sudo cryptsetup luksKillSlot /dev/sdb1 1

Step 9: Back Up the LUKS Header

The LUKS header contains the key slots and encryption metadata. If the header is corrupted (e.g., a bad write to the beginning of the partition), the encrypted data becomes permanently inaccessible — even if you know the passphrase. Always back up the LUKS header immediately after formatting:

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

Protect the backup file and store it securely offline:

sudo chmod 400 /root/luks-header-backup-sdb1.img

To restore a header from backup (use only if the header is damaged):

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

Step 10: Inspect LUKS Information with luksDump

The luksDump command displays detailed information about the LUKS header, including the cipher, hash, key size, and the status of each key slot:

sudo cryptsetup luksDump /dev/sdb1

Example output:

LUKS header information for /dev/sdb1

Version:        1
Cipher name:    aes
Cipher mode:    xts-plain64
Hash spec:      sha256
Payload offset: 4096
MK bits:        256
MK digest:      ab cd ef 01 23 45 67 89 ab cd ef 01 23 45 67 89 01 23 45 67
MK salt:        ab cd ef 01 23 45 67 89 ab cd ef 01 23 45 67 89 01 23 45 67
                01 23 45 67 89 ab cd ef 01 23 45 67 89 ab cd ef 01 23 45 67
MK iterations:  214750
UUID:           a1b2c3d4-e5f6-7890-abcd-ef1234567890

Key Slot 0: ENABLED
        Iterations:             1717500
        Salt:                   01 23 45 67 ...
        Key material offset:    8
        AF stripes:             4000
Key Slot 1: ENABLED
        ...
Key Slot 2: DISABLED
...
Key Slot 7: DISABLED

This output confirms which key slots are in use. A DISABLED slot is empty; ENABLED slots contain an active passphrase or key file. Use this to audit who has access to the encrypted volume.

Conclusion

You have successfully configured LUKS disk encryption on RHEL 7. Your encrypted partition is formatted, mounted, configured to decrypt at boot via /etc/crypttab, and has its LUKS header backed up for recovery. LUKS encryption is transparent to applications — once the container is unlocked and mounted, files are read and written normally while the kernel handles encryption in the background with negligible performance overhead on modern hardware. Combine LUKS with SELinux policies and filesystem-level access controls for a defence-in-depth approach to data protection. For regulatory compliance requirements (PCI-DSS, HIPAA, GDPR), document the encryption algorithm, key length, and key management procedures as evidence of data-at-rest encryption controls.