Apologies
Dear readers, I apologize sincerely. This blog was supposed to be about security, however my first post will be related to system administration. That said, let's get our hands dirty!
Genesis of the idea
I recently bought a new PC to replace my old laptop that finaly decided to die a few weeks ago. As I already own a laptop for professional purposes, I decided to go for a desktop computer that would allow me to have some more power and storage. At the time, I was thinking about setting up an encrypted RAID1 array for my system partition and a RAID5 array dedicated to storage, with the usual ext4 + LVM + MDADM + LUKS combo. Speaking with a good friend of mine about this project, he finally said "You may wanna try ZFS, it supports native encryption and RAID, but it may be a bit overkill in your situation".
I like overkill.
So I set up my encrypted RAID1 system array pretty easily thanks to the documentation and the many tutorials available out there. Then, I configured my motherboard for Wake-On-LAN which was also quite straightforward, but when the time came to decrypt my root filesystem remotely (over SSH), I realized that no such module had been implemented so far.
How to it works (short version)
I adopted a strategy similar to this packages'. The approach is quite simple:
- Connect to the server using an early SSH server (either Dropbear or TinySSH)
- Detect and unlock the root filesystem using the zfs_decrypt function implemented in the zfs hook
- Kill the existing ZFS decryption routine to allow the boot process to continue Thanks to the great @minextu, this feature is now live if you're using the archzfs repository, since this Pull Request has been merged.
How to make it work
Finally, the interesting bit ! Here's the walkthrough...
Install an early SSH server (Dropbear)
We need to install and configure the SSH server first.
- Install mkinitcpio-netconf and mkinitcpio-dropbear from the AUR.
- Configure the netconf module. Here is the kernel option in the bootloader entry that I use for DHCP:
ip=:::::eth0:dhcp
- Alternatively, you can use the following to specify a static IP and a gateway address (more options here):
ip=192.168.1.1::192.168.1.254:255.255.255.0::eth0:none
- Generate a new SSH key.
- Copy the public key to /etc/dropbear/root_key. It will be automatically imported when the ramdisk is built by mkinitcpio.
- If you want to modify the port on which Dropbear is listening, it is possible to copy /usr/lib/initcpio/hooks/dropbear to /etc/initcpio/hooks/dropbear and modify the dropbear command line
/usr/sbin/dropbear -E -s -j -k -p port
Activate kernel hooks
We're nearly done. I personnally load the kernel hooks in this particular order in /etc/mkinitcpio.conf:
HOOKS=(base udev autodetect modconf block keyboard keymap netconf dropbear zfsencryptssh zfs filesystems)
And the last step, regenerate your ramdisk!
mkinitcpio -p linux
Any error should be displayed when the kernel image is configured.
Enjoy
Here we are, now you should be able to connect to your server and unlock your root filesystem remotely.
Stay tuned for more tech and security related articles!
Need offensive security services, or application security support? CryptID has got you covered!