Last updated by YesDay on 16 March 2018 Tags: odroid-c2 archlinux alarm luks fde encryption

1. Overview of the OS image

1.1. Introduction

This is an OS image for ODROID-C2. The root filesystem is encrypted with LUKS to provide additional protection against unauthorised access, particularly in the case when someone gains physical access to the device. The configuration is suitable for both headless and non headless setup, and supports remote unlocking (via SSH) of the encrypted root filesystem during the boot process.

The image is based on the ODROID-C2 ArchLinux ARM image, with additional software and configuration.

A pre-configured SSH key is provided to allow remotely unlocking the encrypted root filesystem during the initial boot. Upon successful boot you’re advised to disable this key for security reasons.

Moreover, after flashing the image and right after the initial boot make sure to:

  • change the default password yesday for the users (root, alarm) and the LUKS volume

  • run the provided expand-filesystem-luks script in order to expand the root filesystem partition to the rest of the available space (find instructions in the relevant section below)

  • follow the steps from Errata to fix known issues

Finally, if you would like to know how this image was created, or prefer to create the image yourself, refer to: How to install ArchLinux with Full Disk Encryption on ODROID-C2

1.2. Basic facts

Note
Generally speaking, encrypted data is hard to compress therefore the compression ratio of this OS image is relatively low.

1.3. Additional software

The image adds the following software on top of the ODROID-C2 ArchLinux ARM image:

  • Basic - sudo python git rsync

  • AUR helper - base-devel cower pacaur

  • Initramfs generator - dracut

  • Encryption - lvm2 cryptsetup

  • LUKS remote unlocking - dhclient dropbear dracut-crypt-ssh

  • Custom utility scripts - expand-filesystem-luks

2. Flash the OS image into microSD card or eMMC module

Replace /dev/mmcblk0 in the following instructions with the device name for the microSD card as it appears on your computer. Use the provided microSD to eMMC adapter card to install to eMMC.

Download the OS image (1.7G) and MD5 checksum

wget https://github.com/yesday/odroid-c2-archlinux-luks/releases/download/v0.0.1/odroid-c2-archlinux-luks.img.gz
wget https://github.com/yesday/odroid-c2-archlinux-luks/releases/download/v0.0.1/odroid-c2-archlinux-luks.img.gz.md5sum

Verify the MD5 checksum

md5sum -c odroid-c2-archlinux-luks.img.gz.md5sum

Unmount all the partitions of the microSD card

lsblk
umount /dev/mmcblk0p1
umount /dev/mmcblk0p2

Flash the OS image into the microSD card (completes in ~ 6 min)

gunzip --stdout odroid-c2-archlinux-luks.img.gz | sudo dd bs=10M of=/dev/mmcblk0

Flash all cached data into the microSD card (as shown, multiple executions are required)

sync
sync
sync

3. Boot into the OS image

There are three options to interact with the ODROID-C2:

After choosing one of the above options, connect the microSD card to the ODROID-C2 and boot. With either option, since the root filesystem is encrypted, you will be prompted to enter the password to unlock the root filesystem during boot. As with the user passwords, the default password for the LUKS volume is yesday.

4. Initial commands

The default password in the below instructions is yesday.

Change the password of the users alarm and root

passwd
su
passwd

Change the LUKS password (caution: device name /dev/mmcblk0 might be different on your ODROID-C2)

sudo cryptsetup luksChangeKey /dev/mmcblk0p2 -S 0
Note
LUKS/dm_crypt enabled devices may hold up to 10 different keyfiles/passwords. Refer to the relevant documentation for further details.

If you wish to be able to remotely unlock the LUKS volume then follow the instructions in How to remotely unlock the LUKS rootfs during boot. Otherwise, make sure to remove the pre-configured SSH key from the Dropbear configuration by following these steps:

Re-encrypt the partition /dev/mmcblk0p2 by following the instructions from https://www.systutorials.com/docs/linux/man/8-cryptsetup-reencrypt/. This will ensure a new key is used to encrypt the data.

Expand the root filesystem partition to the rest of the available space

sudo expand-filesystem-luks
sudo reboot
sudo expand-filesystem-luks
sudo reboot # optional

Verify the root filesystem partition now occupies the entire space of the microSD card

df -h

Follow the instructions from How to upgrade the software

5. How to remotely unlock the LUKS rootfs during boot

The remote unlocking functionality is implemented by the dracut module crypt-ssh. Refer to the module’s documentation for additional details.

The module starts the Dropbear SSH server during boot to allow remotely unlocking the LUKS rootfs. If unlocking succeeded, the Dropbear terminates itself and your connection.

Replace 10.0.0.100 in the following instructions with the IP address assigned to the ODROID-C2 by your local DHCP server. Use the fing tool to find the assigned IP address (e.g. sudo fing 10.0.0.1/24).

5.1. Configure access to the Dropbear server

In order to connect you have to register the public SSH key of your Linux box to the remote Dropbear server. For convenience, this image comes with a pre-configured SSH key, which you can use in order to connect for the first time. For security reasons, you are strongly advised to disable the pre-configured key from the Dropbear configuration right after the initial boot.

Using the pre-configured SSH key, unlock the LUKS rootfs. To do so, follow the instructions from Unlocking the volume interactively but use the pre-configured SSH key to connect (e.g. ssh -i id_rsa root@10.0.0.100).

Once the remote system is unlocked and booted, go to your Linux box, and copy the ssh public key to the appconf/dracut-crypt-ssh/authorized_keys file on the remote ODROID-C2 server

cat ~/.ssh/*.pub | ssh alarm@10.0.0.100 'umask 077; mkdir -p appconf/dracut-crypt-ssh; touch appconf/dracut-crypt-ssh/authorized_keys; cat >appconf/dracut-crypt-ssh/authorized_keys'

The above command overrides the existing configuration, therefore the pre-configured SSH key will no longer be permitted access.

To apply the changes run the Dracut command to generate the initramfs

5.2. Unlocking the volume interactively

From your Linux box, connect to the remote Dropbear SSH server running on the ODROID-C2

ssh -p 222 root@10.0.0.100

Unlock the volume (asks you for the passphrase and sends it to console)

console_auth
Passphrase:

If unlocking the device succeeded, the initramfs will clean up itself and Dropbear terminates itself and your connection.

Additional commands
  • console_peek Prints what’s on the console

Note
There is also the unlock command but we encountered this issue when tested it at the time of this writing with all the latest updates installed.

5.3. Unlocking the volume using a password file

Some use cases require to feed input automatically to the interactive command console_auth.

From your Linux box, unlock the volume

ssh -p 222 root@10.0.0.100 console_auth < password-file

or

gpg2 --decrypt password-file.gpg | ssh -p 222 root@10.0.0.100 console_auth

5.4. OPTIONAL: Restrict access to the console_auth command

For additional security, you might want to only allow the execution of the command console_auth and nothing else. To achieve this you need to configure the SSH key with restricting options in the authorized_keys file.

From your Linux box, copy the public SSH key, with restricting options, to the appconf/dracut-crypt-ssh/authorized_keys file on the remote ODROID-C2 server

(printf 'command="console_auth",no-agent-forwarding,no-port-forwarding,no-pty,no-X11-forwarding ' && cat ~/.ssh/*.pub) | ssh alarm@10.0.0.100 'umask 077; mkdir -p appconf/dracut-crypt-ssh; touch appconf/dracut-crypt-ssh/authorized_keys; cat >appconf/dracut-crypt-ssh/authorized_keys'

Refer to the Dropbear documentation for a full list of restricting options. Prior to continuing, it might be a good idea to create a copy of the initramfs

sudo cp /boot/initramfs-linux.img /boot/initramfs-linux.img-`date +%y%m%d-%H%M%S`
Caution
In headless setup, carefuly examine the restricting options to avoid locking yourself out.

Generate new initramfs using dracut

sudo dracut --force --hostonly -a "network crypt lvm crypt-ssh" /boot/initramfs-linux.img

In this case, you can unlock the volume interactively by simply typing

ssh -p 222 root@10.0.0.100

Note that when typing the above command:

  • The console_auth command is automatically invoked on the remote server and immediately prompts for password, as if you just typed ssh -p 222 root@10.0.0.100 console_auth.

  • While you type the password, it will be displayed on the screen in plain text. Therefore, you should avoid unlocking interactively when the access is restricted to the console_auth command.

  • When you press enter you will be disconnected no matter whether the password was correct or not. Whereas with the non-restricted login (see Unlocking the volume interactively) you would only be disconnected if the password was correct, meaning that you would have feedback for whether the unlocking was successful or not.

On the other hand, to unlock the volume using a password file, from your Linux box, type

ssh -p 222 root@10.0.0.100 < password-file

or

gpg2 --decrypt password-file.gpg | ssh -p 222 root@10.0.0.100

5.5. OPTIONAL: Configure static IP for the Dropbear server

This image comes with the Dropbear server configured with DHCP by default. However, in a headless setup you might want to use static IP instead.

To enable static IP during boot, replace the dracut option ip=dhcp with static IP configuration inside bootargs

sudo nano /boot/boot.ini
setenv bootargs "rd.neednet=1 ip=10.0.0.100::10.0.0.1:255.255.255.0:archlinux-luks-host:eth0:off rd.luks.uuid=ae51db2d-0890-4b1b-abc5-8c10f01da353 root=/dev/mapper/vg-root rootwait <leave the rest as is>"

Refer to network documentation of dracut and dracut options for more options (man dracut.cmdline).

Reboot so that the new configuration takes effect

sudo reboot

6. How to upgrade the software

The majority of the software is installed via the standard pacman tool and the pacaur AUR helper. In order to upgrade, type

sudo pacman -Syu
pacaur -Syua

(Optional) The dracut module crypt-ssh is installed from source code. Follow these steps to upgrade.

cd ~/github-src/dracut-crypt-ssh/dracut-crypt-ssh
git pull
./configure
make
sudo make install
Note
As of 19 Sep 2017 the dracut module crypt-ssh is also available as a package within the AUR. If you prefer to use the package then remove the relevant files manually (sudo make uninstall not available) and install the package by typing: pacaur -S dracut-crypt-ssh-git.

7. Dracut command to generate the initramfs

Mind that the order of the modules in the below command is important

sudo dracut --force --hostonly -a "network crypt lvm crypt-ssh" /boot/initramfs-linux.img

8. Errata

8.1. Configure Dropbear to listen on port 222 instead of the standard SSH port 22

This will prevent the SSH host verification warning due to the fact that Dropbear and OpenSSH use different host keys (see also Dropbear+OpenSSH: share keys).

Remove the line dropbear_port="22" from /etc/dracut.conf.d/crypt-ssh.conf

Generate new initramfs

sudo dracut --force --hostonly -a "network crypt lvm crypt-ssh" /boot/initramfs-linux.img

8.2. OPTIONAL: Install dracut-crypt-ssh from AUR

The dracut module crypt-ssh is installed from source code under the directory ~/github-src/dracut-crypt-ssh/dracut-crypt-ssh.

As of 19 Sep 2017 the module is also available as a package within the AUR.

If you prefer to use the package then remove the relevant files manually (sudo make uninstall not available) and install the package by typing: pacaur -S dracut-crypt-ssh-git.

8.3. OPTIONAL: Use trizen instead of pacaur

As of 2017-12-15, pacaur is no longer maintained and users are encouraged to move to another solution (refer to the Pinned Comment of the package).

To install trizen, which is an alternative AUR helper, follow these steps

sudo pacman -S --needed base-devel
mkdir ~/aur && cd $_
git clone https://aur.archlinux.org/trizen.git
cd trizen
makepkg -si --needed --noconfirm