Auto‑mount encrypted memory card at boot

Encrypt the memory card with a key file instead of a password

Intro

Disclaimer I: This worked for me. Chances are it will work for you, too, but this is not a copy-paste tutorial. Stay vigilant, messing up will be on you. Make a backup before you begin. Maybe you should also know how to perform recovery. Nota bene: "Turn the phone OFF" = press the power button really, really long. Maybe two minutes.

Disclaimer II: If you want to open encryption automatically, you have to store the key somewhere, which makes the whole thing potentially less secure.

Without Udev

There are other approaches to this involving udev rules to unlock & mount every time you insert/remove the card. This is different - the idea is that the memory card mostly stays where it is and that apps can rely on it being mounted. Manual un/mounting, removal and insertion, is still possible though.

Prerequisites

Consider reading the "Connect to PC" chapter from this article.

Encrypt the memory card with a key file instead of a password

Format the card through the UI (Settings-> Storage), with encryption, using a Linux filesystem (ext4). It will ask for a password - enter a good one, we are not going to discard this option.
Unlock & mount it.

Open a terminal.
To get an overview of where we are:

$> lsblk

It should show luks-$UUID11, mounted on /run/media/*/$UUID2.

Start a root session.

$> devel-su

First we add a key file to the LUKS container. You can use any file of any size, or generate one:

#> dd if=/dev/urandom of=/path/to/some.key bs=1M count=1
#> cryptsetup luksAddKey UUID="$UUID1" /path/to/some.key

It will ask for your passphrase, then add the key; so now there's two ways to open the encryption.

Test if it works:

#> cryptsetup luksOpen UUID="$UUID1" --key-file=/path/to/some.key luks-"$UUID1"

Enable user mounting

Execute this command and add the complete line to /etc/fstab:

#> grep luks-$UUID1 /etc/mtab

Add noauto,user to the options. So the string that now probably looks like
rw,nosuid,nodev,relatime,errors=remount-ro,data=ordered
should become
noauto,user,rw,nosuid,nodev,relatime,errors=remount-ro,data=ordered
in /etc/fstab. IMPORTANT!

#> reboot

...and hope you did it right. Nothing happens yet - the system won't (yet) automount this partition.

Two systemd services to prepare and mount the card

The card can be automatically mounted as a normal user, but not without some preparations during the boot process.

First, create a file that contains both UUIDs as environment variables, for convenience (see .service files):

$> echo -e 'UUID1="XXXXXXXXXXXXXXXXXXXXXXXXXXXX"\nUUID2="XXXXXXXXXXXXXXXXXXXXXXXXXXXX"' > /path/to/automount-memcard.env

As root

Create /etc/systemd/system/automount-memcard-prepare.service:

ini
[Unit] Description=Prepare Automount memory card After=local-fs.target cryptsetup.target graphical.target multi-user.target Requires=local-fs.target cryptsetup.target graphical.target multi-user.target [Service] EnvironmentFile=/path/to/automount-memcard.env ExecStart=/bin/sh -c '{ [ -z "$UUID1" ] || [ -z "$UUID2" ]; } && exit 1;\ cryptsetup luksOpen UUID="$UUID1" \ --key-file=/path/to/some.key luks-"$UUID1"; \ mkdir -p /run/media/nemo/"$UUID2"; \ chown 100000:100000 /run/media/nemo/"$UUID2";' [Install] WantedBy=multi-user.target

It opens the encryption and creates the directory to mount on, with the right ownership.

Take care you get all the backslashes \ right, otherwise systemd might balk and leave your phone with a WSOD2.

As usual, start, check status, enable if OK:

#> systemctl start automount-memcard-prepare.service
#> systemctl status automount-memcard-prepare.service
#> systemctl enable automount-memcard-prepare.service

exit the superuser session.

As normal user

Create ~/.config/systemd/user/automount-memcard.service:

ini
[Unit] Description=Automount memory card After=user-session.target Requires=user-session.target [Service] EnvironmentFile=/path/to/automount-memcard.env ExecStart=/bin/bash -c '[ -z "$UUID1" ] && [ -z "$UUID2" ] && exit 1;\ ok=0; for ((i=0;i<100;i++)); do \ sleep 1;\ [ -b /dev/mapper/luks-"$UUID1" ] \ && [ -d /run/media/nemo/"$UUID2" ] \ && [ "$(stat -c %%u /run/media/nemo/"$UUID2"/)" = 100000 ] \ && ok=1 && break;\ done;\ [ "$ok" = 1 ] && ! grep -q /run/media/nemo/"$UUID2" /etc/mtab && mount -v /run/media/nemo/"$UUID2"' [Install] WantedBy=user-session.target

It waits until the preparations from the first service have completed, then mounts the luksOpened partition.

Again, start, check status, enable if OK:

$> systemctl --user start automount-memcard.service
$> systemctl --user status automount-memcard.service
$> systemctl --user enable automount-memcard.service

This should have worked if you followed exactly until now. Test with a reboot, go to Settings=>Storage, the memory card should be there, mounted and ready to use.

I took some pictures; the camera app decided to store them on the memory card, but the gallery app did not see them.

Solution:

  • Install Sailfish Utilities from the Jolla store.
  • In Settings=>Utilities, clear the tracker database

The system starts rebuilding the database. This takes a few minutes, and the gallery won't be usable until this is done. Try pidof tracker-extract-3 to see if it's still building.


  1. A UUID is a long string of hexadecimal numbers separated by hyphens, in this exact (afaik) format: nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn (i.e. 8-4-4-4-12). It is unique for each device. Please substitute accordingly whenever the text reads $UUID1 or $UUID2

  2. White Screen Of Death. Fixable with booting into recovery & editing or removing the file. There's no such thing as a bricked SFOS phone.