Install LVM LUKS

From Void Linux Wiki
Revision as of 11:41, 11 May 2019 by Piraty (talk | contribs) (warning about ed25519 keys + improve wording)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Here are some pointers to get you started on getting (parts of a) system encrypted with LUKS while using Void Linux.

Install Void manually with encrypted root filesystem and unencrypted boot partition

NOTE: Don't just copy and paste. There are notes indicating when you might need to alter things to match your system, but most importantly, think before you run a command!
NOTE: So far, this article only contains confirmed information for BIOS systems. Hopefully any EFI/UEFI information will be added later.

1. Boot the Void live CD, then find your way to a command prompt. If you booted the minimal install, then run bash to enter a bash shell rather than the default sh, which lacks features like up-arrow history scrolling and tab completion.

2. Run sudo fdisk -l to list all available disks on the system, and take note of the disk you want to install to. This article will now refer to the install disk as /dev/sda, substitute where necessary.

3. Now we're going to overwrite the disk with random data. Warning! This will erase ALL data on the disk you specify, and the whole point of doing this is to make any previous data nigh-unrecoverable, so it's unlikely you'll be able to get anything back. Be very careful not to erase the wrong disk. To wipe the disk, run dd if=/dev/urandom of=/dev/sda. Make sure you use the correct name for your label! This is the last time I'll remind you! This process *will* take a long time, potentially an order of hours depending on your disk size, and requires no user interaction. This is a task to leave running while you're occupied with something else if possible.

4. Run cfdisk /dev/sda. Create two partitions, one 1GB in size with the boot flag enabled for the boot partition, and one for the rest of the filesystem -- make this whatever size you need, the rest of the disk is the default and a common choice.

5. Set up the ext2 filesystem on the boot partition by running mkfs.ext2 -L boot /dev/sda1.

6. Setup encryption on the desired partition:

cryptsetup luksFormat /dev/sda2 # Initialises the LUKS partition. Will prompt you to enter and confirm the passphrase which will be used to unlock the partition, make sure you choose something secure.

cryptsetup luksOpen /dev/sda2 <device-name> # Prompts you for the set password and unlocks the drive, creating a special device file to represent it in /dev/mapper/<device-name>.

Anything written in <angle-brackets> can be any name you choose.

7. Create a volume group called <volume-group-name> in the device we just unlocked:

vgcreate <volume-group-name> /dev/mapper/<device-name>

8. Create a logical volume (LV) inside the logical volume group to hold the root filesystem of your install:

lvcreate --name <root-name> -L 20G <volume-group-name>

The -L flag is used to specify an exact size, here we picked 20 Gigabytes as an example. If you'd like to specify a percentage of the available space, then use the -l flag instead, like so:

lvcreate --name <root-name> -l 100%free <volume-group-name>

This makes it easy to use all available space without figuring out its exact size.

9. Now we're going to create an ext4 filesystem inside of the logical volume:

mkfs.ext4 -L <root-name> /dev/<volume-group-name>/<root-name>

10. Next, we mount the LVM device to the filesystem of our live OS so we can directly manipulate its filesystem:

mount /dev/<volume-group-name>/<root-name> /mnt

Now the root of the logical volume can be accessed in /mnt, just like a regular mounted partition</code>

Set up the boot directory and mount our unencrypted partition to it:

mkdir /mnt/boot
mount /dev/sda1 /mnt/boot

Now we need to set up enough of a bare-bones Linux file hierarchy so that xbps can install our system for us.

for dir in dev proc sys; do
>mkdir /mnt/$dir
>mount --rbind /$dir /mnt/$dir
>done

11. Time to install Void. We need the base-system, cryptsetup, lvm2 and grub packages in order for our bare-bones system to function, so that's all we'll install for now.

xbps-install -Sy -R https://alpha.de.repo.voidlinux.org/current -r /mnt base-system lvm2 cryptsetup grub

This will download and install all of the required packages. Overview of flags:

-S -- used to force xbps to update from the repository rather than relying on local package cache

-y -- automatically answer "yes" to all questions

-R -- specify a particular repository url

-r -- specify a non-standard root directory (we need to use this to tell xbps to install packages in /mnt. Without this option we'd install all the packages to our live system, which isn't what we want.)

12. Now we can chroot into our new Void environment: chroot /mnt /bin/bash

13. Set the root account's password with passwd root.

14. Set ownership and permissions for the root directory:

chown root:root /
chmod 755 /

15. Set the machine's hostname using echo <your-hostname> > /etc/hostname.

If you're on a network with a set naming scheme, then ask your system administrator what the hostname should be. If you don't know if your network has a set naming scheme, then ask your system administrator if it does. Otherwise, you can just make something up here.

16. Open /etc/fstab in your text editor of choice (vi is available by default). Then add your partitions to the table in the file. An example fstab would look like this:

# <file system>	  <dir> <type>  <options>             <dump>  <pass>
tmpfs             /tmp  tmpfs   defaults,nosuid,nodev 0       0
/dev/sda1         /boot ext2    defaults              0       0
/dev/sda2         /     ext4    defaults              0       0

17. Install grub to the disk: grub-install /dev/sda

18. Set up language options:

echo "LANG=en_US.UTF-8" > /etc/locale.conf
echo "en_US.UTF-8 UTF-8" >> /etc/default/libc-locales
xbps-reconfigure -f glibc-locales

Use whichever language code you want your system to use, e.g. for Japanese you'd use ja_JP.

19. Add rd.auto=1 to the GRUB_CMDLINE_LINUX_DEFAULT variable in /etc/default/grub. That means the line foes from looking like this:

GRUB_CMDLINE_LINUX_DEFAULT="loglevel=4 slub_debug=P page_poison=1"

to this:

GRUB_CMDLINE_LINUX_DEFAULT="loglevel=4 slub_debug=P page_poison=1 rd.auto=1"

This enables auto-assembly of special devices.

20. (optional) If you want to use a different keyboard layout (e.g. Dvorak) to enter your LUKS passphrase, also add rd.vconsole.keymap=dvorak to the same variable.

21. Now we need to use xbps-reconfigure to force dracut and grub to update, which means we'll need to know which linux package we have installed. Navigate to the /var/db/xbps directory, then run:

cat <plist-file> | grep key | grep linux

(where <plist-file> is the name of the .plist file you find in that directory) and you should get some output that looks like this:

<key>linux</key>
<key>linux-firmware-amd</key>
<key>linux-firmware-intel</key>
<key>linux-firmware-network</key>
<key>linux-firmware-nvidia</key>
<key>linux4.19</key>
<key>util-linux</key>

We're interested in the one with the version number. This means we're using Linux 4.19, and so the command we now need to run is:

xbps-reconfigure -f linux4.19

Substitute the version that you're running.

22. Once that's done, run exit to exit the chroot environment, then reboot your box. Grub should prompt you for the decryption passphrase once it starts up, and once you enter it, everything should work as normal from there.

Adding Bcache between LUKS and LVM

If you have a slow and capacious HDD and a fast and small SSD, you might want to use the SSD as a cache for the HDD. It can be done with Bcache by adding several commands to the "Set up filesystems" part of the previous instruction. So let /dev/sda be the HDD and /dev/sdb be the SSD. As in the previous part, /dev/sda1 has a size of 1G and will be used as /boot, and /dev/sda2 contains the remaining free space.

Format /dev/sdb to have one partition: /dev/sdb1.

3a. Set up /boot on /dev/sda1 and LUKS on both drives:

mkfs.ext2 -L boot /dev/sda1
cryptsetup luksFormat /dev/sda2
cryptsetup luksOpen /dev/sda2 crypt-pool
cryptsetup luksFormat /dev/sdb1
cryptsetup luksOpen /dev/sdb1 cache-pool

3b. Download bcache-tools and set up Bcache:

xbps-install -S bcache-tools
make-bcache -B /dev/mapper/crypt-pool -C /dev/mapper/cache-pool

Here we state that bcache should use /dev/mapper/crypt-pool as a backing device and /dev/mapper/cache-pool as a cache device. This will create a /dev/bcache0 device, where you can install LVM.

3c. Finish setting up the filesystems

vgcreate pool /dev/bcache0
lvcreate --name root -L 20G pool
mkfs.ext4 -L root /dev/mapper/pool-root
mount /dev/mapper/pool-root /mnt
mkdir /mnt/{boot,dev,proc,sys}
mount /dev/sda1 /mnt/boot
mount --rbind /dev /mnt/dev
mount --rbind /proc /mnt/proc
mount --rbind /sys /mnt/sys

The rest of the installation repeats the previous part, except that while installing the Void, you should also add bcache-tools:

xbps-install -S -R https://alpha.de.repo.voidlinux.org/current -r /mnt base-system lvm2 cryptsetup grub-x86_64-efi efibootmgr bcache-tools

Installation using void-installer

Again, this section does not follow the best practices, such as writing over the drive with random data, but will provide a basic encrypted system. Everything will be encrypted except /boot.

Warning: Do not follow this guide to the letter if you have more than one drive or if you have any data you do not want to lose! This guide will destroy all data on /dev/sda!

1. Start by booting the live CD of your choice, then press CTRL+ALT+F1 and log in as root:

Username: root
Password: voidlinux

2. It's time to set up the disk. Remember, all data on the disk will be destroyed!

fdisk /dev/sda
o
n
Enter
Enter
Enter
+1G
n
Enter
Enter
Enter
Enter
a
1
p -- Confirm that you have two partitions. One 1G partition for /boot and the rest of the drive will be dedicated to LUKS.
w

3. Create and open the LUKS device:

cryptsetup luksFormat /dev/sda2 -- Time for that super secret password! Don't forget it, or you'll lose access to all of your data!
cryptsetup luksOpen /dev/sda2 crypt-pool

4. Create a volume group and add sub-volumes:

vgcreate pool /dev/mapper/crypt-pool
lvcreate --name root -L 20G pool -- Feel free to use more for root if needed.
lvcreate --name swap -L 16G pool -- Optional.  But shoot for double the ram if used.
lvcreate --name home -l 100%FREE pool -- Note the lowercase 'L'.  If a specific size is required, make it the same way we made the others.

5. Now let's make sure grub knows what's going on. Run vi /etc/default/grub and find this line:

GRUB_CMDLINE_LINUX_DEFAULT="loglevel=4"

And change it to:

GRUB_CMDLINE_LINUX_DEFAULT="loglevel=4 rd.auto=1 cryptdevice=/dev/sda2:crypt-pool root=/dev/mapper/pool-root"

6. Install Void like normal. Run void-installer and follow the steps with the following exceptions:

  • If networking fails to connect, there may be a simple conflict with whatever the live environment is running. It's typically safe to ignore and move on to the next step.
  • Skip the partitioning step.
  • On the filesystem step set sda1 to ext2 /boot and the rest should be obvious. Choose your favorite filesystem for / and /home, or just stick with the old stand by of ext4.
  • Set pool-root to /
  • Set pool-home to /home
  • Set swap to swap if applicable.

7. Go back to choose the install step. After installation, select "no" when it prompts to reboot.

8. From the shell, mount the necessary drives

mount /dev/mapper/pool-root /mnt
mount /dev/sda1 /mnt/boot
mount --rbind /dev /mnt/dev
mount --rbind /proc /mnt/proc
mount --rbind /sys /mnt/sys

9. Chroot to your new mount and setup dns

chroot /mnt /bin/bash
echo 'nameserver 8.8.8.8' > /etc/resolv.conf

10. Install necessary packages

xbps-install lvm2 cryptsetup

11. Configuration

xbps-reconfigure -f linux4.18 (replace 4.18 with current version of linux package)
grub-mkconfig -o /boot/grub/grub.cfg

12. Double check grub.cfg

To be safe, open /boot/grub/grub.cfg from your favorite editor, and make sure your changes from step 5 are there.

Reboot, and it should ask you for a password for "crypt-pool", and finish booting normally.

Unlock over ssh (optional)

In certain scenarios, you may wish to be able to unlock an encrypted system remotely. Before you decide to set this up, be sure to have assessed your threat model and taken the associated risks into account.

Since Void Linux uses dracut to build the initramfs, we can make use of dracut-crypt-ssh. This integrates the dropbear secure shell into the initramfs and provides commands to interact with the encrypted system.

IMPORTANT: Read the module documentation! Don't copy&paste what is presented here, as it is intended only as a get-to-know guide and is not considered safe!

Setup

1. First, we install the package:

xbps-install dracut-crypt-ssh

2. By definition, dracut needs to provide access to the network, so add the respective commands to the grub config file at /etc/default/grub (append to GRUB_CMDLINE_LINUX_DEFAULT)

rd.neednet=1 ip=dhcp  #provide early net access via DHCP

This can be good for testing, however it may not be very convenient. To set a static IP, use the command like this (detailed information can of course be found in dracut's network documentation):

rd.neednet=1 ip=11.12.13.14::11.12.13.1:255.255.255.0:Hostname:eth0:off  #set IP manually

3. To be able to log in to the post-boot/pre-decrypted machine, we need to provide our public ssh-key to dropbear, so it recognizes us. You can ssh-copy-id your public ssh-key to the root account, but you may want to use an alternative key than your usual one and after testing you may want to customize dropbear's settings to not have that key in root's authorized_keys file. Once again: see dracut-crypt-ssh documentation! Be warned that dropbear does not support ed25519 keys.

4. Right now the new module is not included in your current initramfs, so we need to rebuild it:

xbps-reconfigure -f linux<KernelVersion>

5. Watch out for dracut-crypt specific output and fix the issues (missing ssh key, for example).

6. Finally, reboot to test. Make sure you can access the machine by other means in case it fails, otherwise you will remain locked out.

Dropbear's port defaults to 222:

ssh -p 222 root@<ip>

To see what is going on on the console:

console_peek

To enter the LUKS passphrase:

console_auth

Voila!

Last notes

  • Be sure to read the documentation for dracut-crypt-ssh.
  • Think about the pros and cons for your specific use case! Remember that the LUKS key can be read/intercepted by anyone who has physical access to the machine, without you noticing it.
  • You can integrate the setup directly into the installation process (if you install headless, for example), but make sure you got the IP assignment with ip=... correctly before you lock yourself out.