Skip to content

Instantly share code, notes, and snippets.

@Caerostris
Last active September 6, 2015 15:15
Show Gist options
  • Save Caerostris/1eed683facb98fb22ca9 to your computer and use it in GitHub Desktop.
Save Caerostris/1eed683facb98fb22ca9 to your computer and use it in GitHub Desktop.

KVM / Xen VPS full disk encryption done right

# Install Ubuntu over SSH

At the moment, your only way to run the Ubuntu installation is via VNC. However, VNC is completely unencrypted. If you transmit your encryption password via VNC, you might just as well not encrypt your server.
In order to perform the installation securely, we need to run the installation via SSH.

Starting the installation via SSH

Boot your server from the Ubuntu Server installation disk. Press F6 in the boot menu and activate expert mode.
Start the installation and configure your language and keyboard.
Now, choose Load installer components from CD and load the network-console component.
Go ahead and configure your network. If you are using DHCP this step should be fairly straightforward. If not you will have to manually provide the details.
Once your network is configured, Continue the installation remotely using SSH. Choose a strong password, even though it's just temporary. The installer has a bug which does not allow you to use spaces in your password. After you entered your password you will be presented with the server's SSH key fingerprint. Leave the page open and fire up your console. In your console, type
ssh installer@yourip
Make sure to compare the fingerprint and only type "yes" if they match.

## Performing the installation

Via SSH, choose "Start installer" and continue the installation as usual.

  • Set up users and passwords
  • Configure the clock
  • Detect disks
  • Partition disks

At partition disks, choose Guided - Use entire disk and set up encrypted LVM.
Follow the steps.

Next, choose Install the system. When asked, either choose linux-generic or linux-virtual. The targeted drivers did not work for me and after choosing it once I had to start over.
Configure the package manager. Do not use a network mirror.
Select and install software. Make sure to check Basic Ubuntu server and OpenSSH server. If you don't check it, it won't install Ubuntu Server or you won't be able to connect using SSH.
Install the grub bootloader to the Master Boot Record (MBR) and Finish the installation.
When the server reboots after the installation finished, do not enter your LUKS password via VNC!

## Unlocking LUKS via SSH

Instead, boot the Ubuntu installer CD again.
At the main menu, press F6 to enable the expert mode and choose Rescue a broken sytstem.
Follow the previous steps to start the installation via SSH.

Once you logged in via SSH, hit Start installer (expert mode).
Choose Enter rescue mode. When asked, enter the password for your LUKS volume.
The installer will ask you for a device to use as root file system. Choose /dev/*-vg/root where * is your hostname.
At the menu Rescue operations, choose Execute a shell in /dev/*-vg/root.
On my installation, the main ubuntu repository was not enable by default. I had to run

sudo add-apt-repository "deb http://us.archive.ubuntu.com/ubuntu/ trusty main universe multiverse"
sudo add-apt-repository "deb http://us.archive.ubuntu.com/ubuntu/ trusty-updates main universe multiverse"

to add it to the list.
Also, DNS resolution did not work from the rescue CD so I had to manually add us.archive.ubuntu.com and security.ubuntu.com to /etc/hosts.

Once you added the repository and made sure that apt-get update is working, install the dropbear SSH server:
apt-get install dropbear.
Edit /etc/initramfs-tools/root/.ssh/authorized_keys and replace dropbears default key with your own public key.

Copy and paste the following scripts to the server: /etc/initramfs-tools/hooks/crypt_unlock.sh

#!/bin/sh

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
    #run unlock on ssh login
    echo unlock>${DESTDIR}/root/.profile
	#write the unlock script
    cat > "${DESTDIR}/bin/unlock" << EOF
#!/bin/sh

# Read passphrase
read_pass()
{
    # Disable echo.
    stty -echo

    # Set up trap to ensure echo is enabled before exiting if the script
    # is terminated while echo is disabled.
    trap 'stty echo' EXIT SIGINT

    # Read passphrase.
    read "\$@"

    # Enable echo.
    stty echo
    trap - EXIT SIGINT

    # Print a newline because the newline entered by the user after
    # entering the passcode is not echoed. This ensures that the
    # next line of output begins at a new line.
    echo
}

printf "Enter passphrase: "
read_pass password

# kill plymouth
plymouth --quit

echo -ne "\$password" > /lib/cryptsetup/passfifo

EOF

    chmod +x "${DESTDIR}/bin/unlock"

    echo On successful unlock this ssh-session will disconnect. >> ${DESTDIR}/etc/motd
    echo Run \"unlock\" to get passphrase prompt back if you end up in the shell. >> ${DESTDIR}/etc/motd
fi

This script will auto-run an unlock script when you connect to the dropbear SSH server.

/etc/initramfs-tools/scripts/init-bottom/reset_network

#!/bin/sh

PREREQ=""

prereqs() {
	echo "$PREREQ"
}

case "$1" in
	prereqs)
		prereqs
		exit 0
	;;
esac

. /scripts/functions

log_begin_msg "Resetting network on eth0"

ifconfig eth0 0.0.0.0 down

log_end_msg

This script resets the network interface once it is not required by dropbear anymore. Without this script, the server will hang for a minute at every boot, waiting for the interface.

/etc/initramfs-tools/scripts/init-bottom/kill_dropbear

#!/bin/sh

PREREQ=""

prereqs() {
	echo "$PREREQ"
}

case "$1" in
	prereqs)
		prereqs
		exit 0
	;;
esac

. /scripts/functions

log_begin_msg "Killing dropbear"

kill `ps | grep dropbear | grep -v grep | awk '{print $1}'`

log_end_msg

This script will kill the dropbear server after the password was successfully entered. This has two advantages: After the dropbear SSH server was used to unlock the LUKS volume, the server resumes normal startup. Dropbear is stopped again and the OpenSSH server is started. However, the current SSH connection to dropbear is left open. To me it just feels better to have dropbear completely shut down when OpenSSH starts. Secondly, without this script you won't know if you successfully entered the password via dropbear or not. With this script, the dropbear session will be killed. If it disconnects, you know you entered the right password.

Change the permissions for all scripts:

chmod +x /etc/initramfs-tools/hooks/crypt_unlock.sh
chmod +x /etc/initramfs-tools/scripts/init-bottom/reset_network
chmod +x /etc/initramfs-tools/scripts/init-bottom/kill_dropbear

If your server does not get it's IP address via DHCP, you also need to manually configure the network for the boot process:

Edit /etc/initramfs-tools/initramfs.conf. Search for the line DEVICE=. Just below this line, type
IP=192.168.0.10::192.168.0.254:255.255.255.0::eth0:off
Obviously, you'll have to replace these values with your actual values. The line has the format
IP=[ip]::[gateway]:[netmask]:[hostname]:[interface]:[autoconf]
You can leave the hostname blank.
Make sure to capitalise IP= as the config is case-sensitive.

Last but not least, update your initramfs and reboot the server:
update-initramfs -u
exit
Reboot the system

  • initramfs network config
  • copy initramfs unlock & network scripts
  • chmod +x scripts
  • update-initramfs
  • reboot, connect using SSH
  • type password
  • re-connect using SSH
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment