Install LVM LUKS
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
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
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
.
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
toext2 /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
toswap
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.
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.