Skip to content

Instantly share code, notes, and snippets.

@galets
Forked from pezz/crypto-pi-root.md
Last active August 29, 2015 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save galets/149b04415ed6aa57f192 to your computer and use it in GitHub Desktop.
Save galets/149b04415ed6aa57f192 to your computer and use it in GitHub Desktop.

Intro

Just some FYI, to get started:

  • I'm using a 16 GB Sandisk SD card.
  • I have a model B Pi, 512 MB RAM (not really relevant, thought I'd mention it).
  • Monitor and keyboard connected to the Pi itself, for now.
  • Network working, internet access.

Notes

We will run no swap, like the default image, and leave the initial install on the 1.8 GB partition as a potential rescue disk. Trust me, you need to be able to run ARM binaries if you ever need to recover.

Having a rescue partition that you can boot into will be invaluable and would have saved me from my last screw-up.

Step 1

Download and dd the Arch ARM image, as per normal.

At the time of writing this (4 April, 2013) it is:

archlinux-hf-2013-02-11.zip

Run:

sudo dd if=archlinux-hf-2013-02-11.img of=/dev/mmcblk0 bs=1M

You know this bit, now put the card into your Pi.

Step 2

Boot, update everything (pacman -Syu). Based on the current image, you'll have to fix a few pacnew files.

  • Install rsync if it isn't already (a must, but I do think it's installed by default with the alarm image).
  • Install vim :)

Reboot and make sure everything is cool.

Your kernel should be (as of updating on 4 April, 2013) from uname -a:

3.6.11-9-ARCH+

Do any normal tasks now as you would otherwise when setting up a system.

All of this is optional:

  • Set your root password.
  • Set an IP, hostname etc (all the stuff systemd wants, e.g. vconsole etc).
  • Add users, your favourite shell, configure any services, etc.
  • Setup whatever else you don't want to setup later or don't mind having in a rescue environment.

We will be rsyncing this setup to the encrypted partition.

Reboot again, make sure everything is good.

Step 3

Create a new partition of at least 2 GB, I normally just fill the rest of the SD card, it's up to you though.

Use fdisk on /dev/mmcblk0 and create a new primary partition.

I would show you output, but I can't be bothered re-typing stuff I can't copy and paste.

Nevertheless, you should have an mmcblk0p1, p2 and p3.

  • p1 being the vfat boot partition - do not mess with it.
  • p2 being our current 1.8 GB root.
  • p3 being the new partition.

Step 4

dd /dev/zero over the new partition (p3), just to add a minimal amount of safety:

dd if=/dev/zero of=/dev/mmcblk0p3 bs=1M

This will take a long time. You can use if=/dev/urandom if you like, but it will take even longer.

You'll get several kernel IO hung timeout messages while this runs, but it will finish.

Be patient.

When dd finishes, create a LUKS volume on /dev/mmcblk0p3

cryptsetup -c aes-xts-plain -y -s 512 luksFormat /dev/mmcblk0p3

Do what the command says, choose a passphrase etc.

Step 5

Open the LUKS volume and put a filesystem on it:

cryptsetup luksOpen /dev/mmcblk0p3 root

Enter passphrase...

mkfs.ext4 /dev/mapper/root

Step 6

Mount the new filesystem:

mount /dev/mapper/root /mnt

Step 7

Rsync the current system over:

rsync --progress -axv / /mnt/

Don't forget the trailing / on /mnt/

This will take a long time.

Run the rsync again, just to make sure you have everything, this will be much quicker.

Step 8

We're not ready to do our "over SSH" unlock just yet, let's make sure we can at least boot the encrypted root.

Edit /etc/mkinitcpio.conf and make sure this line has:

HOOKS="base udev autodetect modconf block keyboard encrypt filesystems fsck"

Now generate an initrd:

mkinitcpio -k $(uname -r) -g /boot/initrd

Step 9

Edit /boot/config.txt and add to the end:

initramfs initrd 0x01f00000

Step 10

Edit the kernel command line, leave whatever is there alone, add or modify the following (file is /boot/cmdline.txt):

cryptdevice=/dev/mmcblk0p3:root:allow-discards root=/dev/mapper/root initrd=0x01f00000

Up to you if you want allow-discards or not, your choice.

Be sure to leave the "ro" option there.

Now add the following to fstab, edit /mnt/etc/fstab and ensure:

/dev/mmcblk0p1      /boot       vfat    defaults                    0      0
/dev/mapper/root    /           ext4    defaults,discard,commit=120 0      1

Change options to what you want.

Reboot and hope it works!

Step 11

From the console, you should now be able to enter your passphrase and boot off the encrypted root.

Your root filesystem is now the LUKS encrypted mmcblk0p3 and not p2.

Make sure the HOOKS line in /etc/mkinitcpio.conf on p3 matches what you edited before on p2.

Make sure /etc/fstab on this partition is correct (you did it right if it booted and you can do touch foo and write a file).

If you make any changes, reboot and ensure you can boot without any problems (if you are going to reboot, rebuild the initrd before you do -- just to be on the safe side).

Step 12

Install base-devel (hit enter to select all).

pacman -S base-devel

For thoroughness run:

pacman-key --init

Install an AUR helper.

pacman -S yaourt

Handy tip, add the following to /etc/yaourtrc to disable architecture checks.

MAKEPKG_ARG+=(-A)

Step 13

Install dropbear_initrd_encrypt

yaourt -S dropbear_initrd_encrypt

Change the /etc/mkinitcpio.conf HOOKS line to say:

HOOKS="base udev autodetect modconf block keyboard dropbear encryptssh filesystems fsck"

Remove anything you feel you don't need, but this is what I use. Also, order is important so make sure dropbear is before encryptssh which is before filesystems.

Step 14

By default, sshd is enabled and started, so you should have host keys generated without doing anything.

Generate dropbear keys based off your OpenSSH host keys:

[root@pi ~]# cd /etc/dropbear
[root@pi ~]# dropbearconvert openssh dropbear /etc/ssh/ssh_host_rsa_key dropbear_rsa_host_key
Key is a RSA key
Wrote key to '/etc/dropbear/dropbear_rsa_host_key'
[root@pi ~]# dropbearconvert openssh dropbear /etc/ssh/ssh_host_dsa_key dropbear_dss_host_key
Key is a DSS key
Wrote key to '/etc/dropbear/dropbear_dss_host_key'

THIS IS VERY IMPORTANT

Put your own public ssh key into /etc/dropbear/root_key (i.e. the public key you normally put onto hosts so you can ssh in without a password).

Step 15

Edit /boot/cmdline.txt and add:

ip=192.168.0.1::192.168.0.254:255.255.255.0:pi:eth0:none

Edit this to suit your setup. Replace the IP address with the address of your Pi, its gateway and its node name (pi in my case).

Now rebuild the initrd.

mkinitcpio -k $(uname -r) -g /boot/initrd

Reboot, and ssh in from another box:

ssh root@your.pi.box

Enter the passphrase and...

THE END

Any errors or omissions are due to the fact that I've been drinkin'...

Maintenance

  • You must rebuild the initrd after every kernel update. Archlinux ARM kernel packages do not run mkinitcpio automatically after kernel update like regular x86_64 Arch does.

  • When rebuilding the initrd after an update, you must provide the correct string appropriate to the new kernel.

Recovery

The easiest way to recover, in my opinion, would be to:

  • Leave the p2 partition in tact.

  • When something goes wrong, put the SD card into another system and edit cmdline.txt to boot off p2.

  • Use the system on p2 to unlock the LUKS volume etc, and chroot into it, whatever you need to do to fix the system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment