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 luksFormat permanently 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 core cryptsetup workflow remains the same.

What LUKS Does (and Does Not Do)

According to the Red Hat Enterprise Linux Security Guide:

What LUKS does:

  1. Encrypts entire block devices, making it well-suited for protecting removable media, laptop drives, and server data volumes at rest.
  2. Protects arbitrary block contents, including standard filesystems (ext4, xfs), swap partitions, and raw database volumes.
  3. Uses the Linux kernel dm-crypt device-mapper subsystem.
  4. Provides passphrase strengthening (PBKDF2 in LUKS1, Argon2id in LUKS2) to defend against dictionary and brute-force attacks.
  5. Supports multiple key slots, allowing administrators to maintain backup passphrases or automated keyfiles alongside a primary passphrase.

What LUKS does not do:

  1. 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).
  2. 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/keyfile on an unencrypted root filesystem (/dev/sda2) allows /dev/sdb1 to unlock unattended at boot. This protects /dev/sdb1 if 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 from cryptsetup luksUUID /dev/sdb1 instead 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/keyfile added via luksAddKey.

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.

References