In this guide we will show how you can remotely decrypt a headless Debian or Ubuntu Linux system, that has been encrypted with LUKS.
Prerequisites
- A LUKS encrypted Debian jessie or Ubuntu xenial system
- Keyboard and monitor for the initial system setup
- Allow SSH root access on the decrypted system using public key authentication
- Use a different port for ssh (assuming port 4422) on the decrypted system
NOTE: using a different port than the standard SSH port (22) serves a double purpose. For once, you will not received the scary WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! message every time you will try to remotely unlock the system and as an additional bonus you will get less SSH attacks on the active system.
Installing dropbear
Dropbear is a lightweight SSH server especially suitable for initial ramdisk (initrd) environments and other lightweight systems.
Install dropbear:
# apt -y install dropbear
Setup public key authentication for dropbear
Create the homedir for the root user and the SSH configuration directory:
# mkdir -p /etc/initramfs-tools/root/.ssh
Append your client SSH pubkey to authorized_keys:
# cat ~/.ssh/id_rsa.pub | ssh -p 4422 root@encrypted-system "cat >> /etc/initramfs-tools/root/.ssh/authorized_keys"
Setup a static IP for the unlock environment
This step is optional but highly recommended if you are setting up a static, permanent service. If you skip this step DHCP will kick in, provided you have a DHCP Server in your environment.
Run this command to update the /etc/initramfs-tools/initramfs.conf configuration file:
echo IP=10.0.0.67::10.0.0.1:255.255.255.0:encrypted-system:eth0:off >> /etc/initramfs-tools/initramfs.conf
Explanation of the different fields:
[host_ip]::[gateway_ip]:[netmask]:[hostname]:[device]:[autoconf]
NOTE: there are two successive colons (::) after the host_ip.
Setup the unlock script
Copy the following text in /etc/initramfs-tools/hooks/crypt_unlock.sh:
#!/bin/sh
#
# By Stinky Parkia
# https://stinkyparkia.wordpress.com/2014/10/14/remote-unlocking-luks-encrypted-lvm-using-dropbear-ssh-in-ubuntu-server-14-04-1-with-static-ipst/
PREREQ="dropbear"
prereqs() {
echo "$PREREQ"
}
case "$1" in
prereqs)
prereqs
exit 0
;;
esac
. "${CONFDIR}/initramfs.conf"
. /usr/share/initramfs-tools/hook-functions
if [ "${DROPBEAR}" != "n" ] && [ -r "/etc/crypttab" ] ; then
cat > "${DESTDIR}/bin/unlock" < < EOF
#!/bin/sh
if PATH=/lib/unlock:/bin:/sbin /scripts/local-top/cryptroot; then
kill \`ps | grep cryptroot | grep -v "grep" | awk '{print \$1}'\`
# following line kill the remote shell right after the passphrase has
# been entered.
kill -9 \`ps | grep "\-sh" | grep -v "grep" | awk '{print \$1}'\`
exit 0
fi
exit 1
EOF
chmod 755 "${DESTDIR}/bin/unlock"
mkdir -p "${DESTDIR}/lib/unlock"
cat > "${DESTDIR}/lib/unlock/plymouth" < < EOF
#!/bin/sh
[ "\$1" == "--ping" ] && exit 1
/bin/plymouth "\$@"
EOF
chmod 755 "${DESTDIR}/lib/unlock/plymouth"
echo To unlock root-partition run "unlock" >> ${DESTDIR}/etc/motd
fi
Make the script executable:
# chmod +x /etc/initramfs-tools/hooks/crypt_unlock.sh
Apply the configuration
Apply the changes in the initial ramdisk:
# update-initramfs -u
Reboot the system:
# reboot
Remotely unlock the system
From your client, SSH into the initial ramdisk:
ssh root@encrypted-system
If everything is correct you will be greeted by this MOTD:
To unlock root-partition run unlock
BusyBox v1.22.1 (Ubuntu 1:1.22.0-15ubuntu1) built-in shell (ash)
Enter 'help' for a list of built-in commands.
Unlock the system and boot into it:
# unlock
Please unlock disk sda3_crypt:
You will get the following message and you will exit the remote shell if successful:
cryptsetup: sda3_crypt set up successfully
Connection to 10.0.0.67 closed.
You can now login to the active Linux system using the alternative port 4422:
ssh -p 4422 root@encrypted-system
If you can login successfully to your system you can remove the keyboard and monitor and hide your system somewhere where the Sun does not shine :).
Thanks to Stinky Parkia for the excellent guide and the brilliant unlock script.
References
- https://stinkyparkia.wordpress.com/2014/10/14/remote-unlocking-luks-encrypted-lvm-using-dropbear-ssh-in-ubuntu-server-14-04-1-with-static-ipst/
12 replies on “How to remotely decrypt a LUKS encrypted Debian/Ubuntu System”
It’s much easier than this at least on upcoming Debian 9/stretch, possibly also on Debian 8/jessie.
add the IP= line if you don’t wan’t to use DHCP
and then
Not on jessie. Something to try out when stretch comes out. Thanks!
Just wanted to say thank you for the tutorial this works just great on my Ubuntu 16.04 box.
I do have a couple of items to add.
When using multiple network interfaces best practice to lock down the configure inside initramfs.conf down to one device by using the ‘DEVICE=’ else you will need to make multiple IP= lines inside the config so you guarantee the IP address used by dropbear.
The line reads ‘exec /sbin/dropbear ${DROPBEAR_OPTIONS:-$PKGOPTION_dropbear_OPTION} -Fs’
Append -p XXXX where XXXX is the port number used for the dropbear so it will not overlap with the port that is by your openssh thus avoiding the warnings when sshing into your machine.
Thanks for the additional info Richard.
Great tutorial. However I am having a very strange problem. I am able to successfully unlock the filesystem using dropbear SSH and a static IP. But after a few moments and the filesystem builds, when I try to SSH into the box on the same IP and port, I get a network unreachable error. can anyone advise?
Well the idea of the tutorial is to have a different port when the server is in production. In the tutorial we are using port 4422. So if you try this it will probably work:
in Stretch there is already a cryptroot-unlock script included
Indeed. This article should be considered obsolete for stretch.
[…] Theodotos Andreou on How to remotely decrypt a LUKS encrypted Debian/Ubuntu System […]
Hey man, great tutorial.
I had a few questions though.
I am looking to set up an environment like this, however, I need it in the following architecture.
Instead of initiating the unlock from the local host, how would I make it so when the encrypted server boots, it automatically calls the keyserver, retrieves a key file or passphrase, then unlocks the drive.
Thanks!
A more automated workflow is provided by Mandos:
https://wiki.recompile.se/wiki/Mandos
It does have it’s limitations though. Make sure you read the FAQ:
https://www.recompile.se/mandos/man/intro.8mandos
[…] post: https://www.theo-andreou.org/?p=1579 is genius. Except where it isn’t, if you see what we […]