LVM on LUKS: Difference between revisions
(Added instructions for keeping the user's preferred keyboard mapping during the boot password prompt.) |
PureTryOut (talk | contribs) (Add separate bootloader section and grub-efi) |
||
Line 55: | Line 55: | ||
* Install the following packages required to set up LVM and LUKS: | * Install the following packages required to set up LVM and LUKS: | ||
# apk add | # apk add lvm2 cryptsetup e2fsprogs | ||
* Optionally, install and start the <code>haveged</code> service for unpredictable random numbers used for encryption: | |||
# apk add haveged | |||
# rc-service haveged start | # rc-service haveged start | ||
Line 155: | Line 154: | ||
# mkswap /dev/vg0/swap | # mkswap /dev/vg0/swap | ||
Line 169: | Line 164: | ||
# mount -t ext4 /dev/vg0/root /mnt/ | # mount -t ext4 /dev/vg0/root /mnt/ | ||
: If you created further partitions or LVs, create the mount points within the <code>/mnt/</code> directory and mount the devices. | : If you created further partitions or LVs, create the mount points within the <code>/mnt/</code> directory and mount the devices. | ||
Line 209: | Line 199: | ||
: The command uses the settings from the <code>mkinitfs.conf</code> file set in the <code>-c</code> parameter to generate the RAM disk. The command is executed in the <code>/mnt/</code> directory and the RAM disk is generated using the modules for the installed kernel. Without setting the kernel version using the <code>$(ls /mnt/lib/modules/</code>) option, <code>mkinitfs</code> tries to generate the RAM disk using the kernel version installed in the temporary environment, which can differ from the latest one installed by the <code>setup-disk</code> utility. | : The command uses the settings from the <code>mkinitfs.conf</code> file set in the <code>-c</code> parameter to generate the RAM disk. The command is executed in the <code>/mnt/</code> directory and the RAM disk is generated using the modules for the installed kernel. Without setting the kernel version using the <code>$(ls /mnt/lib/modules/</code>) option, <code>mkinitfs</code> tries to generate the RAM disk using the kernel version installed in the temporary environment, which can differ from the latest one installed by the <code>setup-disk</code> utility. | ||
== Installing a bootloader == | |||
=== Syslinux === | |||
Format the <code>/dev/vda1</code> device for the <code>/boot/</code> partition using the ext4 file system: | |||
<pre># mkfs.ext4 /dev/vda1</pre> | |||
Create <code>/mnt/boot/</code> directory and mount the <code>/dev/vda1</code> partition in this directory: | |||
<pre> | |||
# mkdir /mnt/boot/ | |||
# mount -t ext4 /dev/vda1 /mnt/boot/ | |||
</pre> | |||
Install the Syslinux package: | |||
<pre># apk add syslinux</pre> | |||
Edit the <code>/mnt/etc/update-extlinux.conf</code> file and append the following kernel options to the <code>default_kernel_opts</code> parameter: | |||
<pre>default_kernel_opts="... <u>cryptroot=/dev/vda2 cryptdm=lvmcrypt</u>"</pre> | |||
: The <code>cryptroot</code> parameter sets the name of the device that contains the root file system. The <code>cryptdm</code> parameter sets the name of the mapping previously set in the <code>crypttab</code> file. | : The <code>cryptroot</code> parameter sets the name of the device that contains the root file system. The <code>cryptdm</code> parameter sets the name of the mapping previously set in the <code>crypttab</code> file. | ||
Because the <code>update-extlinux</code> utility operators only on the <code>/boot/</code> directory, temporarily change the root to the <code>/mnt/</code> directory and update the boot loader configuration: | |||
<pre> | |||
# chroot /mnt/ | |||
# update-extlinux | |||
# exit | |||
</pre> | |||
: Ignore the errors the <code>update-extlinux</code> utility displays. | : Ignore the errors the <code>update-extlinux</code> utility displays. | ||
Write the MBR to the <code>/dev/vda</code> device: | |||
<pre># dd bs=440 count=1 conv=notrunc if=/mnt/usr/share/syslinux/mbr.bin of=/dev/vda</pre> | |||
=== Grub on EFI === | |||
Format the <code>/dev/vda1</code> device for the <code>/boot/</code> partition using the FAT32 file system: | |||
<pre> | |||
# apk add dosfstools | |||
# mkfs.fat -F32 /dev/vda1 | |||
</pre> | |||
Create <code>/mnt/boot/</code> directory and mount the <code>/dev/vda1</code> partition in this directory: | |||
<pre> | |||
# mkdir /mnt/boot/ | |||
# mount /dev/vda1 /mnt/boot/ | |||
</pre> | |||
Edit the <code>/mnt/etc/default/grub</code> file and add the following kernel options to the <code>GRUB_CMDLINE_LINUX_DEFAULT</code> parameter: | |||
<pre>cryptroot=/dev/vda2 cryptdm=lvmcrypt</pre> | |||
The <code>cryptroot</code> parameter sets the name of the device that contains the root file system. The <code>cryptdm</code> parameter sets the name of the mapping previously set in the <code>crypttab</code> file. | |||
Mount the required filesystems for the Grub EFI installer to the installation: | |||
<pre> | |||
# mount -t proc /proc /mnt/proc | |||
# mount --rbind /dev /mnt/dev | |||
# mount --make-rslave /mnt/dev | |||
</pre> | |||
Then chroot in and use <code>grub-install</code> to install Grub. | |||
<pre> | |||
# (chroot) chroot /mnt | |||
# (chroot) apk add grub grub-efi efibootmgr | |||
# (chroot) grub-install --target=x86_64-efi --efi-directory=/boot | |||
# (chroot) grub-mkconfig -o /boot/grub/grub.cfg | |||
# (chroot) exit | |||
</pre> | |||
== Unmounting the Volumes and Partitions == | == Unmounting the Volumes and Partitions == |
Revision as of 13:01, 26 June 2019
Introduction
This documentation describes how to set up Alpine Linux using a logical volume (LV), that is installed in an encrypted partition. To encrypt the partition the logical volume manager (LVM) the volume group (VG) is installed in, the Device Mapper crypt (dm-crypt) module and Linux Unified Key Setup (LUKS) is used.
Note that you must install the /boot/
directory on an unecrypted partition to boot correctly.
Hard Disk Device Name
The following documentation uses the vda
device as installation destination. If your environment uses a different device name for your hard disk, use the corresponding device names in the examples.
Setting up Alpine Linux Using LVM on Top of a LUKS Partition
To install Alpine Linux in logical volumes running on top of a LUKS encrypted partition, you cannot use the official installation procedure. The installation requires several manual steps you must run in the Alpine Linux Live CD environment.
Preparing the Temporary Installation Environment
Before you begin to install Alpine Linux, prepare the temporary environment:
- Boot the latest Alpine Linux Installation CD.
- At the login prompt, use the
root
user without password to log in.
- Optionally, set the keyboard language:
# setup-keymap
- The default keyboard mapping is
us-us
- Configure the network interface:
# setup-interfaces
- If you set a static IP address, additionally configure DNS be able to resolve host names:
# setup-dns
- Enable the network interface. For example:
# ifup eth0
- Set an apk repository and update the cache:
# setup-apkrepos # apk update
- Install the following packages required to set up LVM and LUKS:
# apk add lvm2 cryptsetup e2fsprogs
- Optionally, install and start the
haveged
service for unpredictable random numbers used for encryption:
# apk add haveged # rc-service haveged start
Creating the Partition Layout
Linux requires an unencrypted /boot/
partition to boot. You can assign the remaining space for the encrypted LVM physical volume (PV).
- Start the
fdisk
utility to set up partitions:
# fdisk /dev/vda
- Create the
/boot/
partition:
- Enter
n
→p
→1
→1
→+100m
to create a new 100 MB primary partition.
- Enter
- Create the
- Set the
/boot/
partition active:
- Enter
a
→1
.
- Enter
- Set the
- Create the LVM PV partition:
- Enter
n
→p
→2
to start creating the next partition. PressEnter
to select the default start cylinder. Enter the size of partition. For example,512m
for 512 MB or5g
for 5 GB. Alternatively pressEnter
to set the maximum available size.
- Enter
- Set the partition type for the LVM PV:
- Enter
t
→2
→8e
- Enter
- To verify the settings, press
p
. The output shows, for example:
- To verify the settings, press
Device Boot Start End Blocks Id System /dev/vda1 * 1 100 50368+ 83 Linux /dev/vda2 101 10402 5192208 8e Linux LVM
- Press
w
to save the changes.
- Optionally, wipe the LVM PV partition with random values:
# haveged -n 0 | dd of=/dev/vda2
- Depending on the size of the partition, this process can take several minutes to hours.
Encrypting the LVM Physical Volume Partition
- To encrypt the partition which will later contain the LVM PV:
# cryptsetup luksFormat /dev/vda2
- If you prefer setting an individual hashing algorithm and hashing schema:
- To run a benchmark:
# cryptsetup benchmark
- To encrypt the partition using individual settings, enter, for example:
# cryptsetup -v -c serpent-xts-plain64 -s 512 --hash whirlpool --iter-time 5000 --use-random luksFormat /dev/vda2
Creating the Logical Volumes and File Systems
- Open the LUKS partition:
# cryptsetup open --type luks /dev/vda2 lvmcrypt
- Create the PV on
/dev/vda
:
# pvcreate /dev/mapper/lvmcrypt
- Create the
vg0
LVM VG in the/dev/mapper/lvmcrypt
PV:
# vgcreate vg0 /dev/mapper/lvmcrypt
- Create the LVs:
- In the following you will create a LV for the root partition. However, you can use the same command with a different LV name to create further LVs for other mount points you want to create.
- To create a 2 GB LV named
root
in thevg0
VG:
- To create a 2 GB LV named
# lvcreate -L 2G vg0 -n root
- Create a 512 MB swap LV:
# lvcreate -L 512M vg0 -n swap
- The LVs created in the previous steps are automatically marked active. To verify, enter:
# lvscan
- Format the
root
LV using the ext4 file system:
# mkfs.ext4 /dev/vg0/root
- If you created further LVs in the previous step, create the file systems on them using the same command with the path to the LV.
- Format the swap LV:
# mkswap /dev/vg0/swap
Mounting the File Systems
Before you can install Alpine Linux, you must mount the partitions and LVs:
- Mount the root LV to the
/mnt/
directory:
# mount -t ext4 /dev/vg0/root /mnt/
- If you created further partitions or LVs, create the mount points within the
/mnt/
directory and mount the devices.
Installing Alpine Linux
In this step you will install Alpine Linux in the /mnt/
directory, which contains the mounted file system structure:
- Install Alpine Linux:
# setup-disk -m sys /mnt/
- The installer downloads the latest packages to install the base installation. Additionally, the installer automatically creates the entries for the mount points in the
fstab
file, which are currently mounted in the/mnt/
directory.
- Note: The automatic writing of the master boot record (MBR) fails in this step. You will write the MBR later manually to the disk.
- To enable the operating system to decrypt the PV at boot time, create the
/mnt/etc/crypttab
file. Enter the following line into the file to decrypt the/dev/vda2
partition using theluks
module and map it to thelvmcrypt
name:
lvmcrypt /dev/vda2 none luks
- The swap LV is not automatically added to the
fstab
file. To add it manually, add the following line to the/mnt/etc/fstab
file:
/dev/vg0/swap swap swap defaults 0 0
- Edit the
/mnt/etc/mkinitfs/mkinitfs.conf
file and append thecryptsetup
module to thefeatures
parameter:
features="ata base ide scsi usb virtio ext4 lvm cryptsetup"
- Note: Alpine Linux uses the
en-us
keyboard mapping by default when prompting for the password to decrypt the partition at boot time. If you changed the keyboard mapping in the temporary environment and want to use it at the boot password prompt, be sure to also add thekeymap
feature to the list above.
- Rebuild the initial RAM disk:
# mkinitfs -c /mnt/etc/mkinitfs/mkinitfs.conf -b /mnt/ $(ls /mnt/lib/modules/)
- The command uses the settings from the
mkinitfs.conf
file set in the -c
parameter to generate the RAM disk. The command is executed in the /mnt/
directory and the RAM disk is generated using the modules for the installed kernel. Without setting the kernel version using the $(ls /mnt/lib/modules/
) option, mkinitfs
tries to generate the RAM disk using the kernel version installed in the temporary environment, which can differ from the latest one installed by the setup-disk
utility.
Installing a bootloader
Syslinux
Format the /dev/vda1
device for the /boot/
partition using the ext4 file system:
# mkfs.ext4 /dev/vda1
Create /mnt/boot/
directory and mount the /dev/vda1
partition in this directory:
# mkdir /mnt/boot/
# mount -t ext4 /dev/vda1 /mnt/boot/
Install the Syslinux package:
# apk add syslinux
Edit the /mnt/etc/update-extlinux.conf
file and append the following kernel options to the default_kernel_opts
parameter:
default_kernel_opts="... <u>cryptroot=/dev/vda2 cryptdm=lvmcrypt</u>"
- The
cryptroot
parameter sets the name of the device that contains the root file system. The cryptdm
parameter sets the name of the mapping previously set in the crypttab
file.
Because the update-extlinux
utility operators only on the /boot/
directory, temporarily change the root to the /mnt/
directory and update the boot loader configuration:
# chroot /mnt/
# update-extlinux
# exit
- Ignore the errors the
update-extlinux
utility displays.
Write the MBR to the /dev/vda
device:
# dd bs=440 count=1 conv=notrunc if=/mnt/usr/share/syslinux/mbr.bin of=/dev/vda
Grub on EFI
Format the /dev/vda1
device for the /boot/
partition using the FAT32 file system:
# apk add dosfstools
# mkfs.fat -F32 /dev/vda1
Create /mnt/boot/
directory and mount the /dev/vda1
partition in this directory:
# mkdir /mnt/boot/
# mount /dev/vda1 /mnt/boot/
Edit the /mnt/etc/default/grub
file and add the following kernel options to the GRUB_CMDLINE_LINUX_DEFAULT
parameter:
cryptroot=/dev/vda2 cryptdm=lvmcrypt
The cryptroot
parameter sets the name of the device that contains the root file system. The cryptdm
parameter sets the name of the mapping previously set in the crypttab
file.
Mount the required filesystems for the Grub EFI installer to the installation:
# mount -t proc /proc /mnt/proc
# mount --rbind /dev /mnt/dev
# mount --make-rslave /mnt/dev
Then chroot in and use grub-install
to install Grub.
# (chroot) chroot /mnt
# (chroot) apk add grub grub-efi efibootmgr
# (chroot) grub-install --target=x86_64-efi --efi-directory=/boot
# (chroot) grub-mkconfig -o /boot/grub/grub.cfg
# (chroot) exit
Unmounting the Volumes and Partitions
- Umount
/mnt/boot/
and /mnt/
:
# umount /mnt/boot/
# umount /mnt/
- Note: If you mounted further partitions or LVs below
/mnt/
, you must first unmount all of them before you can unmount /mnt/
.
- Disable the swap partition:
# swapoff -a
- Deactivate the VG:
# vgchange -a n
- Close the
lvmcrypt
device:
# cryptsetup luksClose lvmcrypt
- Reboot the system:
# reboot
Troubleshooting
General Procedure
In case your system fails to boot, you can verify the settings and fix incorrect configurations:
- Activate the VGs:
# vgchange -a y
- Verify that you run the steps described in the Installing Alpine Linux section correctly. Update the configuration if necessary.
Hardening
- To harden, you should disable DMA[1] and install a hardened version of AES (TRESOR[2] or Loop-Amnesia[3]) since by default cryptsetup with luks uses AES by default.
- Disable DMA in the BIOS and set the password for the BIOS according to Wikipedia.[4]
- Blacklist kernel modules that use DMA and any unused expansion modules (FireWire, CardBus, ExpressCard, Thunderbolt, USB 3.0, PCI Express and hotplug modules) that use DMA.