How to install Gentoo with LUKS LVM and systemd
Introduction
In this post I’ll describe how to install Gentoo with systemd stage3 tarball on LUKS partition and LVM volume group.
This work is based on Full Disk Encryption From Scratch Simplified.
Disk partitions
I prefer to use MBR partition tables with simple, old style BIOS, and not GPT with UEFI, so if you want this guide with GPT / UEFI and TPM send me a laptop with them!
Partition scheme
This is the oldest, and simple partition scheme used on this guide.
Partition | Filesystem | Size | Description |
/dev/sda1 | ext4 | 700MiB | Boot partition |
/dev/sda2 | LUKS | rest of the disk | LUKS partition |
Creating the Boot partition
Using fdisk utility just create a new primary partition. When prompted for the Last sector, type +700M to create a partition of 700MiB in size:
livecd ~# fdisk /dev/sda
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-500118191, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-500118191, default 500118191): +700M
Created a new partition 1 of type 'Linux' and of size 700 MiB.
Creating the LUKS partition
Remaining inside the fdisk shell, just type n to create a new primary partition, and then leave all defaults typing enter for Partition number, First sector and Last sector:
Command (m for help): n
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p):
Using default response p.
Partition number (2-4, default 2):
First sector (1435648-500118191, default 1435648):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (1435648-500118191, default 500118191):
Created a new partition 2 of type 'Linux' and of size 237.8 GiB.
Change partition type to Linux LVM - Optional
Optionally you can change the second primary partition type from Linux to Linux LVM, by typing t, 2 and finally 8e
Command (m for help): t
Partition number (1,2, default 2): 2
Hex code (type L to list all codes): 8e
Changed type of partition 'Linux' to 'Linux LVM'.
Write partition layout to disk
To save partition layout and exit fdisk type w
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
livecd ~# fdisk -l /dev/sda
Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 1435647 1433600 700M 83 Linux
/dev/sda2 1435648 500118191 498682544 237.8G 8e Linux LVM
livecd ~#
Create boot filesystem
Create ext4 filesystem on first partition with only 1% of reserved space for super user.
livecd ~# mkfs.ext4 -m1 /dev/sda1
Encrypt partition with LUKS
Now we can crypt the second partition /dev/sda2 with LUKS
livecd ~# cryptsetup luksFormat -c aes-xts-plain64 -s 512 /dev/sda2
WARNING!
========
This will overwrite data on /dev/sda2 irrevocably.
Are you sure? (Type uppercase yes): YES
Enter passphrase:
Verify passphrase:
livecd ~#
Open the LUKS device
livecd ~# cryptsetup luksOpen /dev/sda2 lvm
Enter passphrase for /dev/sda2:
livecd ~#
Create LVM inside LUKS device
Create the physical volume
livecd ~# pvcreate /dev/mapper/lvm
Create the volume group
livecd ~# vgcreate -s 16M amedeos-g-nexi /dev/mapper/lvm
Create logical volumes
livecd ~# lvcreate -L 4G -n swap amedeos-g-nexi
livecd ~# lvcreate -L 150G -n root amedeos-g-nexi
Create root filesystem
Format root filesystem as ext4 with only 1% of reserved space for super user and mount it.
livecd ~# mkfs.ext4 -m1 /dev/amedeos-g-nexi/root
livecd ~# mount /dev/amedeos-g-nexi/root /mnt/gentoo
Create swap area
Format swap logical volume as swap area and activate it.
livecd ~# mkswap /dev/amedeos-g-nexi/swap
livecd ~# swapon /dev/amedeos-g-nexi/swap
Gentoo installation
Now it’s time to get your hands dirty.
Install systemd stage3
Download the systemd stage3 tarball from Gentoo
livecd ~# cd /mnt/gentoo/
livecd /mnt/gentoo # wget http://distfiles.gentoo.org/releases/amd64/autobuilds/20181228/systemd/stage3-amd64-systemd-20181228.tar.bz2
Unarchive the tarball
livecd /mnt/gentoo # tar xpvf stage3-*.tar.bz2 --xattrs-include='*.*' --numeric-owner
Configuring compile options
Open /mnt/gentoo/etc/portage/make.conf file and configure the system with your preferred optimization variables. Have a look at Gentoo Handbook
livecd /mnt/gentoo # vi /mnt/gentoo/etc/portage/make.conf
For example below you can find my make.conf optimization variables
COMMON_FLAGS="-march=native -O2 -pipe"
CFLAGS="${COMMON_FLAGS}"
CXXFLAGS="${COMMON_FLAGS}"
FCFLAGS="${COMMON_FLAGS}"
FFLAGS="${COMMON_FLAGS}"
MAKEOPTS="-j5"
GRUB_PLATFORMS="pc"
CPU_FLAGS_X86="aes avx avx2 f16c fma3 mmx mmxext pclmul popcnt sse sse2 sse3 sse4_1 sse4_2 ssse3"
USE="-gtk -gnome systemd networkmanager pulseaudio spice usbredir udisks offensive cryptsetup ocr bluetooth bash-completion"
POLICY_TYPES="targeted"
ACCEPT_KEYWORDS="~amd64"
INPUT_DEVICES="libinput"
Chrooting
Copy DNS configurations
livecd /mnt/gentoo # cp --dereference /etc/resolv.conf /mnt/gentoo/etc/
Mount proc, dev and shm filesystems
livecd /mnt/gentoo # mount -t proc /proc /mnt/gentoo/proc
livecd /mnt/gentoo # mount --rbind /sys /mnt/gentoo/sys
livecd /mnt/gentoo # mount --make-rslave /mnt/gentoo/sys
livecd /mnt/gentoo # mount --rbind /dev /mnt/gentoo/dev
livecd /mnt/gentoo # mount --make-rslave /mnt/gentoo/dev
livecd /mnt/gentoo # test -L /dev/shm && rm /dev/shm && mkdir /dev/shm
livecd /mnt/gentoo # mount -t tmpfs -o nosuid,nodev,noexec shm /dev/shm
livecd /mnt/gentoo # chmod 1777 /dev/shm
chroot to /mnt/gentoo
livecd /mnt/gentoo # chroot /mnt/gentoo /bin/bash
livecd / # source /etc/profile
livecd / # export PS1="(chroot) $PS1"
(chroot) livecd / #
mounting the boot partition
(chroot) livecd / # mount /dev/sda1 /boot
Updating the Gentoo ebuild repository
Update the Gentoo ebuild repository to the latest version.
(chroot) livecd ~# emerge --sync
Update portage
If at the end of emerge sync you see a message like this:
* An update to portage is available. It is _highly_ recommended
* that you update portage now, before any other packages are updated.
* To update portage, run 'emerge --oneshot portage' now.
on this case run
(chroot) livecd ~# emerge --oneshot portage
Choosing the right profile (with systemd)
Choose one of the systemd available, for example for my system I have selected desktop/plasma/systemd
(chroot) livecd ~# eselect profile list
...
(chroot) livecd ~# eselect profile set 20
(chroot) livecd ~# eselect profile list
Available profile symlink targets:
...
[20] default/linux/amd64/17.0/desktop/plasma/systemd (stable) *
...
Timezone
Update the timezone, for example Europe/Rome
(chroot) livecd ~# echo Europe/Rome > /etc/timezone
(chroot) livecd ~# emerge --config sys-libs/timezone-data
Configure locales
If you want only few locales on your system, for example C, en_us and it_IT
(chroot) livecd /etc # cat locale.gen
...
en_US ISO-8859-1
en_US.UTF-8 UTF-8
it_IT ISO-8859-1
it_IT.UTF-8 UTF-8
(chroot) livecd /etc # locale-gen
now you can choose your preferred locale with
(chroot) livecd /etc # eselect locale list
(chroot) livecd /etc # eselect locale set 1
reload the environment
(chroot) livecd /etc # env-update && source /etc/profile && export PS1="(chroot) $PS1"
Updating the world
If you change your profile, or if you change your USE flags run the update
(chroot) livecd ~# emerge --ask --verbose --update --deep --newuse @world
now you can take a coffee
Optional - GCC Upgrade
If you are in amd64 testing, most probably, updating the world, you have installed a new version of GCC, so from now we can use it
(chroot) livecd ~# gcc-config --list-profiles
[1] x86_64-pc-linux-gnu-7.3.0 *
[2] x86_64-pc-linux-gnu-8.2.0
set the default profile to 2, corresponding on the above example to the GCC 8.2
(chroot) livecd ~# gcc-config 2
* Switching native-compiler to x86_64-pc-linux-gnu-8.2.0 ...
>>> Regenerating /etc/ld.so.cache... [ ok ]
* If you intend to use the gcc from the new profile in an already
* running shell, please remember to do:
* . /etc/profile
(chroot) livecd ~# source /etc/profile
livecd ~# export PS1="(chroot) $PS1"
after that re-emerge the libtool
(chroot) livecd ~# emerge --ask --oneshot --usepkg=n sys-devel/libtool
Optional - Install vim
If you hate nano editor like me, now you can install vim
(chroot) livecd ~# emerge --ask app-editors/vim
Configure fstab
This file contains the mount points of partitions to be mounted. Run blkid to see the UUIDs
(chroot) livecd ~# blkid
/dev/loop0: TYPE="squashfs"
/dev/sda1: UUID="4040cacf-092e-4221-b815-7ca15b4fb7e1" TYPE="ext4" PARTUUID="fdddc7c0-01"
/dev/sda2: UUID="3cb431e7-a6ff-458d-9f1f-f86dac11545b" TYPE="crypto_LUKS" PARTUUID="fdddc7c0-02"
/dev/sdb1: UUID="2019-01-04-02-22-54-77" LABEL="Gentoo amd64 20190103T214502Z" TYPE="iso9660" PTUUID="26a11c8f" PTTYPE="dos" PARTUUID="26a11c8f-01"
/dev/sdb2: SEC_TYPE="msdos" LABEL_FATBOOT="GENTOOLIVE" LABEL="GENTOOLIVE" UUID="37E9-562E" TYPE="vfat" PARTUUID="26a11c8f-02"
/dev/mapper/lvm: UUID="p8UcJf-k9vk-esRW-JTIY-63Rz-4tSc-YjXyb4" TYPE="LVM2_member"
/dev/mapper/amedeos--g--nexi-swap: UUID="e61a7777-d005-470f-9ab2-27c75b911a18" TYPE="swap"
/dev/mapper/amedeos--g--nexi-root: UUID="a2fc60ea-1f7d-4abf-a991-21f7f0832098" TYPE="ext4"
copy the UUID for root filesystem -> upon LVM -> upon LUKS, (on the above example is a2fc60ea-1f7d-4abf-a991-21f7f0832098), and for the boot filesystem which resides on /dev/sda1 partition (on the above example is 4040cacf-092e-4221-b815-7ca15b4fb7e1).
This is my fstab
(chroot) livecd ~ # cat /etc/fstab
# /etc/fstab: static file system information.
UUID=4040cacf-092e-4221-b815-7ca15b4fb7e1 /boot ext4 defaults 1 2
UUID=a2fc60ea-1f7d-4abf-a991-21f7f0832098 / ext4 defaults 1 1
/dev/amedeos-g-nexi/swap none swap sw 0 0
# tmps
tmpfs /tmp tmpfs defaults,size=4G 0 0
tmpfs /run tmpfs size=100M 0 0
# shm
shm /dev/shm tmpfs nodev,nosuid,noexec 0 0
Installing the sources
Install the kernel, genkernel-next and cryptsetup
(chroot) livecd ~# emerge --ask sys-kernel/gentoo-sources
(chroot) livecd ~# emerge --ask sys-kernel/genkernel-next
(chroot) livecd ~# emerge --ask sys-fs/cryptsetup
Optional - Installing firmware
Some drivers require additional firmware, if you use some of those you need to install the firmware packages
(chroot) livecd ~# emerge --ask sys-kernel/firmware
Optional - Installing intel microcode
If you have an intel cpu and you want to upgrade the microcode you could install the intel-microcode package.
(chroot) livecd ~# mkdir -p /etc/portage/package.use
(chroot) livecd ~# echo "sys-firmware/intel-microcode initramfs" > /etc/portage/package.use/intel-microcode
(chroot) livecd ~# emerge --ask sys-firmware/intel-microcode
Configure genkernel.conf
Configure genkernel for systemd, LUKS and LVM
(chroot) livecd ~# cd /etc/
(chroot) livecd /etc # cp -p genkernel.conf genkernel.conf.ORIG
(chroot) livecd /etc # vim genkernel.conf
...
MAKEOPTS="$(portageq envvar MAKEOPTS)"
...
LVM="yes"
...
LUKS="yes"
...
UDEV="yes"
...
Run genkernel
Configure your kernel with the preferred options and then
(chroot) livecd ~# time genkernel --luks --lvm all
Install and configure grub
Install grub
Configure grub to use device-mapper and standard “pc” platform
(chroot) livecd ~# mkdir -p /etc/portage/package.use
(chroot) livecd ~# echo "sys-boot/grub device-mapper" > /etc/portage/package.use/grub
(chroot) livecd ~# echo 'GRUB_PLATFORMS="pc"' >> /etc/portage/make.conf
emerge grub
(chroot) livecd ~# emerge --ask sys-boot/grub
Install grub on MBR
just run grub-install
(chroot) livecd ~# grub-install --target=i386-pc /dev/sda
Configure grub
if you run grub-mkconfig, it hangs because it doesn’t has /run filesystem and os-probe will loop indefinitely; so we can exit from chroot env and mount /run filesystem
(chroot) livecd ~# exit
livecd ~# mount --rbind /run /mnt/gentoo/run
livecd ~# mount --make-rslave /mnt/gentoo/run
livecd ~ # cd /mnt/gentoo/
livecd /mnt/gentoo # chroot /mnt/gentoo /bin/bash
livecd / # source /etc/profile
livecd / # export PS1="(chroot) $PS1"
(chroot) livecd / #
edit /etc/default/grub
(chroot) livecd /# cd /etc/default/
(chroot) livecd /etc/default # cp grub grub.ORIG
(chroot) livecd /etc/default # vim grub
and most important configure GRUB_CMDLINE_LINUX with
GRUB_CMDLINE_LINUX="init=/usr/lib/systemd/systemd dolvm crypt_root=UUID=3cb431e7-a6ff-458d-9f1f-f86dac11545b root=/dev/mapper/amedeos--g--nexi-root"
where
parameter | description |
init | set init to systemd -> /usr/lib/systemd/systemd |
dolvm | tell init to use lvm |
crypt_root | put here the UUID (from blkid) of the second partition /dev/sda2 |
root | put the logical volume which contains root filesystem |
finally we can run grub-mkconfig
(chroot) livecd /etc/default # cd
(chroot) livecd ~# grub-mkconfig -o /boot/grub/grub.cfg
Set the root password
Remember to set the root password
(chroot) livecd ~# passwd
Rebooting the system
Exit the chrooted environment and reboot
(chroot) livecd ~ # exit
livecd /mnt/gentoo # shutdown -r now