Encrypting Partitions using LUKS
Before you start
You might want to format your device as the first step, but this is only optional. More important is to create a proper partition layout on your device, namely a small one to store some meta information and a larger one to store the actual data.
In the following I am going to assume that the matching block device is /dev/sdb
(you can find yours using e.g. ‘lsblk’).
In order to create the two partitions fire up ‘fdisk’ and create a new partition table
$ fdisk /dev/sdb
Command (m for help): g
Created a new GPT disklabel (GUID: [..]).
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
In the next step, we are going to add the two new partitions. One of size 5M (to store meta data) and one to span the rest. We can thus take the default value for all but the last sector of the first partition.
$ fdisk /dev/sdb
Command (m for help): n
Partition number (1-128, default 1):
First sector (2048-15667166, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-15667166, default 15667166): +5M
Command (m for help): n
Partition number (2-128, default 2):
First sector (12288-15667166, default 12288):
Last sector, +sectors or +size{K,M,G,T,P} (12288-15667166, default 15667166):
Print the partition table to make sure everything worked out
Command (m for help): p
Disk /dev/sdb: 7.5 GiB, 8021606400 bytes, 15667200 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: [..]
Device Start End Sectors Size Type
/dev/sdb1 2048 12287 10240 5M Linux filesystem
/dev/sdb2 12288 15667166 15654879 7.5G Linux filesystem
and save your changes
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
Executing ls /dev/sdb*
will now reveal the two new block devices /dev/sdb1
and /dev/sdb2
.
As the first one will store helpful information it is formatted to ext4 using ‘mke2fs’ (-L
will set the volume label).
$ mke2fs -L sticky-hint -t ext4 /dev/sdb1
Creating filesystem with 5120 1k blocks and 1280 inodes
Allocating group tables: done
Writing inode tables: done
Writing superblocks and filesystem accounting information: done
Useful information about our partitions can then be stored as follows
$ mount /dev/sdb1 /mnt/
$ fdisk -l /dev/sdb > /mnt/partitions
$ umount /mnt
Getting started with encrypting
In the following, LUKS is used as it offers a metadata header.
This can be done by using the ‘cryptsetup’ tool. If you want to use an extra long passphrase, a key file can be used with the --key-file <file>
parameter. For the sake of simplicity I am going to provide a password from stdin here.
$ cryptsetup -v luksFormat /dev/sdb2
WARNING!
========
This will overwrite data on /dev/sdb2 irrevocably.
Are you sure? (Type uppercase yes): YES
Enter passphrase:
Verify passphrase:
Command successful.
The header and keyslot area can then be backuped (assuming that the meta info partition is still mounted as before)
$ cryptsetup luksHeaderBackup /dev/sdb2 --header-backup-file /mnt/header
Accessing the encrypted partition
We can open our newly create drive which is backed by /dev/sdb2
by executing
$ cryptsetup -v luksOpen /dev/sdb2 sticky
Enter passphrase for /dev/sdb2:
Key slot 0 unlocked.
Command successful.
This command is going to create a mapping in /dev/mapper
called ‘sticky’, which we can use to access our partition.
Right now, we obviously cannot use it since there is no filesystem on it. Let’s change that.
$ mke2fs -L sticky -t ext4 /dev/mapper/sticky
Creating filesystem with 1956347 4k blocks and 489600 inodes
Filesystem UUID: 57d5effc-7d34-4866-aa5c-3a1a95c04f81
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632
Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
To be extra secure, its output can be saved to the hint partition as well. The encrypted partition can then be mounted and subsequently used by executing
$ mount /dev/mapper/sticky /mnt/
Unmounting the encrypted partition
The device mounted through the mapping can be unmounted by simply using
$ umount /mnt
In order to remove the mapping another call to ‘cryptsetup’ is necessary
$ cryptsetup -v luksClose sticky
Command successful.
Where sticky
is simply the name of the mapping.
Normal Workflow
To wrap everything up, this is the usual order of commands when using a device encrypted as described before
$ cryptsetup -v luksOpen <block device> <map name>
$ mount /dev/mapper/<map name> <mount point>
$ # do work...
$ umount <mount point>
$ cryptsetup -v luksClose <map name>