Linux Unified Key Setup (LUKS) is the standard on-disk block encryption format for Linux. Using the kernel’s dm-crypt device-mapper subsystem and the cryptsetup utility, LUKS encrypts entire partitions or block devices and supports up to eight independent key slots (passphrases or keyfiles) that unlock a single master encryption key.
Support & Data-Loss Warning:
- Formatting a partition with
cryptsetup luksFormatpermanently destroys all existing data on that partition. Always back up any data before proceeding and double-check the block device name (lsblk,blkid).- CentOS 6 and RHEL 6 used LUKS1 (
cryptsetup 1.2.x) and have reached End of Life. Modern RHEL 8/9 and Linux distributions default to LUKS2 with Argon2 key derivation, though the corecryptsetupworkflow remains the same.
What LUKS Does (and Does Not Do)
According to the Red Hat Enterprise Linux Security Guide:
What LUKS does:
- Encrypts entire block devices, making it well-suited for protecting removable media, laptop drives, and server data volumes at rest.
- Protects arbitrary block contents, including standard filesystems (
ext4,xfs), swap partitions, and raw database volumes. - Uses the Linux kernel
dm-cryptdevice-mapper subsystem. - Provides passphrase strengthening (PBKDF2 in LUKS1, Argon2id in LUKS2) to defend against dictionary and brute-force attacks.
- Supports multiple key slots, allowing administrators to maintain backup passphrases or automated keyfiles alongside a primary passphrase.
What LUKS does not do:
- It is not designed for multi-tenant file sharing where dozens of individual users require distinct access keys to the same block device (LUKS1 supports 8 key slots).
- It is block-level encryption, not file-level encryption—once a LUKS volume is unlocked and mounted, access to files inside the mount point is governed by normal POSIX permissions and SELinux.
For partitioning basics prior to encryption, see the earlier guide on formatting and mounting a disk partition.
Step 1: Unmount the Target Partition
In this walkthrough, /dev/sdb1 is currently mounted at /crypt_fs:
[root@localhost ahmed]# df -k
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda2 18208184 6542312 10734288 38% /
tmpfs 506144 228 505916 1% /dev/shm
/dev/sda1 289293 28459 245474 11% /boot
/dev/sdb1 2030444 3076 1922564 1% /crypt_fs
Unmount the partition before initializing LUKS:
sudo umount /crypt_fs
Ensure cryptsetup is installed (sudo yum install cryptsetup-luks on CentOS/RHEL 6 or sudo yum install cryptsetup on RHEL 7+). You can inspect supported actions and compiled-in cipher defaults with cryptsetup --help:
[root@localhost /]# cryptsetup --help
cryptsetup 1.2.0
Usage: cryptsetup [OPTION...] <action> <action-specific>]
...
<action> is one of:
create <name> <device> - create device
remove <name> - remove device
resize <name> - resize active device
status <name> - show device status
luksFormat <device> [<new key file>] - formats a LUKS device
luksOpen <device> <name> - open LUKS device as mapping <name>
luksAddKey <device> [<new key file>] - add key to LUKS device
luksRemoveKey <device> [<key file>] - removes supplied key or key file from LUKS device
luksKillSlot <device> <key slot> - wipes key with number <key slot> from LUKS device
luksUUID <device> - print UUID of LUKS device
isLuks <device> - tests <device> for LUKS partition header
luksClose <name> - remove LUKS mapping
luksDump <device> - dump LUKS partition information
luksSuspend <device> - Suspend LUKS device and wipe key (all IOs are frozen).
luksResume <device> - Resume suspended LUKS device.
luksHeaderBackup <device> - Backup LUKS device header and keyslots
luksHeaderRestore <device> - Restore LUKS device header and keyslots
Step 2: Initialize the LUKS Partition (luksFormat)
Format /dev/sdb1 with a LUKS header and set an initial passphrase in Key Slot 0. You must type uppercase YES to confirm:
[root@localhost ahmed]# cryptsetup luksFormat /dev/sdb1
WARNING!
========
This will overwrite data on /dev/sdb1 irrevocably.
Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase:
Verify passphrase:
Step 3: Unlock and Map the LUKS Partition (luksOpen)
Open the encrypted partition and map it to /dev/mapper/crypt_fs:
[root@localhost /]# cryptsetup luksOpen /dev/sdb1 crypt_fs
Enter passphrase for /dev/sdb1:
Once unlocked, the decrypted block device is accessible at /dev/mapper/crypt_fs.
Step 4: Generate a Keyfile for Non-Interactive Unlocking (Optional)
If the volume needs to unlock automatically at boot without someone typing a passphrase at the console, generate a random 4 KB keyfile using /dev/urandom and restrict its permissions to 0400 (root read-only):
[root@localhost /]# dd if=/dev/urandom of=/root/keyfile bs=1024 count=4
4+0 records in
4+0 records out
4096 bytes (4.1 kB) copied, 0.000893462 s, 4.6 MB/s
[root@localhost /]# chown root:root /root/keyfile
[root@localhost /]# chmod 0400 /root/keyfile
Security Note: Storing
/root/keyfileon an unencrypted root filesystem (/dev/sda2) allows/dev/sdb1to unlock unattended at boot. This protects/dev/sdb1if that secondary disk is physically removed or decommissioned separately, but if an attacker steals the entire server (including the unencrypted root disk), they can read/root/keyfile. For full-system theft protection, either encrypt the root volume as well, store the keyfile on removable media, or use Network-Bound Disk Encryption (NBDE / Tang & Clevis).
Step 5: Enroll the Keyfile into a LUKS Key Slot (luksAddKey)
Add /root/keyfile into the next available LUKS key slot (Key Slot 1). You will be prompted for the existing passphrase from Step 2 to authorize adding the new key:
[root@localhost /]# cryptsetup luksAddKey /dev/sdb1 /root/keyfile
Enter any passphrase:
Step 6: Create a Filesystem on the Mapped Device
Format the unlocked device /dev/mapper/crypt_fs (not /dev/sdb1 directly!) with ext4:
[root@localhost /]# mkfs.ext4 /dev/mapper/crypt_fs
mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
131072 inodes, 523527 blocks
26176 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=536870912
16 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
Step 7: Mount the Encrypted Filesystem
Mount /dev/mapper/crypt_fs onto the directory /crypt_fs and verify with df:
[root@localhost /]# mkdir -p /crypt_fs
[root@localhost /]# mount /dev/mapper/crypt_fs /crypt_fs
[root@localhost /]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 18G 6.3G 11G 38% /
tmpfs 495M 80K 495M 1% /dev/shm
/dev/sda1 283M 28M 240M 11% /boot
/dev/mapper/crypt_fs 2.0G 3.0M 1.9G 1% /crypt_fs
(Note the distinction between /dev/mapper/crypt_fs, which is the decrypted block device created by dm-crypt, and /crypt_fs, which is the directory mount point.)
Step 8: Configure /etc/crypttab and /etc/fstab for Persistent Mounting
To unlock the LUKS volume automatically during boot, add an entry to /etc/crypttab:
echo "crypt_fs /dev/sdb1 /root/keyfile luks" | sudo tee -a /etc/crypttab
Tip: In production environments where disk device names (
/dev/sdb1) may shift across reboots, prefer referencing the LUKS UUID (UUID=<luks-uuid>) obtained fromcryptsetup luksUUID /dev/sdb1instead of/dev/sdb1.
Next, add the mapped device to /etc/fstab:
/dev/mapper/crypt_fs /crypt_fs ext4 defaults 1 2
Example /etc/fstab:
UUID=476bdfc5-b4cc-43a2-86c4-9d7aace3385a / ext4 defaults 1 1
UUID=8bf10a61-d2de-4cda-bd1d-d5e70aaea1b5 /boot ext4 defaults 1 2
UUID=c5c5584d-c6a4-467b-b26c-b2bac80c7165 swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
/dev/mapper/crypt_fs /crypt_fs ext4 defaults 1 2
Before rebooting, always test /etc/fstab with mount -a so an error in fstab does not drop the server into emergency mode at boot.
Step 9: Verify Reboot and Inspect LUKS Header (luksDump)
Reboot the host and confirm /dev/mapper/crypt_fs unlocks and mounts automatically:
[root@localhost ahmed]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 18G 6.3G 11G 38% /
tmpfs 495M 80K 495M 1% /dev/shm
/dev/sda1 283M 28M 240M 11% /boot
/dev/mapper/crypt_fs 2.0G 3.0M 1.9G 1% /crypt_fs
To inspect the LUKS header and active key slots, run cryptsetup luksDump against the underlying partition (/dev/sdb1, not /dev/mapper/crypt_fs):
[root@localhost ahmed]# cryptsetup luksDump /dev/sdb1
LUKS header information for /dev/sdb1
Version: 1
Cipher name: aes
Cipher mode: cbc-essiv:sha256
Hash spec: sha1
Payload offset: 4096
MK bits: 256
MK digest: 6b a5 e6 1e bd 2d 0c e3 6e 43 af 46 e9 5e 9b 40 59 fc 10 89
MK salt: 8b 3c 4e 99 81 2e e5 cd 2e 9f 61 f9 d2 5e 13 9a
13 71 0a e7 65 ff c4 b7 5c 4c 5a 15 04 7f 22 5d
MK iterations: 138875
UUID: 530f17e2-ea3c-442d-9cfc-e9da5f72630d
Key Slot 0: ENABLED
Iterations: 555505
Salt: 8a 96 63 b8 21 e1 d9 1a e6 4c 7e e8 2b 02 b5 04
e8 5f be ac e2 d9 3f 48 4c b9 0b 74 dd c3 09 38
Key material offset: 8
AF stripes: 4000
Key Slot 1: ENABLED
Iterations: 745495
Salt: 60 dc 17 b3 bd 27 19 18 48 e8 22 9e 96 d6 b9 e9
95 f3 71 06 bf 3e e4 73 e5 d7 23 ac 3b 1a 7a b0
Key material offset: 264
AF stripes: 4000
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED
- Key Slot 0: Initial interactive passphrase set during
luksFormat. - Key Slot 1:
/root/keyfileadded vialuksAddKey.
Backing Up the LUKS Header
If the LUKS header on /dev/sdb1 is ever damaged or overwritten, all encrypted data on the volume becomes permanently unrecoverable—even if you know the passphrase. Always create an offline backup of the LUKS header:
sudo cryptsetup luksHeaderBackup /dev/sdb1 --header-backup-file /root/sdb1-luks-header.bak
sudo chmod 0400 /root/sdb1-luks-header.bak
Copy sdb1-luks-header.bak to secure off-host storage.