How to install Gentoo with Full Disk Encryption (GPT, UEFI, LVM on LUKS1)

2020-09-14

(last time edited: 2021-03-14)

tags: linux, gentoo

Gentoo Linux is a Linux distribution built using the Portage package management system. Unlike a binary software distribution, the source code is compiled locally according to the user's preferences and is often optimized for the specific type of computer. Precompiled binaries are available for some larger packages or those with no available source code.

Notice: We will not install Gentoo from a boot media live image iso! We will use a simpler method: installing from a current working Linux distro and extracting a ROOTFS tarball. It doesn't matter which distro are you working on.

Partition

Check your connected devices.

# lsblk

Partition your device using fdisk.

# fdisk /dev/sdX

Create a new GPT partition table.

Command (m for help): g

Created a new GPT disklabel with disk identifier XxXXXXXXXXXXXX

Create the first partition. This will be your EFI partition. Choose a considerable size. (+200M, +300M)

Command (m for help): n

Partition number (1-128, default 1): 1

First sector (2048-xxxxxxxxxxxxx, default 2048): ENTER

Last sector, +-sectors or +/-size{K,M,G,T,P} (2048-xxxxxxxxx, default xxxxxxxxx): +200M

Created a new partition 1 of type 'xxxxxxxxx' and of size 200 MiB.

Create a second partition. This will be your LUKS partition.

Command (m for help): n

Partition number (2-128, default 2): ENTER

First sector (xxxxxxxxxx-xxxxxxxxxx, default xxxxxxxxxx): ENTER

Last sector, +/-sectors or +/-size{K,M,G,T,P} (xxxxxxxxx-xxxxxxxx, default xxxxxxxxx): ENTER

Created a new partition 2 of type 'xxxxx' and of size XXXXXX GiB.

Write changes and exit.

Command (m for help): w

The partition table has been altered.
Calling iotcl() to re-read partition table.
Syncing disks.

Re-read the partition table so the Linux kernel see the changes.

# kpartx /dev/sdX

Encrypt

Initialize LUKS on the single partition.

# cryptsetup luksFormat --type luks1 /dev/sdX2

Open the partition. You can assign whatever label you want instead of gentooluks.

# cryptsetup open /dev/sdX2 gentooluks

Initialize a physical volume.

# pvcreate /dev/mapper/gentooluks

Create a volume group. You can assign whatever label you want instead of gentoo.

# vgcreate gentoovg /dev/mapper/gentooluks

Create a logical volume for root. You can choose the size you want instead of 50G.

# lvcreate -n root -L 50G gentoovg

Optional: Create a logical volume for swap.

I recommend using 2 times the amount of RAM for systems with less than 2 GB. Equal to the amount of RAM for 2-8GB systems. And 4GB for systems with more than 8GB.

# lvcreate -n swap -L 4G gentoovg

Create a logical volume for home designating all of the free space left.

# lvcreate -n home -l 100%FREE gentoovg

Format

Format the EFI partition and logical volumes.

# mkfs.vfat /dev/sdX1

# mkfs.ext4 /dev/mapper/gentoovg-root

Optional: Activate swap if you opted to create a swap partition.

# mkswap /dev/mapper/gentoovg-swap

# mkfs.ext4 /dev/mapper/gentoovg-home

Mount

Create a directory to start working on your new system.

# mkdir /mnt/nusys

Mount the root logical volume.

# mount /dev/mapper/gentoovg-root /mnt/nusys

Create a home directory in the mounted root volume, in order to mount the home volume.

# mkdir /mnt/nusys/home

Mount the home logical volume.

# mount /dev/mapper/gentoo-home /mnt/nusys/home

Create an EFI directory in the new system.

# mkdir -p /mnt/nusys/boot/efi

Mount the EFI partition.

# mount /dev/sdX1 /mnt/nusys/boot/efi

Tarball

Create a variable containing the latest stage3 Gentoo ROOTFS tarball version. The tarball contains a base Gentoo filesystem.

# TAR=$(curl -s https://gentoo.c3sl.ufpr.br/releases/amd64/autobuilds/latest-stage3-amd64.txt | awk '/^[^#]/ {print $1}')

Pass the variable and download the tarball.

# wget https://gentoo.c3sl.ufpr.br/releases/amd64/autobuilds/"$TAR"

Extract the contents from the tarball.

# tar -xf "$TAR" -C /mnt/nusys

Mount Bind

Bind mount important directories on your new system.

# mount -t proc /proc /mnt/nusys/proc

# mount -t sysfs /sys /mnt/nusys/sys

# mount -B /dev /mnt/nusys/dev

# mount -t devpts pts /mnt/nusys/dev/pts

Configure Portage

Add a working mirror for Gentoo's Portage package manager. I use a Brazilian server.

# echo GENTOO_MIRRORS=https://gentoo.c3sl.ufpr.br >> /mnt/nusys/etc/portage/make.conf

Notify Portage that you'll install GRUB with efi-64 compatibility. Notice! Only if you are installing under a x86_64 CPU with UEFI enabled the BIOS.

# echo GRUB_PLATFORMS=efi-64 >> /mnt/nusys/etc/portage/make.conf

Notify Portage to use an specific video card graphic, in this case I'm using Intel hardware.

# echo VIDEO_CARDS=intel >> /mnt/nusys/etc/portage/make.conf

Declare important USE flags in a .txt file. Portage will compile and install these programs with specific compatibility.

# echo sys-fs/cryptsetup luks1_default > /mnt/nusys/etc/portage/package.use/customuseflags.txt

# echo sys-boot/grub device-mapper grub_platforms_efi-64 >> /mnt/nusys/etc/portage/package.use/customuseflags.txt

Modify the rsync Gentoo mirrors for Portage. I also use the same Brazilian server.

# mkdir /mnt/nusys/etc/portage/repos.conf

# cp /mnt/nusys/usr/share/portage/config/repos.conf /mnt/nusys/etc/portage/repos.conf/gentoo.conf

# sed -i "s/^sync-uri.*/sync-uri = rsync:\/\/rsync.br.gentoo.org\/gentoo-portage/" /mnt/nusys/etc/portage/repos.conf/gentoo.conf

Resolv

Copy our resolv.conf to the new system in order to have working Internet.

# cp /etc/resolv.conf /mnt/nusys/etc

Webrsync

Run webrsync to sinchronize your previously extracted tarball files.

# chroot /mnt/nusys emerge-webrsync

Timezone

Configure timezone.

# echo America/Argentina/Salta > /mnt/nusys/etc/timezone

# chroot /mnt/nusys emerge --config timezone-data

Localization

Configure locales.

# echo en_US.UTF-8 UTF-8 > /mnt/nusys/etc/locale.gen

# chroot /mnt/nusys locale-gen

# echo LANG=\"en_US.UTF-8\" > /mnt/nusys/etc/env.d/02locale

Download Sources and Software Installation

# chroot /mnt/nusys emerge -q sys-kernel/gentoo-sources sys-kernel/dracut sys-fs/lvm2 sys-fs/cryptsetup sys-boot/grub sys-boot/refind net-misc/dhcpcd net-misc/netifrc

Compile and Kernel Installation

First we need to configure our Linux kernel using an ncurses menu.

# chroot /mnt/nusys make -C /usr/src/linux nconfig

Notice: Make sure you turn on these settings:

[*] Enable loadable module support
    General setup  --->

[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
    Device Drivers --->

Multiple devices driver support (RAID and LVM) --->
    <*> Device mapper support
    <*> Crypt target support

[*] Cryptographic API --->
    <*> XTS support
    <*> SHA224 and SHA256 digest algorithm
    <*> AES cipher algorithms
    <*> AES cipher algorithms (x86_64)
    <*> User-space interface for symmetric key cipher algorithms

Make sure you saved the .config file and we will start compiling the Linux kernel (vmlinux and bzImage), kernel modules and also install them.

# chroot /mnt/nusys make -C /usr/src/linux

Initramfs

In order to boot and decrypt our hard-drive, we need an initramfs.

Obtain and save our newly compiled kernel version and save it in a variable.

# KVER=$(ls /mnt/nusys/lib/modules)

Generate an initramfs using dracut.

# chroot /mnt/nusys dracut -H -k /lib/modules/$KVER --kver $KVER

Fstab

With the following commands we will tell our new system where to look for devices when we boot.

# echo tmpfs /tmp tmpfs defaults 0 0 > /mnt/nusys/etc/fstab

# echo /dev/sdX1 /boot/efi vfat defaults 0 0 >> /mnt/nusys/etc/fstab

# echo /dev/mapper/gentoovg-root / ext4 defaults 0 0 >> /mnt/nusys/etc/fstab

Optional: Add swap to fstab if you created a swap partition.

# echo /dev/mapper/gentoovg-swap none swap defaults 0 0 >> /mnt/nusys/etc/fstab

# echo /dev/mapper/gentoovg-home /home ext4 defaults 0 0 >> /mnt/nusys/etc/fstab

GRUB & rEFInd

Edit GRUB's configuration file so it can read LUKS root.

# sed -i "/GRUB_CMDLINE.*=/s/\"$/ rd.auto=1&/" /mnt/nusys/etc/default/grub

Install GRUB.

# chroot /mnt/nusys grub-install /dev/sdX

Create a configuration file for GRUB.

# chroot /mnt/nusys grub-mkconfig -o /boot/grub/grub.cfg

Install rEFInd.

# chroot /mnt/nusys refind-install

User Creation

Create your user.

# chroot /mnt/nusys useradd -m yourusername

Assign a password to your user.

# chroot /mnt/nusys passwd yourusername

Root Password

Assign a password to the root account.

# chroot /mnt/nusys passwd root

System Configuration

Edit hostname.

# sed -i s/localhost/your_desired_hostname/ /mnt/nusys/etc/conf.d/hostname

Create a symbolic link to activate ethernet networking.

# chroot /mnt/nusys ln -s /etc/init.d/net.lo /etc/init.d/net.eth0

Configure keymaps. My keymap is la-latin1.

# sed -i s/keymap=.*/keymap=la-latin1/ /mnt/nusys/etc/conf.d/keymaps

Configure the system clock. I use local instead of UTC.

# sed -i s/clock=.*/clock=local/ /mnt/nusys/etc/conf.d/hwclock

Reboot

Just run:

# reboot

If everything went correctly you will be able to see a cute rEFInd screen at boot.

Happy compiling!