Setting up an external disk for LUKS encryption

Should you encrypt external disks ?, why not as they are normally used as backup devices, and if you encrypted the data to be backed up it would be pointless to then store that on an unencrypted backup device.

The easy way for a Desktop (really the hard way)
================================================
From activites/Applications select the disk option.
Highlight the disk you want to work with.
Select format, use the luks encyption option, use a strong passphrase…
…the disk will be mounted when done

Why is that the hard way ?
You don’t know whats been done, and you have to manually mount it using the disk application whenever you want to use it.

Actually it may prompt you for a password if you login to the desktop; but I prefer it to be automounted anyway.

So, do it the manual/server way

The manual method
=================
Note: I use a key file containing the password at every step, you don’t want to be prompted at boot on a headless server :-). In these examples I use /home/mark/disk_keys/GB1000A but the key file is simply a text file in which you should have a strong passphrase.

(1) use cryptsetup luksFormat to create the LUKS disk
(2) make a filesystem on it, I use ext4
(3) in a startup script of choice do the cryptsetup luksOpen to create the mapper device, using the UUID of the LUKS partition (instead of a device name like /dev/sdb1 as device names can change between reboots)
(4) add the uuid of the ext4 filesystem (the one on the /dev/mapper device not the LUKS uuid) to /etc/fstab
(5) in a startup script (probably the same one that did the cryptsetup luksOpne) mount it
(6) done

Complicated, no. Very simple, example below

Issues I had
============
My own stupidity. Out of habbit from years of program prompts I was typing “y” to the format prompt and (as it generates no messages) assumed it worked and couldn’t figure out what was wrong. Eventually I read the message; you must reply YES (in uppercase) to the luksFormat prompt. The messages (none) displayed on the screen are the same, but it works better.

UUID Notes
==========
During testing I was re-using the same UUID, done as

[root@phoenix posts]# cryptsetup luksFormat \
    /dev/sdb1 /home/mark/disk_keys/GB2000A \
    --uuid=df8f5f03-c3e7-461b-abed-10d293efd2ac  # to force a uuid

But as generally you would let one be generated the command above is just for reference. The examples below will use a generated one.

The UUID is important however; ALWAYS use that for mounting volumes (not just LUKS volumes), I have used UUID in my mount commands for about four years now, ever since I discovered that the different amount of time it took to spin up a disk on reboot would change the /dev/sd* allocations randomly.
You can mount the LUKS disk using UUID, and then mount the internal filesystem by UUID also, preventing any problems.

Now the full example, with additional comments :-)
==================================================

#--------------------------------------------------
# Using line continuations "\" just to make the
# commands more readable (without you having to
# scroll left/right).
#--------------------------------------------------

#--------------------------------------------------
# format a partition/disk as a LUKS container
# - The device is /dev/sdb1
# - The parameter after that is a file containing the
#   passphrase to be used. any strong passphrase
# NOTE: at the prompt do not reply y, you must reply
#       YES, in capitals
#--------------------------------------------------
[root@falcon ~]# cryptsetup luksFormat \
                 /dev/sdb1 \
                 /home/mark/disk_keys/GB1000A

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

Are you sure? (Type uppercase yes): YES

#--------------------------------------------------
# get the UUID,
# we want to work with the UUID not the device name
#--------------------------------------------------
[root@falcon ~]# blkid /dev/sdb1
/dev/sdb1: UUID="3b1f3117-02c5-498a-ae52-b66a289ec011" TYPE="crypto_LUKS" 

#--------------------------------------------------
# Then we can use luksOpen on the UUID,
#  - using the key file used to create the LUKS volume
#  - and check the /dev/mapper device was created
#    (or echo $? after the luksOpen would tell you
#     if it went splat). In this example the device
#     that would be created bu luksOpen would be
#     /dev/mapper/luks-1000A
# The parameter after the UUID=xx is the name of the
# device that will be created in /dev/mapper
#--------------------------------------------------
[root@falcon ~]# cryptsetup luksOpen \
         UUID=3b1f3117-02c5-498a-ae52-b66a289ec011 \
         luks-1000A \
         --key-file=/home/mark/disk_keys/GB1000A
[root@falcon ~]# ls /dev/mapper/luk*
/dev/mapper/luks-1000A

#--------------------------------------------------
# Format the filesystem
#  - using the /dev/mapper device of course
#    (using /dev/sdb1 would overwrite the luks header
#     and give you a normal ext4 filesystem)
#--------------------------------------------------
[root@falcon ~]# mkfs -t ext4 /dev/mapper/luks-1000A
mke2fs 1.42.3 (14-May-2012)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
61054976 inodes, 244189496 blocks
12209474 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=0
7453 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
	4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968, 
	102400000, 214990848

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

#--------------------------------------------------
# Get the UUIDs (YES THERE ARE TWO)
#   - the one on /dev/sdb1 is is the LUKS filesystem
#     UUID that can be used by cryptsetup, which
#     you wrote down in the previous steps didn't
#     you.
#   - the one on the /dev/mapper device is the UUID
#     of the ext4 filesystem within the LUKS
#     container, that you can mount and use as a
#     filesystem,# mount the encrypted external drives
cryptsetup luksOpen \
     UUID=3b1f3117-02c5-498a-ae52-b66a289ec011 \
     luks-1000A \
     --key-file=/home/mark/disk_keys/GB1000A
mount /mnt/GB1000A
#     see the /etc/fstab notes below
#--------------------------------------------------
[root@falcon ~]# blkid /dev/sdb1
/dev/sdb1: UUID="3b1f3117-02c5-498a-ae52-b66a289ec011" TYPE="crypto_LUKS" 
[root@falcon ~]# blkid /dev/mapper/luks-1000A
/dev/mapper/luks-1000A: UUID="44b5acdd-8e87-466f-b755-495eb8d088b2" TYPE="ext4" 
[root@falcon ~]# 

#--------------------------------------------------
# In the /etc/fstab add an entry for the ext4
# filesystem. It MUST be set to 'noauto' as it
# cannot be mounted at boot time... not until
# after cryptosetup has opened it.
# A grep shows you whats in my fstab based on the
# above commands.
#--------------------------------------------------
[root@falcon ~]# grep 1000A /etc/fstab
#     /mnt/GB1000A - a 1Tb disk - Luks disk so cannot automount
UUID=44b5acdd-8e87-466f-b755-495eb8d088b2	/mnt/GB1000A ext4 noauto,rw,defaults 1 2
[root@falcon ~]# 

#--------------------------------------------------
# At this point
#  - as the luksOpen is still in effect
#    you could just mount it
#--------------------------------------------------
[root@falcon ~]# mount /mnt/GB1000A
[root@falcon ~]# df -k | grep 1000
/dev/mapper/luks-1000A           975721988 14496368 912387724   2% /mnt/GB1000A
[root@falcon ~]# 

The example above shows how to encrypt a filesystem, and add an entry in fstab for the ext4 filesystem embedded in the LUKS container.

Obviously the noauto is required in the fstab as the filesystem cannot be mounted the LUKS container is first mounted.

What I do is have a startup script run at S99 do do all the “cryptsetup luksOpen” commands using the LUKS container uuid (as physical device names do change between reboots) using the keyfile to avoid the boot hanging at a password prompt. That created the /dev/mapper devices and registers their UUID values.

After that, as the luksOpen has made the UUID values of the internal ext4 filesystems available to udev I can just issue a simple mount command for the mountpoint as the fstab uses the ext4 uuid made available by the luksOpen.

Simple after all isn’t it.

The next steps you should take
==============================
Do a “man” on cryptsetup, you do want to regulary backup the luks header area.

The next steps you could also take
==================================
For my servers I’ve tried to get the disks automounted, I would put the below command into one of my startup scripts.

# mount the encrypted external drives# mount the encrypted external drives
cryptsetup luksOpen UUID=3b1f3117-02c5-498a-ae52-b66a289ec011 luks-1000A --key-file=/home/mark/disk_keys/GB1000A
mount /mnt/GB1000A
cryptsetup luksOpen \
    UUID=3b1f3117-02c5-498a-ae52-b66a289ec011 \
    luks-1000A \
    --key-file=/home/mark/disk_keys/GB1000A
mount /mnt/GB1000A

Anyway, that should be enough to get you started with LUKS encrypted partitions.

Update April 2014

For any Fedora release using /etc/crypttab to automate the luksOpen using disk keys is the preferred method for creating the /dev/mapper entries rather than using a startup script however… if you can guarantee the external drive is always available at boot time or your boot will hang.

One change I noticed in F20 though is that /etc/fstab now uses the /dev/mapper entry (in a default install) to mount luke encrypted filesystems rather than the uuid method. So just mentioning that in an update here.

And since F17 (certainly on F17 anyway) plugging in a luks encrypted USB stick correctly prompts for the disk encrytion password when it is attempted to be automounted… it is just not possible to type anything into the password field thrown up during automount. So manually using cryptsetup luksOpen is still required for those.

It may be fixed in an update by now ?.

About mark

At work, been working on Tandems for around 30yrs (programming + sysadmin), plus AIX and Solaris sysadmin also thrown in during the last 20yrs; also about 5yrs on MVS (mainly operations and automation but also smp/e work). At home I have been using linux for decades. Programming background is commercially in TAL/COBOL/SCOBOL/C(Tandem); 370 assembler(MVS); C, perl and shell scripting in *nix; and Microsoft Macro Assembler(windows).
This entry was posted in Unix. Bookmark the permalink.