documentation/docs/gentoo-desktop-setup/installation.md
2025-01-12 18:33:21 +01:00

12 KiB

Now is the time to actually install Gentoo.

First import the pool again:

root@host:~# zpool import -N -R /mnt rpool
root@host:~# zfs load-key -L file:///tmp/rpool.key rpool

Then mount the datasets and the ESP on /mnt:

root@host:~# mount -t zfs rpool/root/gentoo /mnt
root@host:~# mkdir /mnt/var
root@host:~# mount -t zfs rpool/root/gentoo/var /mnt/var
root@host:~# mkdir /mnt/efi
root@host:~# mount -t vfat /dev/disk/by-label/esp /mnt/efi

Now we're going to fetch a stage3 tarball for on the root of the system. Replace the <release_date> with the latest tarball release.

root@host:~# cd /mnt
root@host:/mnt# wget https://distfiles.gentoo.org/releases/amd64/autobuilds/current-stage3-amd64-musl-hardened/stage3-amd64-musl-hardened-<release_date>.tar.xz

This should have placed a tarball at /stage3-amd64-musl-hardened-*-.tar.xz. There are also other mirrors like https://ftp.snt.utwente.nl/pub/os/linux/gentoo/releases/amd64/autobuilds/current-stage3-amd64-musl-hardened/ which might provide a faster download depending on your location. Check out https://www.gentoo.org/downloads/mirrors/ for other mirrors.

It is also possible to use links instead of wget which provides a small user interface for navigation: # links https://distfiles.gentoo.org/releases/amd64/autobuilds/current-stage3-amd64-musl-hardened

Unpack it in the new root:

root@host:/mnt# tar xpvf stage3-*.tar.xz --numeric-owner -C /mnt

Then before finally chrooting into the system simply copy over the resolv.conf for internet connection inside the chroot.

root@host:/# cp /etc/resolv.conf /mnt/etc/.
root@host:/# cp /tmp/rpool.key /mnt/tmp
root@host:/# for i in dev proc sys run; do mount --rbind --make-rslave /$i /mnt/$i; done
root@host:/# chroot /mnt 

Configuring the system

Portage

Before installing any software first edit /etc/portage/make.conf which acts as the main configuration file for portage. A Gentoo installation is highly personal so diverting from these settings is encouraged. Here's an example file:

# Please consult /usr/share/portage/config/make.conf.example for a more
# detailed example.
COMMON_FLAGS="-march=native -O2 -pipe"
CFLAGS="${COMMON_FLAGS}"
CXXFLAGS="${COMMON_FLAGS}"
FCFLAGS="${COMMON_FLAGS}"
FFLAGS="${COMMON_FLAGS}"
RUSTFLAGS="${RUSTFLAGS} -C target-cpu=native"

# MakeOpts
MAKEOPTS="-j7 -l5"

# WARNING: Changing your CHOST is not something that should be done lightly.
# Please consult https://wiki.gentoo.org/wiki/Changing_the_CHOST_variable before changing.
CHOST="x86_64-pc-linux-musl"

# NOTE: This stage was built with the bindist USE flag enabled

# This sets the language of build output to English.
# Please keep this setting intact when reporting bugs.
LC_MESSAGES=C.utf8

# Logging
PORTAGE_ELOG_CLASSES="log warn error"
PORTAGE_LOGDIR="/var/log/portage"
PORTAGE_LOGDIR_CLEAN="find \"\${PORTAGE_LOGDIR}\" -type f ! -name \"summary.log*\" -mtime +7 -delete"

# Only accept free licenses
ACCEPT_LICENSE="-* @FREE"

# USE flags
USE="${USE} networkmanager -modemmanager wayland dbus elogind -systemd policykit pam man udev pipewire initramfs secureboot modules-sign dist-kernel" # ....

# Emerge settings
EMERGE_DEFAULT_OPTS="${EMERGE_DEFAULT_OPTS} --with-bdeps y"

# For secureboot (will be necessary later)
SECUREBOOT_SIGN_KEY="/var/lib/sbctl/keys/db/db.key"
SECUREBOOT_SIGN_CERT="/var/lib/sbctl/keys/db/db.pem"
MODULES_SIGN_KEY="${SECUREBOOT_SIGN_KEY}"
MODULES_SIGN_CERT="${SECUREBOOT_SIGN_CERT}"
MODULES_SIGN_HASH="sha512"

Don't forget to change the MAKEOPTS to match your CPU and also the USEFLAGS to your liking by i.e. adding -gtk-doc.

Now finally sync the repositories and try installing a package like vim.

root@chroot:~# emaint sync
...
Action: sync for repo: gentoo, returned code = 0

root@chroot:~# emerge --ask --verbose app-editors/vim
>>> Completed (3 of 4) app-editors/vim-*::gentoo

Then try running vim and it theory it should work!

Fstab

Simply add these lines to the systems fstab:

rpool/root/gentoo       /   	zfs     rw,noatime,xattr,posixacl,casesensitive                 0 1
rpool/root/gentoo/var   /var	zfs     rw,noatime,nosuid,nodev,xattr,posixacl,casesensitive    0 2
/dev/disk/by-label/esp  /efi	vfat	defaults,nodev,nosuid,noexec,umask=0077                 0 2
tmpfs                   /tmp	tmpfs	rw,nodev,nosuid,noexec,mode=1777                        0 0
proc                    /proc	proc	nodev,nosuid,noexec,hidepid=2                           0 0

Date and time

Musl does not come with timezone's installed by default. Install timezone-data with:

root@chroot:~# emerge -av sys-libs/timezone-data

Select the correct timezone with:

TZ="/usr/share/zoneinfo/<region>/<city>"

Update the environment of your shell-session:

root@chroot:~# env-update && source /etc/profile

To sync your system's time with a server set up a Network Time Protocol daemon. It's recommended to use OpenBSD's openntpd which aims to be as secure and minimal as possible:

root@chroot:~# emerge -av net-misc/openntpd
root@chroot:~# rc-update add ntpd default
root@chroot:~# rc-service ntpd start

Set up locales

Musl also does not support locales out of the box. They aren't necessary but some programms rely on them to set the language of their application. To be able to use locales install the musl-locales package:

root@chroot:~# emerge -av sys-apps/musl-locales

And to allow the system to know where the locales are located:

MUSL_LOCPATH="/usr/share/i18n/locales/musl"

There are a multiple locales to choose from. In most situations choosing en_US is the standard but selecting a diverent one should not break the system. Choose the desired locale with n \in \mathbb{N}:

root@chroot:~# eselect locale list
root@chroot:~# eselect locale set <n>
root@chroot:~# env-update && source /etc/profile

Setting the hostname

The system's hostname is the name given to the machine. Other systems on a network will also be able to see this name. To set it replace with the desired name:

root@chroot:~# echo "<hostname>" > /etc/hostname

Internet

NetworkManager is an easy to use network manager. It has compatibility with most VPN protocols, works with Eduroam etc. and also has multiple graphical interfaces. Before emerging it, consider adding some USE flags to your liking:

net-misc/networkmanager dhcpcd -wext -modemmanager -ppp

Also make sure the networkmanager USE flag is enabled in your make.conf. Then emerge networkmananger:

root@chroot:~# emerge -av net-misc/networkmanager

Then disable any other network services before enabling the NetworkManagerservice:

root@chroot:~# rc-update add NetworkManager default
 * service NetworkManager added to runlevel default

Adding GURU

GURU is an extra repository which contains packages not available in the main Gentoo repository. Although the packages it contains might not be as well tested as in the main repo they are still necessary for some setups. Add Guru with:

root@chroot:~# emerge -av app-eselect/eselect-repository
root@chroot:~# eselect repository enable guru
root@chroot:~# emaint sync --repo guru

To allow unstable packages from GURU set the ~amd64 keyword for it:

*/*::guru ~amd64

Making the system boot

Sbctl

sbctl is a simple tool which allows for the management of Secureboot settings on a system. It can create, deploy and sign keys with ease. First off install sbctl:

root@chroot:~# emerge -av sbctl

Verify that Secureboot mode is on and in setup mode with sbctl status

Then create and enroll keys into the system.

root@chroot:~# sbctl create-keys
Created Owner UUID abcde....
Creating secure boot keys...✔
Secure boot keys created!

root@chroot:~# sbctl enroll-keys <--microsoft>
...
Enrolled keys to the EFI variables!

Use the --microsoft flag if the system is unable to use custom keys or when dual booting with Windows.

Zlevis' auto decryption

zlevis is able to unlock an encrypted ZFS root pool with keys saved in a TPM, currently it's only available in the portage-ample repository and also has some dependencies in the guru repository. Add the portage-ample repository with:

root@chroot:~# eselect repository add portage-ample git https://git.bijl.us/lnorg/portage-ample
root@chroot:~# emaint sync -r portage-ample

Then before emerging add the dracut flag for zlevis:

app-crypt/zlevis dracut

Then simply install it:

root@chroot:~# emerge -av app-crypt/zlevis

Now add zlevis to the pool with

root@chroot:~# zfs set tpm:jwe=$(zlevis-encrypt '{}' < /tmp/rpool.key) rpool

UKI's

UKI's in conjuction with secureboot make for a pretty secure bootchain. It bundles the command line, initramfs, efi-stub and more in one file which can then easily be signed for Secureboot. We use dracut as initramfs generator and ukify as UKI generator.

Configure the kernelinstall to use dracut and ukify:

layout=uki
initrd_generator=dracut
uki_generator=ukify
[UKI]
SecureBootSigningTool=sbsign

Portage also has to be told to generate a UKI when installing a kernel. Set the corresponding required USE flags:

sys-apps/systemd-utils kernel-install boot ukify
sys-kernel/installkernel dracut ukify uki

These USE flags tell portage also to install systemd-boot which can automatically detect UKI's and because of the secureboot flag in /etc/portage/make.conf it will also automatically sign the bootloader when it gets installed or updated on the ESP.

For a desktop to function it will also require firmware. On Linux this is usually the linux-firmware package. Allow the licenses required for linux-firmware:

# Accepting the license for linux-firmware and redistributable licenses
sys-kernel/linux-firmware linux-fw-redistributable @BINARY-REDISTRIBUTABLE

Then to allow zlevis to unlock the root pool it will need to be added to the initramfs. Enable the zlevis module for dracut:

nofsck="yes"
add_dracutmodules+=" zlevis "

Before installing a kernel define a minimal kernel command line which allows the initramfs to find the root:

rw root=ZFS=rpool/root/gentoo quiet splash

Then finally install the packages mentioned which are required for a running system:

root@chroot:~# emerge -av sbsigntools systemd-utils linux-firmware gentoo-kernel-bin zfs-kmod

Note that gentoo-kernel-bin was installed which is the pre-compiled Gentoo kernel. Later on we will compile our own custom kernel.

It should have done this without throwing any errors.

Because Gentoo generates UKI's for all the kernels installed on a system it would be nice to be able to choose upon boot which one. For a nice boot interface install systemd-boot on the ESP:

root@chroot:~# bootctl install
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed" to "/efi/EFI/systemd/systemd-bootx64.efi".
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed" to "/efi/EFI/BOOT/BOOTX64.EFI".
Random seed file /efi/loader/random-seed successfully refreshed (32 bytes).
Created EFI boot entry "Linux Boot Manager".

The last thing to do is adding a few ZFS services on boot:

root@chroot:~# rc-update add zfs-import sysinit
root@chroot:~# rc-update add zfs-mount sysinit

Now exit the chroot and unmount the filesystem with:

root@chroot:~# umount -lf /mnt

The system should be functionalafter reboot!