Encrypting a partition with systemd
Sorry if this is known by everybody.
Please take this as a draft for an improvement of the wiki pages, which don’t cover the ways to do things with systemd.
Introduction
I wanted to encrypt the SD card of my very old samsung-rossa phone. I checked both the Alpine Wiki and the PmOS FDE pages, and they don’t mention systemd solutions. As I am familiar with encrypting partitions in my Debian computers I thought I could try and write a tutorial of how to do it using the systemd tools on a postmarketOS phone. It would be great to be able to start contributing to the project.
Basically this is no longer accurate
Alpine, like Gentoo, uses the
dmcrypt
service rather than/etc/crypttab
.
Alpine maybe, in postmarketOS you can choose now. I’m going to go the crypttab way.
How to find the partition to encrypt?
First of all you’ll have find the partition you want to encrypt. lsblk
is your tool.
# lsblk -a -f NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS loop0 loop1 loop2 loop3 loop4 loop5 loop6 loop7 mmcblk1 └─mmcblk1p1 ext4 61de6b0d-dcd6-4049-9fe8-3a15872992b5 3.6G 1% /run/media/my_user/61de6b0d-dcd6-4049-9fe8-3a15872992b5 mmcblk0 ├─mmcblk0p1 vfat 00BC-614E 51.1M 20% /lib/firmware/msm-firmware-loader/mnt/apnhlos ├─mmcblk0p2 vfat 00BC-614E 19.6M 69% /lib/firmware/msm-firmware-loader/mnt/modem ├─mmcblk0p3 ├─mmcblk0p4 ├─mmcblk0p5 ├─mmcblk0p6 ├─mmcblk0p7 ├─mmcblk0p8 ├─mmcblk0p9 ├─mmcblk0p10 ├─mmcblk0p11 ├─mmcblk0p12 ├─mmcblk0p13 ext4 57f8f4bc-abf4-655f-bf67-946fc0f9f25b ├─mmcblk0p14 ├─mmcblk0p15 ├─mmcblk0p16 ├─mmcblk0p17 ├─mmcblk0p18 ├─mmcblk0p19 ├─mmcblk0p20 ├─mmcblk0p21 ├─mmcblk0p22 ext4 57f8f4bc-abf4-655f-bf67-946fc0f9f25b 3.7M 0% /lib/firmware/msm-firmware-loader/mnt/persist ├─mmcblk0p23 ext4 57f8f4bc-abf4-655f-bf67-946fc0f9f25b ├─mmcblk0p24 ├─mmcblk0p25 ext4 57f8f4bc-abf4-655f-bf67-946fc0f9f25b ├─mmcblk0p26 ext4 57f8f4bc-abf4-655f-bf67-946fc0f9f25b └─mmcblk0p27 ├─userdata1 ext2 pmOS_boot 404cb4cc-292b-41b0-84ce-491cdecc565c 144M 31% /boot └─userdata2 ext4 pmOS_root 2327129a-45ee-4bdc-8eaa-f15751d19703 515.4M 84% / mmcblk0boot0 mmcblk0boot1
You are going to encrypt the 4Gb card /dev/mmcblk1p1
. As it was already in use (but not encrypted) first I must unmount it
# umount /run/media/my_user/61de6b0d-dcd6-4049-9fe8-3a15872992b5/
Create the encrypted partition
# cryptsetup luksFormat --type luks2 /dev/mmcblk1p1
We have created a container. Now
# cryptsetup open /dev/mmcblk1p1 secrets_crypt
creates /dev/mapper/secrets_crypt
.
# lsblk -m -T -f NAME SIZE OWNER GROUP MODE FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS mmcblk1 29G root disk brw-rw---- └─mmcblk1p1 3.9G root disk brw-rw---- crypto_LUKS 4e946a1e-444d-4aa2-a716-d7327b6349ba └─secretos_crypt 3.9G root root brw------- ext4 4fe1078f-3e52-4296-9f88-0444c6e12997 ...
Take note: UUID=4fe1078f-3e52-4296-9f88-0444c6e12997
(the numbering of disks and partitions can change, the UUID is unique).
Format it
# mkfs.ext4 /dev/mapper/secrets_crypt
Check
# cryptsetup status /dev/mapper/secrets_crypt /dev/mapper/secrets_crypt is active. type: LUKS2 cipher: aes-xts-plain64 keysize: 512 bits key location: keyring device: /dev/mmcblk1p1 sector size: 512 offset: 32768 sectors size: 8216576 sectors mode: read/write
Manual Usage
Opening and mounting the encrypted partition
# cryptsetup open UUID=4e946a1e-444d-4aa2-a716-d7327b6349ba secrets_crypt
which is equivalent to
# (just in case) # systemd-cryptsetup detach secrets_crypt # systemd-cryptsetup attach secrets_crypt /dev/disk/by-uuid/4e946a1e-444d-4aa2-a716-d7327b6349ba /root/.secrets_key luks,nofail Set cipher aes, mode xts-plain64, key size 512 bits for device /dev/disk/by-uuid/4e946a1e-444d-4aa2-a716-d7327b6349ba.
Now mount it
# mount -t ext4 /dev/mapper/secrets_crypt /mnt/.secrets
Closing the encrypted partition
# umount /mnt/.secrets # cryptsetup close secrets_crypt
Automatic Usage
We don’t want to have to open and mount the partition every time we are going to use it, but want it mounted at boot.
Create a Key File only known to root (the Key File mentioned in the tutorials above). You can use the method in the tutorials
# dd bs=512 count=4 if=/dev/urandom of=/root/.secrets_key iflag=fullblock # chmod 400 /root/.secrets_key
Add the key
# cryptsetup luksAddKey UUID="4e946a1e-444d-4aa2-a716-d7327b6349ba" /root/.secrets_key
# systemd-cryptenroll /dev/mmcblk1p1 SLOT TYPE 0 password 1 password
The first password is the one you used to create the LUKS volume, the second one is the key file.
Add or create the information to /etc/crypttab
secrets_crypt UUID=4e946a1e-444d-4aa2-a716-d7327b6349ba /root/.secrets_key luks,nofail
The following step has to do -my guess- with the service not having a preset. I have to create the rule to start the service with the information provided in crypttab
.
# /usr/lib/systemd/system-generators/systemd-cryptsetup-generator /etc/systemd/system
I don’t know if the subdirectory is the correct one - postmarketOS admins?
Rebooted. Did it work?
You can list all generated unit files using
# systemctl list-unit-files | grep systemd-cryptsetup systemd-cryptsetup@secrets_crypt.service enabled disabled
# systemctl status systemd-cryptsetup@secrets_crypt.service ● systemd-cryptsetup@secrets_crypt.service - Cryptography Setup for secrets_crypt Loaded: loaded (/etc/crypttab; enabled; preset: disabled) Active: active (exited) since Sat 2025-02-01 10:03:25 CET; 6min ago Invocation: 60fbc3a29448409fa6121523c243c281 Docs: man:crypttab(5) man:systemd-cryptsetup-generator(8) man:systemd-cryptsetup@.service(8) Main PID: 954 (code=exited, status=0/SUCCESS) Mem peak: 69.6M CPU: 4.746s Feb 01 10:03:23 samsung-rossa systemd[1]: Starting Cryptography Setup for secrets_crypt... Feb 01 10:03:23 samsung-rossa systemd-cryptsetup[954]: Set cipher aes, mode xts-plain64, key size 512 bits for device /dev/disk/by-uuid/4e946a1e-444d-4aa2-a716-d7327b6349ba. Feb 01 10:03:25 samsung-rossa systemd[1]: Finished Cryptography Setup for secrets_crypt.
This means that the command has worked (is enabled) and that there was no preset fot it - is wasn’t foreseen by the admins.
But does it really work?
# echo "this is a text" > /mnt/.secrets/test.txt # ls -l /mnt/.secrets/test.txt -rw-r--r-- 1 root root 15 Feb 3 12:42 /mnt/.secretos/test.txt
It does!
The following step is to use a hardware token, but that would be the subject of a new post.
I hope this was useful to anybody.