Full disk encryption secure boot: Difference between revisions

From Alpine Linux
m (Format)
 
(51 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{Draft}}
'''Disclaimer : this is not to be followed, only for testing purposes. This will be updated when GRUB 2.12 rc1 will be available for LUKSv2, GRUB and FDE to work'''


This guide is to explain step by step how to setup Alpine Linux with Full Disk Encryption using LUKS2, /boot & / together on the same partition, encrypted swap for hibernation on a nvme drive, with UEFI & Secure Boot.
This guide is to explain, step-by-step, how to setup Alpine Linux with Full Disk Encryption using LUKS2, LVM (one Physical Volume Partition with three Logical Volume Partitions (/ /boot & swap) with hibernation on a NVMe drive, with UEFI & Secure Boot. This guide has been written using Alpine Linux Std 3.16.1, please adapt some commands if needed.
The goal of this guide is to follow the KISS principle, lvm can be added, another file system can be used, multiple partitions for /home; /var/log etc.. can also be added, if running everything in one partition is not meeting your requirements.


= Sequence of Events =
The goal of this guide is to follow the KISS principle, but another file system can be used, multiple partitions for /home; /var/log etc.. can also be added, if the proposed configuration is not meeting your requirements.
 
* Installing packages
* Partitioning the disk
* Configuring LUKS
* Mounting points and File System
* Installing Alpine
* mkinitfs settings & modules
* Grub settings
* Configuring Secure Boot


= Installing packages =
= Installing packages =
Line 22: Line 12:
For encryption, we will use cryptsetup :
For encryption, we will use cryptsetup :
<pre># apk add cryptsetup</pre>
<pre># apk add cryptsetup</pre>
For LVM:
<pre># apk add lvm2</pre>


For using and managing UEFI, multiple packages are needed :
For using and managing UEFI, multiple packages are needed :
<pre># apk add efibootmgr e2fsprogs grub grub-efi</pre>
<pre># apk add efibootmgr e2fsprogs grub grub-efi</pre>
= Preparing / overwriting the disk =
<pre># apk add haveged</pre>
This can take long, on my side for a 500GB nVME it tooks ~30 minutes.
<pre># haveged -n 0 | dd of=/dev/nvme0n1</pre>


= Partitioning the disk =
= Partitioning the disk =


Let's assume the disk is /dev/nvme0n1 and no partition is present, we will create three partitions :
Let's assume the disk is /dev/nvme0n1 and no partition is present, we will create two partitions :
   
   
* one for UEFI
* one for UEFI
* one for /
* one for LVM
* one for swap (hibernation)


<pre># gdisk /dev/nvme0n1
<pre> # gdisk /dev/nvme0n1
GPT fdisk (gdisk) version 1.0.9.1
GPT fdisk (gdisk) version 1.0.9.1


Partition table scan:
Partition table scan:
   MBR: protective
   MBR: not present
   BSD: not present
   BSD: not present
   APM: not present
   APM: not present
   GPT: present
   GPT: not present


Found valid GPT with protective MBR; using GPT.
Creating new GPT entries in memory.
 
Command (? for help): d
No partitions


Command (? for help): n
Command (? for help): n
Partition number (1-128, default 1):  
Partition number (1-128, default 1):  
First sector (2048-1000215182, default = 2048) or {+-}size{KMGTP}:  
First sector (34-1000215182, default = 2048) or {+-}size{KMGTP}:  
Last sector (2048-1000215182, default = 1000214527) or {+-}size{KMGTP}: 512M
Last sector (2048-1000215182, default = 1000214527) or {+-}size{KMGTP}: 512M
Current type is 8300 (Linux filesystem)
Current type is 8300 (Linux filesystem)
Line 58: Line 52:
Command (? for help): n
Command (? for help): n
Partition number (2-128, default 2):  
Partition number (2-128, default 2):  
First sector (1048577-1000215182, default = 1050624) or {+-}size{KMGTP}:  
First sector (34-1000215182, default = 1050624) or {+-}size{KMGTP}:  
Last sector (1050624-1000215182, default = 1000214527) or {+-}size{KMGTP}: 16G
Last sector (1050624-1000215182, default = 1000214527) or {+-}size{KMGTP}:  
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): 8200
Changed type of partition to 'Linux swap'
 
Command (? for help): n
Partition number (3-128, default 3):
First sector (1048577-1000215182, default = 33556480) or {+-}size{KMGTP}:
Last sector (33556480-1000215182, default = 1000214527) or {+-}size{KMGTP}:  
Current type is 8300 (Linux filesystem)
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): 8309
Hex code or GUID (L to show codes, Enter = 8300): 8309
Line 81: Line 67:
The operation has completed successfully.
The operation has completed successfully.
</pre>
</pre>
Populate /dev with the new partitions
<pre> # partprobe /dev/nvme0n1</pre>


= Configuring LUKS =
= Configuring LUKS =


<pre># cryptsetup -v -c aes-xts-plain64 -s 512 --hash sha512 --pbkdf pbkdf2 --iter-time 5000 --use-random luksFormat /dev/nvme0n1p2
Using luks2 (unsupported by GRUB at the moment):
<pre># cryptsetup -v -c aes-xts-plain64 -s 512 --hash sha512 --pbkdf pbkdf2 --iter-time 1000 --use-random luksFormat /dev/nvme0n1p2</pre>
Using luks1:
<pre># cryptsetup -v -c aes-xts-plain64 -s 512 --hash sha512 --iter-time 1000 --use-urandom --type luks1 luksFormat /dev/nvme0n1p2</pre>


<pre>
WARNING!
WARNING!
========
========
Line 96: Line 89:
Command successful.
Command successful.


cryptsetup -v -c aes-xts-plain64 -s 512 --hash sha512 --pbkdf pbkdf2 --iter-time 5000 --use-random luksFormat /dev/nvme0n1p3
# cryptsetup luksOpen /dev/nvme0n1p2 lvmcrypt
</pre>


WARNING!
= LVM : Physical & Logical Volumes creation =
========
<pre># pvcreate /dev/mapper/lvmcrypt
This will overwrite data on /dev/nvme0n1p3 irrevocably.
  Physical volume "/dev/mapper/lvmcrypt" successfully created.
# vgcreate vg0 /dev/mapper/lvmcrypt
  Volume group "vg0" successfully created
# lvcreate -L 20G vg0 -n swap (I have a 16GB RAM laptop)
  Logical volume "swap" created.
# lvcreate -l 100%FREE vg0 -n root
  Logical volume "root" created.
</pre>


Are you sure? (Type 'yes' in capital letters): YES
To check the creation :
Enter passphrase for /dev/nvme0n1p3:
<pre># lvscan
Verify passphrase:
  ACTIVE            '/dev/vg0/swap' [20.00 GiB] inherit
Key slot 0 created.
  ACTIVE            '/dev/vg0/root' [455.92 GiB] inherit
Command successful.
</pre>
</pre>


= Mounting points and File System =
= Mounting points and File System =
Open the LUKS partitiond we just created:
<pre># cryptsetup luksOpen /dev/nvme0n1p2 nvme0n1p2-crypt
# cryptsetup luksOpen /dev/nvme0n1p3 nvme0n1p3-crypt
</pre>


Create vfat file system for UEFI partition:
Create vfat file system for UEFI partition:
Line 120: Line 115:


Create ext4 file system for / partition:
Create ext4 file system for / partition:
<pre># mkfs.ext4 /dev/mapper/nvme0n1p2-crypt</pre>
<pre># mkfs.ext4 /dev/vg0/root</pre>


Create ext4 file system for swap partition:
Activate SWAP:
<pre># mkfs.ext4 /dev/mapper/nvme0n1p3-crypt</pre>
<pre># mkswap /dev/vg0/swap
# swapon /dev/vg0/swap
</pre>


Create mounting points and mount partitions :
Mount / partition to /mnt :
Mount / partition to /mnt :
<pre># mount -t ext4 /dev/mapper/nvme0n1p2-crypt /mnt</pre>
<pre># mount -t ext4 /dev/vg0/root /mnt</pre>
 
Create /boot/efi:
Create /boot/efi:
<pre># mkdir /mnt/boot/efi -p</pre>
<pre># mkdir /mnt/boot/efi -p</pre>
Mount UEFI partition to /mnt/boot/efi :
Mount UEFI partition to /mnt/boot/efi :
<pre># mount -t vfat /dev/nvme0n1p1 /mnt/boot/efi</pre>
<pre># mount -t vfat /dev/nvme0n1p1 /mnt/boot/efi</pre>
Activate SWAP:
 
<pre># mkswap /dev/mapper/nvme0n1p3-crypt
# swapon /dev/mapper/nvme0n1p3-crypt</pre>
Check partition scheme:
Check partition scheme:
<pre># lsblk
<pre># lsblk
NAME                MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINTS
nvme0n1       259:0    0 476.9G  0 disk   
loop0                7:0    0 105.2M  1 loop  /.modloop
├─nvme0n1p1   259:1    0  511M  0 part  /mnt/boot/efi
sda                  8:0    1  7.6G  0 disk  /media/sda
└─nvme0n1p2    259:2    0 476.4G 0 part   
├─sda1                8:1    1  148M  0 part 
  └─lvmcrypt  253:0    0 476.4G 0 crypt  
└─sda2                8:2    1  1.4M  0 part 
    ├─vg0-swap 253:1   0   20G 0 lvm  [SWAP]
nvme0n1             259:0    0 476.9G  0 disk   
    └─vg0-root 253:2   0 456.4G 0 lvm  /mnt
├─nvme0n1p1         259:1    0  511M  0 part  /mnt/boot/efi
├─nvme0n1p2        259:2    0 15.5G 0 part   
│ └─nvme0n1p2-crypt 253:0    0 15.5G 0 crypt /mnt
└─nvme0n1p3        259:3   0 460.9G 0 part 
  └─nvme0n1p3-crypt 253:1   0 460.9G 0 crypt [SWAP]
</pre>
</pre>


= Installing Alpine =
= Installing Alpine =


<pre># setup-disk -m sys /mnt/
<pre># setup-disk -m sys /mnt/</pre>
MOUNTPOINT=/mnt setup-alpine
</pre>


= mkinitfs settings & modules =
= mkinitfs settings & modules =
Edit the /mnt/etc/mkinitfs/mkinitfs.conf file and append the cryptsetup module to the features parameter:
Edit the /mnt/etc/mkinitfs/mkinitfs.conf file and append the modules to the features parameters (keymap only needed if your keyboard is not QWERTY):
<pre> features="... cryptsetup"</pre>
<pre>features="ata base ide scsi usb virtio ext4 lvm nvme keymap cryptsetup cryptkey resume"</pre>
Regenerate the initram:
Regenerate the initram:
<pre># mkinitfs -c /mnt/etc/mkinitfs/mkinitfs.conf -b /mnt/ $(ls /mnt/lib/modules/)</pre>
<pre># mkinitfs -c /mnt/etc/mkinitfs/mkinitfs.conf -b /mnt/ $(ls /mnt/lib/modules/)</pre>
Line 165: Line 154:


Create a crypto_keyfile.bin to avoid typing the passphrase twice during the boot process (one for Grub partition, one for Alpine partition):
Create a crypto_keyfile.bin to avoid typing the passphrase twice during the boot process (one for Grub partition, one for Alpine partition):
<pre> # touch /mnt/crypto_keyfile.bin
<pre># touch /mnt/crypto_keyfile.bin
# chmod 600 /mnt/crypto_keyfile.bin
# chmod 600 /mnt/crypto_keyfile.bin
# dd bs=512 count=4 if=/dev/urandom of=/mnt/crypto_keyfile.bin
# dd if=/dev/random bs=512 count=4 | xxd -p -c999 | tr -d '\n' > /mnt/crypto_keyfile.bin
# cryptsetup luksAddKey /dev/nvme0n1p2 /mnt/crypto_keyfile.bin
# cryptsetup luksAddKey /dev/nvme0n1p2 /mnt/crypto_keyfile.bin
</pre>
</pre>


Then, let's mount and chroot to our fresh installation:
Then, let's mount and chroot to our fresh installation:
<pre> # mount -t proc /proc /mnt/proc
<pre># mount -t proc /proc /mnt/proc
# mount --rbind /dev /mnt/dev
# mount --rbind /dev /mnt/dev
# mount --make-rslave /mnt/dev
# mount --make-rslave /mnt/dev
Line 178: Line 167:
# chroot /mnt
# chroot /mnt
</pre>
</pre>
Edit /etc/default/grub and add cryptkey after cryptdm=root parameter like this:
<pre>GRUB_TIMEOUT=2
GRUB_DISABLE_SUBMENU=y
GRUB_DISABLE_RECOVERY=true
GRUB_CMDLINE_LINUX_DEFAULT="modules=sd-mod,usb-storage,ext4,nvme cryptroot=UUID=XXXX cryptdm=lvmcrypt cryptkey quiet rootfstype=ext4"
</pre>
XXXX could be found with blkid command
Add a new GRUB_PRELOAD_MODULES line like this:
<pre>GRUB_PRELOAD_MODULES="luks cryptodisk part_gpt lvm"
</pre>
Finally, add the cryptodisk parameter :
<pre>GRUB_ENABLE_CRYPTODISK=y</pre>


Let's show the UUID of our partition scheme:
Let's show the UUID of our partition scheme:
<pre> # lsblk -f
<pre># lsblk -f</pre>
nvme0n1                                                                                                           
 
├─nvme0n1p1 vfat 62E0-E4C0 509.7M 0% /boot/efi
Create a /root/grub-pre.cfg and replace <XXXX-UUID_WITHOUT_HYPHENS> with your encrypted lvm partition UUID (here /dev/nvme0n1p2) without hyphens, replace <YYYY> with VG UUID from vgdisplay and replace <ZZZZ> with LV UUID from lvdisplay of your /dev/vg0/root
├─nvme0n1p2 crypto_LUKS 275836d9-05af-4e1a-bce5-335ef3bcd6e8               
<pre>
│ └─nvme0n1p2-crypt ext4 9bed7992-81cc-4126-8bbd-4e724dbb7bdd 13.9G    3% /
set crypto_uuid=<XXXX-UUID_WITHOUT_HYPHENS>
└─nvme0n1p3 crypto_LUKS 67eae09f-f533-4bfa-b874-e17016929138               
cryptomount -u $crypto_uuid
  └─nvme0n1p3-crypt swap fcb8594e-2409-4365-bf0b-0199c3acf1c6               
set root='lvmid/<YYYY>/<ZZZZ>'
set prefix=($root)/boot/grub
insmod normal
normal
</pre>
</pre>


Edit /etc/default/grub and add a new line starting with GRUB_CMDLINE_LINUX parameter, replacing <UUID> with the UUID of the encrypted partition (in this case /dev/nvme0n1p2):
= Configuring Secure Boot =
<pre> GRUB_CMDLINE_LINUX="cryptroot=/dev/nvme0n1p2:nvme0n1p2-crypt:allow-discards cryptkey"
<pre># apk add efi-mkkeys efibootmgr sbsigntool
GRUB_PRELOAD_MODULES="luks cryptodisk part_gpt"
# efi-mkkeys -s "Your Name" -o /etc/uefi-keys
GRUB_ENABLE_CRYPTODISK=y
</pre>
</pre>


Re-install Grub:
Re-install Grub:
<pre> # grub-install --target=x86_64-efi --efi-directory=/boot/efi
<pre># mkdir /boot/efi/EFI/AlpineLinuxSecureBoot
# grub-mkimage -p /boot/grub -O x86_64-efi -c /root/grub-pre.cfg -o /tmp/grubx64.efi luks2 part_gpt cryptodisk lvm ext2 gcry_rijndael pbkdf2 gcry_sha512
# install -v /tmp/grubx64.efi /boot/efi/EFI/AlpineLinuxSecureBoot/
# sed -i 's/SecureBoot/SecureB00t/' /boot/efi/EFI/AlpineLinuxSecureBoot/grubx64.efi
# cd /boot/efi/EFI/AlpineLinuxSecureBoot/
# sbsign --key /etc/uefi-keys/db.key --cert /etc/uefi-keys/db.crt --output grubx64.efi.signed grubx64.efi
# grub-mkconfig -o /boot/grub/grub.cfg
# grub-mkconfig -o /boot/grub/grub.cfg
# efibootmgr --disk /dev/nvme0n1p1 --part 1 --create --label 'Alpine Linux Secure Boot Signed' --load /EFI/AlpineLinuxSecureBoot/grubx64.efi.signed --verbose
</pre>
</pre>


= Configuring Secure Boot =
To check that your .efi is signed :
<pre> # sbverify --cert /etc/uefi-keys/db.crt /boot/efi/EFI/AlpineLinuxSecureBoot/grubx64.efi.signed
Signature verification OK
# sbverify --list /boot/efi/EFI/AlpineLinuxSecureBoot/grubx64.efi.signed
signature 1
image signature issuers:
- /CN="Your Name" (db)
image signature certificates:
- subject: /CN="Your Name" (db)
  issuer:  /CN="Your Name" (db)
</pre>
 
Copy db.auth, KEK.auth and PK.auth files from /etc/uefi-keys to a FAT formatted file system.
 
Reboot & enter into your UEFI (Fx key depending of your laptop)
 
== Import keys to UEFI ==
 
This is just an example from an XPS laptop, each UEFI is unique.
 
# Go to '''Boot Configuration''' > '''Secure Boot'''
# Change '''Enable Secure Boot''' to '''ON'''
# Change '''Secure Boot Mode''' to '''Deployed Mode'''
# Change '''Enable Custom Mode''' to '''ON'''
# Go to '''Custom Mode Key Management'''
#* '''Reset All Keys'''
#* '''Select Key Database''' select '''db''' > Replace from file > select your Flash Drive > select '''db.auth'''
#* '''Select Key Database''' select '''KEK''' > Replace from file > select your Flash Drive > select '''KEK.auth'''
#* '''Select Key Database''' select '''PK''' > Replace from file > select your Flash Drive > select '''PK.auth'''
# '''APPLY CHANGES''' > '''EXIT'''
 
Check Secure Boot State:
<pre># apk add mokutil
# mokutil --sb-state
SecureBoot enabled
</pre>
 
Congrats!
 
== Hibernate on encrypted LVM swap partition ==
 
Find your vg0-swap UUID :
<pre>lsblk -f</pre>
 
Add resume parameter to your /etc/default/grub :
<pre>GRUB_CMDLINE_LINUX_DEFAULT=....resume=UUID=<UUID of your vg0-swap partition>
</pre>
 
Add a line to your /etc/fstab :
<pre>/dev/vg0/swap  none            swap    sw    0 0</pre>
 
Enable swap service during boot :
<pre>rc-update add swap default</pre>
 
Install zzz and test it
<pre># apk add zzz
zzz- Z</pre>
 
Done and congrats !
 
[[Category:Security]]

Latest revision as of 21:50, 18 December 2023

Disclaimer : this is not to be followed, only for testing purposes. This will be updated when GRUB 2.12 rc1 will be available for LUKSv2, GRUB and FDE to work

This guide is to explain, step-by-step, how to setup Alpine Linux with Full Disk Encryption using LUKS2, LVM (one Physical Volume Partition with three Logical Volume Partitions (/ /boot & swap) with hibernation on a NVMe drive, with UEFI & Secure Boot. This guide has been written using Alpine Linux Std 3.16.1, please adapt some commands if needed.

The goal of this guide is to follow the KISS principle, but another file system can be used, multiple partitions for /home; /var/log etc.. can also be added, if the proposed configuration is not meeting your requirements.

Installing packages

To facilitate the partitioning we will use gdisk :

# apk add lsblk gptfdisk

For encryption, we will use cryptsetup :

# apk add cryptsetup

For LVM:

# apk add lvm2

For using and managing UEFI, multiple packages are needed :

# apk add efibootmgr e2fsprogs grub grub-efi

Preparing / overwriting the disk

# apk add haveged

This can take long, on my side for a 500GB nVME it tooks ~30 minutes.

# haveged -n 0 | dd of=/dev/nvme0n1

Partitioning the disk

Let's assume the disk is /dev/nvme0n1 and no partition is present, we will create two partitions :

  • one for UEFI
  • one for LVM
 # gdisk /dev/nvme0n1
GPT fdisk (gdisk) version 1.0.9.1

Partition table scan:
  MBR: not present
  BSD: not present
  APM: not present
  GPT: not present

Creating new GPT entries in memory.

Command (? for help): n
Partition number (1-128, default 1): 
First sector (34-1000215182, default = 2048) or {+-}size{KMGTP}: 
Last sector (2048-1000215182, default = 1000214527) or {+-}size{KMGTP}: 512M
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): ef00
Changed type of partition to 'EFI system partition'

Command (? for help): n
Partition number (2-128, default 2): 
First sector (34-1000215182, default = 1050624) or {+-}size{KMGTP}: 
Last sector (1050624-1000215182, default = 1000214527) or {+-}size{KMGTP}: 
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): 8309
Changed type of partition to 'Linux LUKS'

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/nvme0n1.
The operation has completed successfully.

Populate /dev with the new partitions

 # partprobe /dev/nvme0n1

Configuring LUKS

Using luks2 (unsupported by GRUB at the moment):

# cryptsetup -v -c aes-xts-plain64 -s 512 --hash sha512 --pbkdf pbkdf2 --iter-time 1000 --use-random luksFormat /dev/nvme0n1p2

Using luks1:

# cryptsetup -v -c aes-xts-plain64 -s 512 --hash sha512 --iter-time 1000 --use-urandom --type luks1 luksFormat /dev/nvme0n1p2
WARNING!
========
This will overwrite data on /dev/nvme0n1p2 irrevocably.

Are you sure? (Type 'yes' in capital letters): YES
Enter passphrase for /dev/nvme0n1p2: 
Verify passphrase: 
Key slot 0 created.
Command successful.

# cryptsetup luksOpen /dev/nvme0n1p2 lvmcrypt

LVM : Physical & Logical Volumes creation

# pvcreate /dev/mapper/lvmcrypt
  Physical volume "/dev/mapper/lvmcrypt" successfully created.
# vgcreate vg0 /dev/mapper/lvmcrypt
  Volume group "vg0" successfully created
# lvcreate -L 20G vg0 -n swap (I have a 16GB RAM laptop)
  Logical volume "swap" created.
# lvcreate -l 100%FREE vg0 -n root
  Logical volume "root" created.

To check the creation :

# lvscan
  ACTIVE            '/dev/vg0/swap' [20.00 GiB] inherit
  ACTIVE            '/dev/vg0/root' [455.92 GiB] inherit

Mounting points and File System

Create vfat file system for UEFI partition:

# mkfs.vfat /dev/nvme0n1p1

Create ext4 file system for / partition:

# mkfs.ext4 /dev/vg0/root

Activate SWAP:

# mkswap /dev/vg0/swap
# swapon /dev/vg0/swap

Mount / partition to /mnt :

# mount -t ext4 /dev/vg0/root /mnt

Create /boot/efi:

# mkdir /mnt/boot/efi -p

Mount UEFI partition to /mnt/boot/efi :

# mount -t vfat /dev/nvme0n1p1 /mnt/boot/efi

Check partition scheme:

# lsblk
nvme0n1        259:0    0 476.9G  0 disk  
├─nvme0n1p1    259:1    0   511M  0 part  /mnt/boot/efi
└─nvme0n1p2    259:2    0 476.4G  0 part  
  └─lvmcrypt   253:0    0 476.4G  0 crypt 
    ├─vg0-swap 253:1    0    20G  0 lvm   [SWAP]
    └─vg0-root 253:2    0 456.4G  0 lvm   /mnt

Installing Alpine

# setup-disk -m sys /mnt/

mkinitfs settings & modules

Edit the /mnt/etc/mkinitfs/mkinitfs.conf file and append the modules to the features parameters (keymap only needed if your keyboard is not QWERTY):

features="ata base ide scsi usb virtio ext4 lvm nvme keymap cryptsetup cryptkey resume"

Regenerate the initram:

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

Grub settings

Create a crypto_keyfile.bin to avoid typing the passphrase twice during the boot process (one for Grub partition, one for Alpine partition):

# touch /mnt/crypto_keyfile.bin
# chmod 600 /mnt/crypto_keyfile.bin
# dd if=/dev/random bs=512 count=4 | xxd -p -c999 | tr -d '\n' > /mnt/crypto_keyfile.bin
# cryptsetup luksAddKey /dev/nvme0n1p2 /mnt/crypto_keyfile.bin

Then, let's mount and chroot to our fresh installation:

# mount -t proc /proc /mnt/proc
# mount --rbind /dev /mnt/dev
# mount --make-rslave /mnt/dev
# mount --rbind /sys /mnt/sys
# chroot /mnt

Edit /etc/default/grub and add cryptkey after cryptdm=root parameter like this:

GRUB_TIMEOUT=2
GRUB_DISABLE_SUBMENU=y
GRUB_DISABLE_RECOVERY=true
GRUB_CMDLINE_LINUX_DEFAULT="modules=sd-mod,usb-storage,ext4,nvme cryptroot=UUID=XXXX cryptdm=lvmcrypt cryptkey quiet rootfstype=ext4"

XXXX could be found with blkid command

Add a new GRUB_PRELOAD_MODULES line like this:

GRUB_PRELOAD_MODULES="luks cryptodisk part_gpt lvm"

Finally, add the cryptodisk parameter :

GRUB_ENABLE_CRYPTODISK=y

Let's show the UUID of our partition scheme:

# lsblk -f

Create a /root/grub-pre.cfg and replace <XXXX-UUID_WITHOUT_HYPHENS> with your encrypted lvm partition UUID (here /dev/nvme0n1p2) without hyphens, replace <YYYY> with VG UUID from vgdisplay and replace <ZZZZ> with LV UUID from lvdisplay of your /dev/vg0/root

set crypto_uuid=<XXXX-UUID_WITHOUT_HYPHENS>
cryptomount -u $crypto_uuid
set root='lvmid/<YYYY>/<ZZZZ>'
set prefix=($root)/boot/grub
insmod normal
normal

Configuring Secure Boot

# apk add efi-mkkeys efibootmgr sbsigntool
# efi-mkkeys -s "Your Name" -o /etc/uefi-keys

Re-install Grub:

# mkdir /boot/efi/EFI/AlpineLinuxSecureBoot
# grub-mkimage -p /boot/grub -O x86_64-efi -c /root/grub-pre.cfg -o /tmp/grubx64.efi luks2 part_gpt cryptodisk lvm ext2 gcry_rijndael pbkdf2 gcry_sha512
# install -v /tmp/grubx64.efi /boot/efi/EFI/AlpineLinuxSecureBoot/
# sed -i 's/SecureBoot/SecureB00t/' /boot/efi/EFI/AlpineLinuxSecureBoot/grubx64.efi
# cd /boot/efi/EFI/AlpineLinuxSecureBoot/
# sbsign --key /etc/uefi-keys/db.key --cert /etc/uefi-keys/db.crt --output grubx64.efi.signed grubx64.efi
# grub-mkconfig -o /boot/grub/grub.cfg
# efibootmgr --disk /dev/nvme0n1p1 --part 1 --create --label 'Alpine Linux Secure Boot Signed' --load /EFI/AlpineLinuxSecureBoot/grubx64.efi.signed --verbose

To check that your .efi is signed :

 # sbverify --cert /etc/uefi-keys/db.crt /boot/efi/EFI/AlpineLinuxSecureBoot/grubx64.efi.signed 
Signature verification OK
# sbverify --list /boot/efi/EFI/AlpineLinuxSecureBoot/grubx64.efi.signed
signature 1
image signature issuers:
 - /CN="Your Name" (db)
image signature certificates:
 - subject: /CN="Your Name" (db)
   issuer:  /CN="Your Name" (db)

Copy db.auth, KEK.auth and PK.auth files from /etc/uefi-keys to a FAT formatted file system.

Reboot & enter into your UEFI (Fx key depending of your laptop)

Import keys to UEFI

This is just an example from an XPS laptop, each UEFI is unique.

  1. Go to Boot Configuration > Secure Boot
  2. Change Enable Secure Boot to ON
  3. Change Secure Boot Mode to Deployed Mode
  4. Change Enable Custom Mode to ON
  5. Go to Custom Mode Key Management
    • Reset All Keys
    • Select Key Database select db > Replace from file > select your Flash Drive > select db.auth
    • Select Key Database select KEK > Replace from file > select your Flash Drive > select KEK.auth
    • Select Key Database select PK > Replace from file > select your Flash Drive > select PK.auth
  6. APPLY CHANGES > EXIT

Check Secure Boot State:

# apk add mokutil
# mokutil --sb-state
SecureBoot enabled

Congrats!

Hibernate on encrypted LVM swap partition

Find your vg0-swap UUID :

lsblk -f

Add resume parameter to your /etc/default/grub :

GRUB_CMDLINE_LINUX_DEFAULT=....resume=UUID=<UUID of your vg0-swap partition>

Add a line to your /etc/fstab :

/dev/vg0/swap   none            swap     sw    0 0

Enable swap service during boot :

rc-update add swap default

Install zzz and test it

# apk add zzz
zzz- Z

Done and congrats !