Alpine Linux Installation with LUKS2
This is a guide for installing Alpine Linux Edge with full disk encryption using LUKS2, GPT partitions (with legacy boot) and BTRFS.
Steps
- Fetch an ISO for the latest release from AlpineLinux.org
- An alternative would be creating your own ISO using
the
alpine-edgeprofile of alpine-conf
- An alternative would be creating your own ISO using
the
- Boot Alpine Linux and as root with the password ‘root’
- Configure your installation environment.
- Upgrade all installed packages to version form Edge.
- Configure the package manager and upgrade packages to Edge
- Partition the disk.
- Create a LUKS2 container.
- Create the file systems.
- Install and configure Alpine.
Installation environment configuration
- Optionally setup a different keymap using
setup-keymap - Set a hostname using
setup-hostname - Configure network interfaces using
setup-interfaces - Up your configured network interfaces using
ifup
Upgrade to Edge
In order to upgrade to Alpine Linux Edge we first of all need to configure Alpine’s package manager APK:
- Choose a mirror using
setup-apkrepos - Select the Edge repositories in
/etc/apk/repositories:- Only select the Edge version of the community, main and testing repostories, disable all other repositories.
Now we can upgrade all installed packages using apk upgrade -U -a.
Keep in mind that this won’t properly upgrade the Linux kernel since
this would require a reboot. If you (for some reasons) need a newer
version of the Kernel than the one available in the current release to
install Alpine Linux on your hardware you need to create a custom
ISO.
Partitioning the disk
In order to partition the disk we need a tool which allows us to create
these partitions. You might use busybox fdisk to create MBR partitions
but I personally prefer gptfdisk for creating GPT partitions, it can
be installed using: apk add gptfdisk.
After you picked your partition tool you need to determine the device
path of the disk you want to partition. This can be done using fdisk -l | grep ^Disk:.
Now we can create our partition in this guide the following partitions will be created:
- A partition with the size 512M for an unencrypted
/boot - A swap partition with the size 8G for an encrypted swap.
- A partition for LUKS using all remaining available space.
The following commands are performed to create these partitions:
# gdisk /dev/sda
GPT fdisk (gdisk) version 1.0.3
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Command (? for help): n
Partition number (1-128, default 1): 1
Last sector (2048-3907029134, default = 3907029134) or {+-}size{KMGTP}: +512M
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300):
Changed type of partition to 'Linux filesystem'
Command (? for help): n
First sector (34-3907029134, default = 1050624) or {+-}size{KMGTP}:
Last sector (1050624-3907029134, default = 3907029134) or {+-}size{KMGTP}: +8G
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 8309
Changed type of partition to 'Linux LUKS'
Command (? for help): n
Partition number (3-128, default 3):
First sector (34-3907029134, default = 17827840) or {+-}size{KMGTP}:
Last sector (17827840-3907029134, default = 3907029134) or {+-}size{KMGTP}:
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 8309
Changed type of partition to 'Linux LUKS'
After creating these partition we also need to set the ‘legacy BIOS
bootable’ flag on our /boot partition. This can be done with gdisk
using the following commands:
Command (? for help): x
Expert command (? for help): a
Partition number (1-3): 1
Known attributes are:
0: system partition
1: hide from EFI
2: legacy BIOS bootable
60: read-only
62: hidden
63: do not automount
Attribute value is 0000000000000000. Set fields are:
No fields set
Toggle which attribute field (0-63, 64 or <Enter> to exit):
Have enabled the 'legacy BIOS bootable' attribute.
Attribute value is 0000000000000004. Set fields are:
2 (legacy BIOS bootable)
After invoking these command partitions your partition table should roughly look like this:
Number Start (sector) End (sector) Size Code Name
1 2048 1050623 512.0 MiB 8300 Linux filesystem
2 1050624 17827839 8.0 GiB 8309 Linux LUKS
3 17827840 3907029134 1.8 TiB 8309 Linux LUKS
If that’s the case write your GPT partition table to the disk and quit your Partitioning tool.
Create a LUKS2 container
In order to create a LUKS2 container the cryptsetup utility needs to
be installed, this can be done using: apk add cryptsetup. With this
utility we can now create a LUKS2 container on our third partition
using the following commands:
# cryptsetup luksFormat --type luks2 /dev/sda3
WARNING!
========
This will overwrite data on /dev/sda3 irrevocably.
Are you sure? (Type uppercase yes): YES
Enter passphrase for /dev/sda3:
Verify passphrase:
WARNING: Locking directory /run/cryptsetup is missing!
You can ignore the warning, cryptsetup will create this directory for us
if it doesn’t exist yet. After creating the LUKS2 container it needs to
be opened using: cryptsetup open --type luks2 /dev/sda3 root.
File system creation
Next up we need to create some file system. We are going to be using
ext2 for our /boot partition and Btrfs for our root file system. In
order to create these file systems two additional tools need to be
installed using: apk add e2fsprogs btrfs-progs.
The file system can then be created using the following commands:
# mkfs.ext2 /dev/sda1
mke2fs 1.43.8 (1-Jan-2018)
Creating filesystem with 131072 4k blocks and 32768 inodes
Filesystem UUID: f9b1fbe3-e86e-44f2-ad9e-271a70d0e7ff
Superblock backups stored on blocks:
32768, 98304
Allocating group tables: done
Writing inode tables: done
Writing superblocks and filesystem accounting information: done
# mkfs.btrfs /dev/mapper/root
btrfs-progs v4.14
See http://btrfs.wiki.kernel.org for more information.
Label: (null)
UUID: b0a71438-b36a-489e-84fd-d126748b67e2
Node size: 16384
Sector size: 4096
Filesystem size: 1.81TiB
Block group profiles:
Data: single 8.00MiB
Metadata: DUP 1.00GiB
System: DUP 8.00MiB
SSD detected: no
Incompat features: extref, skinny-metadata
Number of devices: 1
Devices:
ID SIZE PATH
1 1.81TiB /dev/mapper/root
Mounting the file systems
The file system need to be mounted at a mountpoint, where are going to
use /mnt for that. To mount the ext2 and btrfs file systems invoke the
following commands:
# mount -t btrfs /dev/mapper/root /mnt/
# mkdir /mnt/boot
# mount -t ext2 /dev/sda1 /mnt/boot
Additionally I always like to create various subvolumes when using Btrfs. Normally I create the following subvolumes:
# btrfs subvolume create /mnt/home
Create subvolume '/mnt/home'
# btrfs subvolume create /mnt/var
Create subvolume '/mnt/var'
# btrfs subvolume create /mnt/var/log
Create subvolume '/mnt/var/log'
# btrfs subvolume create /mnt/var/tmp
Create subvolume '/mnt/var/tmp'
Install and configure Alpine
Now Alpine needs to be installed on the given mountpoint. The basic installation can be done using:
# BOOTLOADER=syslinux setup-disk -m sys /mnt/
Depending on the quality and speed of your internet connection this might take a while. The script will emit a warning in this step that the MBR needs to be fixed manually, we will do this later on.
After Alpine has been installed on the mountpoint we need to make sure
that initramfs and bootloader are configured correctly. Otherwise the
system will not boot properly. I also highly recommend editing
/mnt/etc/fstab at this point and including appropriate mount options.
The initramfs needs to be configured in order to include the files
and kernel modules required by the cryptsetup utility to decrypt our
LUKS2 container. Since our root filesystem uses Btrfs we also need the
appropriate Kernel modules to mount it from the initramfs. Therefore the
configuration file /mnt/etc/mkinitfs/mkinitfs.conf should roughly look
like this:
features="ata base scsi usb btrfs cryptsetup"
In addition to that we need to tell the initramfs which devices contains
the LUKS2 container. This is done using a kernel parameter. In order to
modify the kernel parameters we need to edit the bootloader
configuration. This can be done by editing
/mnt/etc/update-extlinux.conf. The default_kernel_opts variable in
that file should contain the following items:
default_kernel_opts="cryptroot=/dev/sda3 cryptdm=root"
Next up we need to rebuild the initramfs and bootloader configurations this can be done with the following commands:
# mkinitfs -c /mnt/etc/mkinitfs/mkinitfs.conf -b /mnt/ $(ls -1 /mnt/lib/modules/)
==> initramfs: creating /mnt/boot/initramfs-hardened
# chroot /mnt/ update-extlinux -v 2>/dev/null
Updating extlinux configuration.
Found kernel: /boot/vmlinuz-hardened
Found initramfs: /boot/initramfs-hardened
1 entries found.
Installing libutil.c32 libcom32.c32 mboot.c32 menu.c32 vesamenu.c32 to /boot.
The (almost) final step is writing the MBR mentioned early. This can be
done using dd(1):
# dd bs=440 conv=notrunc count=1 if=/mnt/usr/share/syslinux/gptmbr.bin of=/dev/sda
1+0 records in
1+0 records out
Finally the last steps are setting a root password, unmounting the file system and rebooting your computer. Those steps can be performed with the following commands:
# chroot /mnt passwd root
Changing password for root
New password:
Retype password:
passwd: password for root changed by root
# umount /mnt/boot/ /mnt/
# cryptsetup luksClose /dev/mapper/root
# reboot