Alpine Linux: Setup with full-disk encryption

Posted on December 12, 2020


In this tutorial we'll be installing Alpine Linux with full-disk encryption.


Download


First, you'll need to download Alpine Linux and create bootable media.


Alpine Linux downloads


sha256sum -c alpine.iso.sha256
dd if=alpine.iso of=/dev/sdx # sdx is the bootable media device

Setup


Boot from the bootable media. Login as the user 'root' and run the setup script.


setup-alpine

When prompted for a disk to use, choose 'none'. We'll be setting up disks manually.


Disks


This tutorial will use the device /dev/nvme0n1, which is an NVME device.


We will use fdisk to partition the disk.


fdisk /dev/nvme0n1

Type m to see the available commands.


We need to create two partitions:


- The boot partition, 100MiB in size.

- The root partition, taking up the remainder of available space.


Type o to create a new DOS partition table.


For the boot partition, type n to create a new partition, choose p for primary partition and 1 for the partition number, leave the first sector as is, and choose +100M for the last sector.


Type a and choose partion number 1 to make the boot partition bootable.


For the root partition, type n to create a new partition, choose p for primary partition and 2 for the partition number, leave the first sector as is, and leave the last sector as is. The root partition should take up the remainder of the available disk space.


Type p to verify that you made the correct changes.

Type w to write the changes to disk and exit.


We will only be encrypting the root partition. The boot partition must be unencrypted so that we can boot from it.


First install the required packages.


apk add cryptsetup e2fsprogs

Now create the boot partition filesystem.


If using BIOS:


mkfs.ext4 /dev/nvme0n1p1

If using UEFI:


mkfs.vfat /dev/nvme0n1p1

Now encrypt the root partition.


cryptsetup luksFormat /dev/nvme0n1p2

This will encrypt the second partition of the NVME device. It will prompt you for a password to use.


Tip: to view long help messages, pipe the output into less:


cryptsetup --help | less

Now open the parition and give it to a memorable name:


cryptsetup open /dev/nvme0n1p2 cryptroot

The encrypted device will now be available as /dev/mapper/cryptroot.


Now make an ext4 filesystem on the root partition.


mkfs.ext4 /dev/mapper/cryptroot

Installation


First, install the required packages:


apk add syslinux

Mount the encrypted root on /mnt.


mount /dev/mapper/cryptroot /mnt

Mount the boot partition.


mkdir /mnt/boot
mount /dev/nvme0n1p1 /mnt/boot

Install Alpine Linux to disk.


setup-disk /mnt

Create the file /mnt/etc/crypttab and map the device to the name 'cryptroot'.


cryptroot UUID=<UUID> none luks

Tip: you can store the UUID with:


blkid -s UUID -o value /dev/sda2 > uuid

And load it from within vi with:


:r uuid

Edit /mnt/etc/update-extlinux.conf.

Change the value of 'root' to /dev/mapper/cryptroot.

Specify the cryptroot and cryptdm options. In cryptroot, specify the UUID of the device root. In cryptdm, specify the name we mapped the device to, which was cryptroot.


While you are at it you can remove 'nomodeset' from default_kernel_opts if you want to enable graphics later on.


# ...
default_kernel_opts="quiet rootfstype=ext4 cryptroot=UUID=<UUID> cryptdm=cryptroot"
root=/dev/mapper/cryptroot

Chroot into the root filesystem and run update-extlinux.


chroot /mnt
update-extlinux
exit

Modify the mkinitfs.conf file and add the following features.

kms is for Kernel Mode Setting, which is needed for graphics to work properly later on.

nvme is required to allow booting from an NVME device.

cryptsetup is required to boot from an encrypted partition.


features="... kms nvme cryptsetup"

Now rebuild the initramfs.


mkinitfs -c /mnt/etc/mkinitfs/mkinitfs.conf -b /mnt $(ls /mnt/lib/modules)

We are almost done. Just a few more steps to make things bootable.


If we were booting using BIOS and MBR, only one more step would be needed, which would be to write the master boot record:


dd if=/usr/share/syslinux/mbr.bin of=/dev/nvme0n1

Unfortunately with UEFI things are slightly more complicated.


Make a 'syslinux' directory in the boot partition.

Copy syslinux files to the syslinux directory.


mkdir /mnt/boot/syslinux
cp /usr/share/syslinux/efi64/* /mnt/boot/syslinux/

Copy extlinux.conf to the syslinux directory.


cp /mnt/boot/extlinux.conf /mnt/boot/syslinux/syslinux.cfg

Edit the syslinux.cfg file and prepend vmlinuz-lts and initramfs-lts with a forward slash.

You'll have to do this every time update-extlinux is run.


Now add an entry to your UEFI boot system.


apk add efibootmgr
efibootmgr --create --disk /dev/nvme0n1 --part 1 --loader "/syslinux/syslinux.efi" --label "Linux" --edd 3
# Shorter version:
efibootmgr -c -d /dev/nvme0n1 -p 1 -l "/syslinux/syslinux.efi" -L "Linux" -e 3

We specify --edd 3 because efibootmgr sometimes fails to detect EDD 3.0.


Unmount all filesystems and reboot from hard disk.

If everything worked properly, then you should be prompted for your password to unlock the root filesystem.


umount /mnt/boot
umount /mnt
reboot

And now you have successfully installed Alpine Linux.


Troubleshooting


Should anything go wrong, you can boot from the bootable media and remount the filesystems.


apk add cryptsetup
cryptsetup open /dev/nvme0n1p2 cryptroot
mount /dev/mapper/cryptroot /mnt
mount /dev/nvme0n1p1 /mnt/boot

---

This work is licensed under a CC-BY-SA-4.0 license.

Source code


Have a comment on one of my posts?

Send an email