What is LUKS and how to use it? Let’s encrypt our filesystem on Linux!

LUKS stands for Linux Unified Key Setup. It is an encryption specification that was written for Linux systems in 2004. LUKS is used to encrypt block devices and partitions. This encryption helps to keep our data safe in rest.

When a volume is encrypted with LUKS then without knowing the passphrase (or having the key file) it is impossible to decrypt and read the data. Our LUKS security is as strong as our passphrase that protects it. If malicious actors can guess or bruteforce our passphrase then our secret data is readable for them. For security and privacy reasons it is recommended to use a strong passphrase!

A practical LAB exercise

We are going to extend a Debian Bullseye with a new disk.

The new volume will be configured to use LUKS on its partition.

LUKS uses the Device Mapper Crypt kernel module to encrypt the volumes, so we will use dm-crypt.

Its administrative tool in the userland is cryptsetup that must be installed. Cryptsetup can be installed from the distribution’s package repositories.

Running the lsblk command will show the current setup of our block devices.

root@debtop:~# lsblk 
NAME                  MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda                     8:0    0   30G  0 disk 
├─sda1                  8:1    0  487M  0 part /boot
├─sda2                  8:2    0    1K  0 part 
└─sda5                  8:5    0 29.5G  0 part 
  ├─debtop--vg-root   254:0    0 10.1G  0 lvm  /
  ├─debtop--vg-swap_1 254:1    0  976M  0 lvm  [SWAP]
  └─debtop--vg-home   254:2    0 18.4G  0 lvm  /home
sdb                     8:16   0    5G  0 disk 
sr0                    11:0    1 1024M  0 rom 

The new disk is visible in the output: there is a 5G sdb device.

Create a basic Linux partition

Let’s create a partition on the new disk with fdisk!

fdisk /dev/sdb <- opens the interactive fdisk partition editor
n       <- create a new partition
p       <- primary partition
t        <- set the partition type
83     <- to Linux partition
w      <- save the changes and exit

Now we have a new, empty partition on the sdb device!

root@debtop:~# lsblk 
NAME                  MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda                     8:0    0   30G  0 disk 
├─sda1                  8:1    0  487M  0 part /boot
├─sda2                  8:2    0    1K  0 part 
└─sda5                  8:5    0 29.5G  0 part 
  ├─debtop--vg-root   254:0    0 10.1G  0 lvm  /
  ├─debtop--vg-swap_1 254:1    0  976M  0 lvm  [SWAP]
  └─debtop--vg-home   254:2    0 18.4G  0 lvm  /home
sdb                     8:16   0    5G  0 disk 
└─sdb1                  8:17   0    5G  0 part 
sr0                    11:0    1 1024M  0 rom  

Create a LUKS volume on the partition

Let’s format the partition to use LUKS encryption! The -y option will ask the passphrase twice (verify). The -v option turns on the verbose mode.

root@debtop:~# cryptsetup -y -v luksFormat /dev/sdb1
YES                                                         <- if you understand the risks
Enter passphrase for /dev/sdb1:    <- our LUKS encryption is as strong as our passphrase! 
Verify passphrase: 
Key slot 0 created.
Command successful.

After running this interactive command our /dev/sdb1 LUKS volume is encrypted. Nobody can read the data we put here except those who know the passphrase. Our encryption and security are as strong as our passphrase is. We must always use a very strong passphrase to avoid guessing and bruteforce attacks.

Open the LUKS encrypted volume

At this point we can open the encrypted volume with LUKS. We provide the “second_disk” target to the command. It will create the /dev/mapper/second_disk device. After providing the passphrase from the previous step we decrypted the volume and opened it.

root@debtop:~# cryptsetup -v luksOpen /dev/sdb1 second_disk
Enter passphrase for /dev/sdb1: 
Key slot 0 unlocked.
Command successful.

The lsblk output also shows that the decryption was successful.

root@debtop:~# lsblk
NAME                  MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
sda                     8:0    0   30G  0 disk  
├─sda1                  8:1    0  487M  0 part  /boot
├─sda2                  8:2    0    1K  0 part  
└─sda5                  8:5    0 29.5G  0 part  
  ├─debtop--vg-root   254:0    0 10.1G  0 lvm   /
  ├─debtop--vg-swap_1 254:1    0  976M  0 lvm   [SWAP]
  └─debtop--vg-home   254:2    0 18.4G  0 lvm   /home
sdb                     8:16   0    5G  0 disk  
└─sdb1                  8:17   0    5G  0 part  
  └─second_disk       254:3    0    5G  0 crypt 
sr0                    11:0    1 1024M  0 rom   

Create a filesystem on the decrypted LUKS volume

We create a fresh filesystem on the decrypted volume. We chose the ext4 filesystem for this example.

root@debtop:~# mkfs.ext4 /dev/mapper/second_disk 
mke2fs 1.46.2 (28-Feb-2021)
Creating filesystem with 1306368 4k blocks and 327040 inodes
Filesystem UUID: e7d314c6-c5fe-4f75-8d2d-728a77ada6a9
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done

Mount the decrypted LUKS volume for daily use

We have a filesystem on the decrypted device that can be mounted as a regular partition for input and output. We create a new mount point in the /mnt directory calling it crypted_stuff. We can mount it with the regular Linux mount command.

root@debtop:~# mkdir /mnt/crypted_stuff
root@debtop:~# mount -v /dev/mapper/second_disk /mnt/crypted_stuff/
mount: /dev/mapper/second_disk mounted on /mnt/crypted_stuff.
root@debtop:~# lsblk 
NAME                  MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
sda                     8:0    0   30G  0 disk  
├─sda1                  8:1    0  487M  0 part  /boot
├─sda2                  8:2    0    1K  0 part  
└─sda5                  8:5    0 29.5G  0 part  
  ├─debtop--vg-root   254:0    0 10.1G  0 lvm   /
  ├─debtop--vg-swap_1 254:1    0  976M  0 lvm   [SWAP]
  └─debtop--vg-home   254:2    0 18.4G  0 lvm   /home
sdb                     8:16   0    5G  0 disk  
└─sdb1                  8:17   0    5G  0 part  
  └─second_disk       254:3    0    5G  0 crypt /mnt/crypted_stuff
sr0                    11:0    1 1024M  0 rom

The filesystem is mounted now, it can be used for storing files on it.

With the cryptsetup luksDump /dev/sdb1 command we can query all of the information regarding our LUKS protected volume.

Umount and close a LUKS volume

If we want to close and encrypt the decrypted volume then first umount /mnt/crypted_stuff it, and use the cryptsetup luksClose /dev/mapper/second_disk command.

We can open and mount the volume again whenever we need it.

Automatic mount of LUKS volumes

It is possible to mount automatically the LUKS encrypted partitions, but it is a security tradeoff. We have to put the key on the disk, so an attacker can decrypt and open our secrets too.

Command cheat sheet

  • apt install cryptsetup
  • fdisk /dev/sdb
  • cryptsetup -y -v luksFormat /dev/sdb1
  • cryptsetup -v luksOpen /dev/sdb1 second_disk
  • mkfs.ext4 /dev/mapper/second_disk
  • mkdir /mnt/crypted_stuff
  • mount -v /dev/mapper/second_disk /mnt/crypted_stuff/
  • umount /mnt/crypted_stuff
  • cryptsetup luksClose /dev/mapper/second_disk

If you have anything to share then please visit my Tom’s IT Cafe Discord Server!

Leave a comment