PI crypt

16 April 2016

Intro

Raspberry PI devices are on the rage now, they are cheap portable and run Linux, using such a device on a remote site (be it for remote backup or pentesting) requires you to keep sensitive data on remote sdcards/USB drives etc.

In this post ill cover how to setup root encrypted RPi.

Setup

Iv used a lot of resources (see footnotes) and posts in order to get a working solution using Ubuntu 15.10 as the host and Raspbian Jessie lite as the Pi OS image.

First we will setup the sdcard:

# prepare the image
$ wget https://downloads.raspberrypi.org/raspbian_lite_latest
$ unzip raspbian_lite_latest
# we assume the sdcard 
$ dd if=2016-03-18-raspbian-jessie-lite.img of=/dev/sdb bs=4M

Entering the chroot:

$ aptitude install qemu-user-static
# chrooting mostly same as in kali
$ mkdir -p /mnt/chroot/boot
$ mount /dev/sdb2 /mnt/chroot/
$ mount /dev/sdb1 /mnt/chroot/boot/
$ mount -t proc none /mnt/chroot/proc
$ mount -t sysfs none /mnt/chroot/sys
$ mount -o bind /dev /mnt/chroot/dev
$ mount -o bind /dev/pts /mnt/chroot/dev/pts
$ cp /usr/bin/qemu-arm-static /mnt/chroot/usr/bin/
# And we are home
$ LANG=C chroot /mnt/chroot/
$ uname -a
 Linux foo 4.2.0-25-generic #30-Ubuntu SMP Mon Jan 18 12:31:50 UTC 2016 armv7l GNU/Linux

Setting up initramf (yes your are running arm binaries on your x86 machine):

# Comment out the single line in this file (or else apt-get wont work)
$ vi /etc/ld.so.preload
$ apt-get update
$ apt-get install busybox cryptsetup dropbear -y

Our first mkinitramfs (the small dropbear that will load prior to the OS):

# find the kernel version for initramfs
$ ls -l /lib/modules/ |awk -F" " '{print $9}'
4.1.19+
4.1.19-v7+

# You can ignore the 'Unsupported ioctl: cmd=0x5331' at the end
$ mkinitramfs -o /boot/initramfs.gz 4.1.19-v7+
$ update-rc.d ssh enable
# set the root password for the init image
$ passwd
# Now edit and change/add root=/dev/mapper/crypt_sdcard cryptdevice=/dev/mmcblk0p2:crypt_sdcard 
$ vi /boot/cmdline.txt
# add 'initramfs initramfs.gz 0x00f00000'
$ vi /boot/config.txt

Copy the private ssh key that will enabled you to ssh to the dropbear instance (in which you enter the decryption password):

$ cat /etc/initramfs-tools/root/.ssh/id_rsa

At this point we will load modules (bypassing 'debian /sbin/cryptsetup: not found raspbian') and change the fstab to point to crypt_sdcard and:

$ cat /etc/fstab
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults 0 2
/dev/mapper/crypt_sdcard / ext4 defaults,noatime 0 1

# make sure to load the initramfs modules 
$ cat /usr/share/initramfs-tools/modules
aes
chainiv
cryptomgr 
krng
sha256
sha224
sha512
sha1
xts
cbc
ecb
ctr
dm-crypt
dm-mod
# And yet again
$ cat /etc/initramfs-tools/modules
aes
chainiv
cryptomgr 
krng
sha256
sha224
sha512
sha1
xts
cbc
ecb
ctr
dm-crypt
dm-mod
# append the following to /usr/share/initramfs-tools/hooks/cryptroot (after the askpass copy_exec):
$ cat /usr/share/initramfs-tools/hooks/cryptroot | grep /sbin/cryptsetup -A 5
copy_exec /sbin/cryptsetup
copy_exec /sbin/dmsetup
copy_exec /lib/cryptsetup/askpass
# new section
for mod in aes chainiv cryptomgr krng sha256 sha224 sha512 sha1 xts cbc ecb ctr dm-crypt dm-mod; do
 add_crypto_modules $mod
done

# ignore the cryptsetup errors since we don't have encryption set yet
$ mkinitramfs -o /boot/initramfs.gz 4.1.19-v7+

We will un-chroot and copy our work aside so we can copy it back once the drive is encrypted:

$ exit
$ umount /mnt/chroot/boot
$ umount /mnt/chroot/sys
$ umount /mnt/chroot/proc
# Backup our work thus far
$ mkdir -p /mnt/backup
$ rsync -avh /mnt/chroot/* /mnt/backup/
# finalize the un-chrooting
$ umount /mnt/chroot/dev/pts
$ umount /mnt/chroot/dev
$ umount /mnt/chroot

We will move to setting up the encrypted drive

$ echo -e "d\n2\nw" | fdisk /dev/sdb
# note the use of 131072 which is where sdb1 ends for this specific image
$ echo -e "n\np\n2\n131072\n\nw" | fdisk /dev/sdb

Extrac the SDcard (so the new partitioning scheme will be detected) and move to encrypting the new partition:

$ cryptsetup -v -y --cipher aes-cbc-essiv:sha256 --key-size 256 luksFormat /dev/sdb2
$ cryptsetup -v luksOpen /dev/sdb2 crypt_sdcard
$ mkfs.ext4 /dev/mapper/crypt_sdcard

We can now restore our backup into the new encrypted partition:

$ mkdir -p /mnt/encrypted
$ mount /dev/mapper/crypt_sdcard /mnt/encrypted/
$ rsync -avh /mnt/backup/* /mnt/encrypted/
$ umount /mnt/encrypted/
$ rm -rf /mnt/backup
$ sync
$ cryptsetup luksClose /dev/mapper/crypt_sdcard

You can now insert the SDcard into the PI and carry on to logging in.

Login

The login process is now composed of two steps, first logging into the dropbear session and decrypt the drive, the second is the usual ssh login:

# find the IP by viewing the pi load screen
$ ssh -i private root@<ip>
# Enter your key
$ /scripts/local-top/cryptroot
# trigger the boot process
$ kill -9 `ps | grep -m 1 'cryptroot' | cut -d ' ' -f 3`
# once the pi loads you should be able to login as usual
$ ssh pi@<ip>

Summary

The processes of setting the root encrypted image is quite contrived and manual at the moment, the guides out there aren't complete or up to date, this guide is a starting point for a more automated approach.

Footnotes:

  • The original tutorial for Kali Linux which gives a good outline (doesn't work as is on Raspbian tough).
  • A post which mainly helped me to solve 'qemu: uncaught target signal 4' error.
  • A post that helped solved the 'debian /sbin/cryptsetup: not found raspbian' errors
Tags: security raspberry encryption pi