Creating a pmount-compatible encrypted USB drive

Contents

1 Why pmount

There are many ways to set up the way removable media is mounted (or even auto-mounted) in linux. Out of those, pmount provides the following advantages:

These are my short notes on how to format a USB drive in a way that is compatible with pmount.

2 Identifying the USB drive

lsblk -f shows all block devices in the system. If we run it before inserting the drive, and then after, the inserted drive is the new device in the output:

$ lsblk -f
NAME   FSTYPE      FSVER LABEL       UUID                                 FSAVAIL FSUSE% MOUNTPOINT
sda
|-sda1
|-sda2 ext4        1.0   sddroot     38e24d86-4374-4042-aebe-eeaec2317b6f    5.5G    84% /
sdb

We can also use watch (1) or ogle (shameless plug) to monitor the output of lsblk and get an immediate feedback when the drive is detected.

3 Creating the luks-encrypted partition

All examples assume that an empty USB drive was inserted and identified as /dev/sdb. Do not use the commands below if you don’t understand what they are doing. If you have a second hard-drive identified as /dev/sdb, for instance, the commands below will make it unusable.

3.1 Partition the drive

We can use fdisk or any other partitioning tool. An example session:

$ sudo fdisk /dev/sdb
Welcome to fdisk (util-linux 2.33.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x52edff0e.
Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 
First sector (2048-102399, default 2048): 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-102399, default 102399): 
Created a new partition 1 of type 'Linux' and of size 49 MiB.
Command (m for help): w
The partition table has been altered.
Syncing disks.

The partition type doesn’t matter much, it has no relation with the file system in linux. Use 83 (Linux) if in doubt.

3.2 Format the partition

Use cryptsetup luksFormat to format the partition; we also choose the passphrase in this step. Let’s create a variable with the partition (/dev/sdb1 in this example) and format it:

$ part=/dev/sdb1
$ sudo cryptsetup luksFormat --label cryptflash "$part"
WARNING: Device /dev/sdb1 already contains a 'dos' partition signature.
WARNING!
========
This will overwrite data on /dev/sdb1 irrevocably.
Are you sure? (Type uppercase yes): YES
Enter passphrase for /dev/sdb1: mypassphrase

Verify passphrase: mypassphrase

3.3 Create the filesystem

This is a two-step process: we first “open” the luks partition, creating a pseudo-device; and then we create the filesystem we want on top of that. The filesystem layer doesn’t care if the device is an abstract cryptographic engine or a real partition.

Let’s open the luks partition in the pseudo-device cryptdev:

$ sudo cryptsetup luksOpen "$part" cryptdev
Enter passphrase for /dev/sdb1: mypassphrase

We now have to create the filesystem. The pmount manual has a list of supported filesystems. ext4 is the most popular one for non-removable drives, but it’s not great for drives that we want to use in multiple systems, as it hard-codes the UIDs. That means that if we won’t have the proper permissions if we plug the drive in another system where our UID has a different numerical value. We’d then have to use sudo, which nullifies one of the advantages of pmount.

For this reason, we are using UDF for the partition:

$ sudo mkfs.udf -l cryptflash /dev/mapper/cryptdev
filename=/dev/mapper/cryptdev
label=cryptflash
uuid=60eb257a9f3b5c1f
blocksize=512
blocks=69632
udfrev=2.01
start=0, blocks=64, type=ERASE
start=64, blocks=13, type=VRS
start=77, blocks=19, type=ERASE
start=96, blocks=16, type=MVDS
start=112, blocks=16, type=ERASE
start=128, blocks=16, type=LVID
start=144, blocks=112, type=ERASE
start=256, blocks=1, type=ANCHOR
start=257, blocks=69118, type=PSPACE
start=69375, blocks=1, type=ANCHOR
start=69376, blocks=96, type=ERASE
start=69472, blocks=16, type=RVDS
start=69488, blocks=143, type=ERASE
start=69631, blocks=1, type=ANCHOR
mkudffs: Warning: Creating new UDF filesystem on partition, and not on whole disk device
mkudffs: Warning: UDF filesystem on partition cannot be read on Apple systems

At last, we close the luks layer with:

$ sudo cryptsetup luksClose cryptdev

4 Mounting/unmounting the drive

We can luksOpen the device and just use the regular mount to access the files. But using pmount is much more convenient, as it takes care of doing both steps and doesn’t require any configuration or permissions.

All partitions in block devices pop up in /dev/disk/by-label/ as a symbolic link to the underlying /dev entry. We can simply use that path as the argument to pmount to get the corresponding filesystem mounted at /media/:

$ pmount /dev/disk/by-label/cryptflash

To unmount:

$ pumount /media/disk_by-label_cryptflash/

We can also create a simple script that does that when given the label:

#!/bin/bash

label=${1?Usage $0 <label>}

set -e -x

pmount "/dev/disk/by-label/$label"
: mounted at "/media/disk_by-label_${label}"

5 References