All Projects → ViRb3 → pi-encrypted-boot-ssh

ViRb3 / pi-encrypted-boot-ssh

Licence: other
🔑 Raspberry Pi Encrypted Boot with Remote SSH

Projects that are alternatives of or similar to pi-encrypted-boot-ssh

re-mote
Re-mote operations using SSH and Re-gent
Stars: ✭ 61 (-36.46%)
Mutual labels:  ssh, ubuntu, remote
gba-remote-play
Stream Raspberry Pi games to a GBA via Link Cable
Stars: ✭ 356 (+270.83%)
Mutual labels:  remote, pi, raspberry
arch-pi
A simple script automatically installing Arch Linux for the Raspberry Pi.
Stars: ✭ 38 (-60.42%)
Mutual labels:  pi, raspberry
RPi-TELEBOT
Python based Telegram bot to monitor and control the raspberry pi
Stars: ✭ 19 (-80.21%)
Mutual labels:  pi, raspberry
RAK831-Zero
Pi Zero RAK831 Adapter board
Stars: ✭ 98 (+2.08%)
Mutual labels:  pi, raspberry
opencv3-setup
Raspberry Pi whiptail Menu driven Easy Install and Compile of opencv3 python from source files.
Stars: ✭ 47 (-51.04%)
Mutual labels:  pi, raspberry
Keep-It-Secure-File-Encryption
Keep It Secure Private Data Encryption & Decryption Tool
Stars: ✭ 38 (-60.42%)
Mutual labels:  secure, encrypted
HyperBian
Hyperion pre installed on Raspberry Pi OS Lite
Stars: ✭ 192 (+100%)
Mutual labels:  pi, raspberry
Psiphon
A multi-functional version of a popular network circumvention tool
Stars: ✭ 169 (+76.04%)
Mutual labels:  ssh, ubuntu
102shows
Raspberry Pi + APA102 + MQTT + 102shows = LED awesomeness!
Stars: ✭ 15 (-84.37%)
Mutual labels:  pi, raspberry
wormhole
A minimalistic Ansible-like tool for configuring remote servers via ssh
Stars: ✭ 22 (-77.08%)
Mutual labels:  ssh, remote
i2pchat
🌀 i2pchat. Anonymous private secure opensource chat using end-to-end encrypted transport.
Stars: ✭ 25 (-73.96%)
Mutual labels:  secure, encrypted
Env-KB
A custom mechanical keyboard inspired by the CFTKB Mysterium utilizing the Raspberry Pi Pico
Stars: ✭ 203 (+111.46%)
Mutual labels:  pi, raspberry
Ubuntu Sshd
Dockerized Ubuntu SSH service
Stars: ✭ 205 (+113.54%)
Mutual labels:  ssh, ubuntu
Secure Wireguard Implementation
A guide on implementing a secure Wireguard server on OVH (or any other Debian VPS) with DNSCrypt, Port Knocking & an SSH-Honeypot
Stars: ✭ 200 (+108.33%)
Mutual labels:  ssh, secure
LoraGW-Setup
SX1301 Lora Concentrator Raspberry PI based gateway setup
Stars: ✭ 70 (-27.08%)
Mutual labels:  pi, raspberry
stenogotchi
Portable stenography using Plover and bluetooth keyboard emulation on a Raspberry Pi Zero W
Stars: ✭ 71 (-26.04%)
Mutual labels:  pi, raspberry
Getssl
obtain free SSL certificates from letsencrypt ACME server Suitable for automating the process on remote servers.
Stars: ✭ 1,687 (+1657.29%)
Mutual labels:  ssh, remote
Vscode Remote Release
Visual Studio Code Remote Development: Open any folder in WSL, in a Docker container, or on a remote machine using SSH and take advantage of VS Code's full feature set.
Stars: ✭ 2,256 (+2250%)
Mutual labels:  ssh, remote
encrypted-smiley-secure-protocol
Node.JS library Encrypted Smiley ® Secure Protocol (eSSP, SSP)
Stars: ✭ 22 (-77.08%)
Mutual labels:  secure, encrypted

Raspberry Pi Encrypted Boot with SSH

⚠️ This guide is only supported for Raspberry Pi 3B & 4B with Ubuntu Server 21.04.
Other platforms and distributions may work, but there may be unexpected issues or side effects.

Introduction

This guide will show you how to encrypt your Raspberry Pi's root partition and set up an initramfs that will prompt for the password, decrypt the partition and gracefully resume boot. You will also learn how to enable SSH during this pre-boot stage, allowing you to unlock the partition remotely.

While the steps are written for the Raspberry Pi, they should be easily transferrable to other SBCs and computers as a whole.

This guide operates directly on an image file and therefore does not require an SD card for the setup. The resulting image can be flashed to an SD card as usual.

Table of Content

Requirements

  • A Raspberry Pi Linux image (e.g. Ubuntu Server 21.04)

  • A computer (host) running Linux (e.g. Xubuntu 21.04)

    ⚠️ NOTE: Your host's Linux should be as similar as possible to the Raspberry Pi's Linux. If you are preparing Ubuntu 21.04 for the Raspberry Pi, use the same version on the host, otherwise you may encounter issues inside the chroot.

On the host

Install dependencies:

You can skip qemu-user-static if your host Linux's architecture matches that of the Raspberry Pi's Linux image.

apt update
apt install -y kpartx cryptsetup-bin qemu-user-static

Create two copies of the Raspberry Pi's Linux image - one to read from (base), and one to write to (target):

  • ubuntu-base.img
  • ubuntu-target.img

Map both images as devices, ensuring the base is readonly:

kpartx -ar "$PWD/ubuntu-base.img"
kpartx -a "$PWD/ubuntu-target.img"

If your system automatically mounted any partitions, unmount them:

umount /media/**/*

Run lsblk and verify the process was successful - you should see two loopback devices, each with two partitions:

NAME      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT # COMMENT
loop0       7:0    0  3.3G  0 loop            # ubuntu-base.img
├─loop0p1 253:0    0  256M  0 part            # ├─ boot
└─loop0p2 253:1    0    3G  0 part            # └─ root
loop1       7:1    0  3.3G  1 loop            # ubuntu-target.img
├─loop1p1 253:2    0  256M  1 part            # ├─ boot
└─loop1p2 253:3    0    3G  1 part            # └─ root

Mount the base image's root partition:

mkdir -p /mnt/original/
mount /dev/mapper/loop0p2 /mnt/original/

Replace the target image's root partition with a new, encrypted partition:

⚠️ NOTE:

In this example we will use aes-adiantum as the encryption method since it is much faster on targets that lack hardware AES acceleration. Ensure that both the host's and Pi's kernel (>= 5.0.0, must include .ko) and cryptsetup (>= 2.0.6) support your encryption method.

By default cryptsetup will benchmark the system that is creating the encrypted partition to find suitable memory difficulty. This is usually half of the machine's available RAM. Since the calculation is is done on the host, it is very likely to exceed the Raspberry Pi's maximum RAM and make it impossible to unlock the partition. To prevent this, set the --pbkdf-memory argument to something less than the Pi's maximum RAM.

cryptsetup luksFormat -c xchacha20,aes-adiantum-plain64 --pbkdf-memory 512000 /dev/mapper/loop1p2

Open (decrypt) the new partition:

cryptsetup open /dev/mapper/loop1p2 crypted

Then format and mount it:

mkfs.ext4 /dev/mapper/crypted
mkdir -p /mnt/chroot/
mount /dev/mapper/crypted /mnt/chroot/

Copy the base image's root partition files to the target image's new, encrypted root partition. You can use dd, but rsync is faster:

rsync --archive --hard-links --acls --xattrs --one-file-system --numeric-ids --info="progress2" /mnt/original/* /mnt/chroot/

Set up a chroot by mounting the target image's boot partition and required virtual filesystems from the host:

mkdir -p /mnt/chroot/boot/
mount /dev/mapper/loop1p1 /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/

Enter the chroot:

LANG=C chroot /mnt/chroot/

In the chroot

Prepare

Install dependencies:

apt update
apt install -y busybox cryptsetup dropbear-initramfs

If the chroot cannot resolve hostnames, you might have a symlinked resolv.conf that is invalid in the chroot context. To work around this, back it up and create a simple nameserver replacement:

mv /etc/resolv.conf /etc/resolv.conf.bak
echo "nameserver 1.1.1.1" > /etc/resolv.conf

Device configuration

Run blkid and note the details of your encrypted and decrypted partitions:

# encrypted
/dev/mapper/loop1p2: UUID="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" TYPE="crypto_LUKS" PARTUUID="cccccccc-cc"
# decrypted
/dev/mapper/crypted: UUID="bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb" BLOCK_SIZE="4096" TYPE="ext4"

Edit /etc/fstab and replace the root entry with your decrypted (virtual) partition's device name:

/dev/mapper/crypted /               ext4  discard,errors=remount-ro 0 1
LABEL=system-boot   /boot/firmware  vfat  defaults                  0 1

Edit /etc/crypttab and add an entry with your encrypted (raw) partition's UUID:

crypted UUID=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa none luks,initramfs

Edit /boot/cmdline.txt and update the root entry:

root=/dev/mapper/crypted cryptdevice=UUID=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:crypted

Enable SSH for the decrypted OS:

touch /boot/ssh

Cryptsetup

Edit the cryptsetup initramfs hook to ensure cryptsetup ends up in the initramfs:

echo "CRYPTSETUP=y" >> /etc/cryptsetup-initramfs/conf-hook

At least on Ubuntu Server 21.04, the initramfs-tools cryptroot hook will resolve any UUIDs to device names during initramfs generation. This is a problem because the device names will likely differ between the host and the Raspberry Pi, resulting in failure to boot. To work around this, apply the following patch:

patch --no-backup-if-mismatch /usr/share/initramfs-tools/hooks/cryptroot << 'EOF'
--- cryptroot
+++ cryptroot
@@ -33,7 +33,7 @@
         printf '%s\0' "$target" >>"$DESTDIR/cryptroot/targets"
         crypttab_find_entry "$target" || return 1
         crypttab_parse_options --missing-path=warn || return 1
-        crypttab_print_entry
+        printf '%s %s %s %s\n' "$_CRYPTTAB_NAME" "$_CRYPTTAB_SOURCE" "$_CRYPTTAB_KEY" "$_CRYPTTAB_OPTIONS" >&3
     fi
 }
EOF

If you are planning to run on a Raspberry Pi 3, the default timeout when waiting for decryption (e.g. 10 seconds) may be too short and you may get a timeout error. To work around this, bump the timeout:

sed -i 's/^TIMEOUT=.*/TIMEOUT=100/g' /usr/share/cryptsetup/initramfs/bin/cryptroot-unlock

SSH

Write your SSH public key inside dropbear's authorized_keys and fix permissions:

echo "/REDACTED/" > /etc/dropbear-initramfs/authorized_keys
chmod 0600 /etc/dropbear-initramfs/authorized_keys

Build initramfs

Note whether you already have an initramdisk - it should be under /boot/initrd.img. This will decide whether you need to update your boot config later on.

Note your kernel version. If there are multiple, choose the one you want to run:

ls /lib/modules/

Build the new initramdisk using the kernel version from above, overwriting the old initramdisk if it exists:

mkinitramfs -o /boot/initrd.img "5.4.0-1008-raspi"

If you had an initramdisk when you checked in the beginning of this section, then your system is already configured to use an initramfs - no changes are necessary. Otherwise, add an entry to your boot config:

echo initramfs initrd.img >> /boot/config.txt

Cleanup

Revert any changes if you have made them before:

mv /etc/resolv.conf.bak /etc/resolv.conf

Sync and exit the chroot:

sync
history -c && exit

On the host

Unmount everything and clean up any remaining artifacts:

umount /mnt/chroot/boot
umount /mnt/chroot/sys
umount /mnt/chroot/proc
umount /mnt/chroot/dev/pts
umount /mnt/chroot/dev
umount /mnt/chroot
cryptsetup close crypted
umount /mnt/original
rm -d /mnt/chroot
rm -d /mnt/original
kpartx -d "$PWD/ubuntu-base.img"
kpartx -d "$PWD/ubuntu-target.img"

You are now ready to flash ubuntu-target.img to an SD card.

On the Raspberry Pi

Boot the Raspberry Pi with the new SD card. It will obtain an IP address from the DHCP server and start listening for SSH connections. To decrypt the root partition and continue boot, from any shell, simply run cryptroot-unlock.

Once booted into the decrypted system, you will notice that the root partition is still sized at ~3GB, no matter how much space you have on the SD card. To fix this, delete and recreate the partition, this time using all available space, then follow up with cryptsetup and ext4 resize:

echo -e "d\n2\nn\np\n2\n\n\nw" | fdisk /dev/mmcblk0
cryptsetup resize crypted
resize2fs /dev/mapper/crypted

Finally, reboot the system for good measure:

reboot

Avoiding SSH key collisions

To avoid host key collisions you can configure a separate trusted hosts store in the ~/.ssh/config of your client:

Host box
	Hostname 192.168.0.30
	User root

Host box-initramfs
	Hostname 192.168.0.30
	User root
	UserKnownHostsFile ~/.ssh/known_hosts.initramfs

Resources

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].