Compare commits

..

2 commits

Author SHA1 Message Date
nils
b8e473b64f Removed raid mention 2024-10-27 12:14:09 +01:00
Nils
440a2b9dce Yes 2024-10-27 12:04:30 +01:00
22 changed files with 190 additions and 967 deletions

View file

@ -1,5 +1,5 @@
# An Alpine Linux desktop installation
This guide will demonstrate how to install [Alpine Linux](https://www.alpinelinux.org/) with encryption, secureboot and a graphical wayland session using wayfire. Alpine Linux makes a perfect base for those who want a minimal, simple and secure Linux installation. This installation will also make use of [Nix](https://nixos.org/) and [Home-manager](https://github.com/nix-community/home-manager) which allows for easy deployment and user independent packages. Check out the [Alpine Linux wiki](https://wiki.alpinelinux.org/wiki/Main_Page) for additional resources and information.
This guide will demonstrate how to install [Alpine Linux](https://www.alpinelinux.org/) with encryption, secureboot and a graphical wayland session using wayfire. Alpine Linux makes a perfect base for those who want a minimal, simple and secure Linux installation. Check out the [Alpine Linux wiki](https://wiki.alpinelinux.org/wiki/Main_Page) for additional resources and information.
> Note that all this documentation is focused on the `x86_64` architecture.

View file

@ -1,26 +1,41 @@
# Installation
To install the Alpine Linux distribution on the system, the alpine root partition and the EFI partition have to be mounted to the main system.
To install the Alpine Linux distribution on the system, the datasets of the system pool and the EFI partitions have to be mounted to the main system.
First import and decrypt the system pool.
```
# zpool import -N -R /mnt tank
# zfs load-key tank
```
Mount the datasets in the system pool and decrypt the home dataset.
```
# mount tank/root/alpine /mnt -t zfs -o noatime
# zfs mount tank/home
# zfs mount tank/var
```
Mount the ESP.
```
# mount /dev/vg/alpine_root /mnt -t ext4
# mkdir /mnt/esp
# mount /dev/disk/by-label/esp /mnt/esp -t vfat
```
Then install Alpine Linux using `setup disk`
Then install Alpine Linux.
```
# export BOOTLOADER=none
# setup-disk -m sys /mnt
```
> This will also add `grub` as bootloader which will be replaced but for now it will reside on the ESP.
To have a functional chroot into the system, bind the system process directories
To have a functional chroot into the system, bind the system process directories.
```
# for i in dev proc sys run; do
> mount --rbind --make-rslave /$i /mnt/$i
# for dir in dev proc sys run; do
> mount --rbind --make-rslave /$dir /mnt/$dir
> done
# chroot /mnt
```
@ -33,7 +48,6 @@ The other setup scripts can be used to configure key aspects of the system. Besi
# setup-timezone -i <area>/<subarea>
# setup-ntp openntpd
# rc-update add acpid default
# rc-update add lvm boot
# rc-update add seedrng boot
# rm -rf /var/tmp
# ln -s /tmp /var/tmp
@ -50,49 +64,38 @@ clock_hctosys="NO"
clock_systohc="NO"
```
Edit `/etc/fstab` for correct mounts
Configure ZFS to mount.
```
/dev/disk/by-label/esp /esp vfat defaults,nodev,nosuid,noexec 0 2
/dev/vg/alpine_root / ext4 defaults,noatime 0 1
/dev/vg/home /home ext4 defaults,noatime,nodev,nosuid 0 2
/dev/vg/var /var ext4 defaults,nodev,nosuid,noexec 0 2
/dev/vg/nix /nix ext4 defaults,noatime,nodev,nosuid 0 2
tmpfs /tmp tmpfs rw,size=4G,nr_inodes=5k,nodev,nosuid,noexec,mode=1777 0 0
proc /proc proc nodev,nosuid,noexec,hidepid=2 0 0
rc-update add zfs-import sysinit
rc-update add zfs-mount sysinit
```
By default, Alpine Linux uses `mkinitfs` to create an initial ram filesystem, although it is minimal that also means that it lacks some functionality which is needed for a proper setup. Because of this `mkinitfs` and `grub-efi `will be replaced with `booster` and `secureboot-hook`.
Edit `/etc/fstab` for correct mounts:
```
# apk add booster secureboot-hook sbctl
# apk del mkinitfs grub-efi
tank/root/alpine / zfs rw,noatime,xattr,posixacl,casesensitive 0 1
/dev/disk/by-label/esp /esp vfat defaults,nodev,nosuid,noexec 0 2
tmpfs /tmp tmpfs rw,nodev,nosuid,noexec,mode=1777 0 0
proc /proc proc nodev,nosuid,noexec,hidepid=2 0 0
```
To configure booster edit `/etc/booster.yaml`:
By default, Alpine Linux uses `mkinitfs` to create an initial ram filesystem.
```
enable_lvm: true
busybox: false
modules: vfat,nls_cp437,nls_iso8859_1
# apk add secureboot-hook sbctl
```
The most important step is the creation of a UKI using `secureboot-hook` which also automatically signs them. First the hook itself will have to be tweaked to use `booster` instead of `mkinitfs`, edit `/etc/kernel-hooks.d/50-secureboot.hook` and change the line:
Configure `/etc/mkinitfs/mkinitfs.conf` to disable it's hook:
```
/sbin/mkinitfs -o "$tmpdir"/initramfs "$NEW_VERSION-$FLAVOR"
# echo 'disable_trigger=yes' >> /etc/mkinitfs/mkinitfs.conf
```
to:
The most important step is the creation of a UKI using `secureboot-hook` which also automatically signs them. Configure `/etc/kernel-hooks.d/secureboot.conf` for cmdline and secureboot.
```
/usr/bin/booster build "$tmpdir"/initramfs --kernel-version "$NEW_VERSION-$FLAVOR"
```
and configure `/etc/kernel-hooks.d/secureboot.conf` for cmdline and secureboot.
```
cmdline="rw rd.luks.name=<uuid>=luks rd.lvm.vg=vg root=/dev/vg/alpine_root modules=ext4 quiet splash"
cmdline="rw root=ZFS=tank/root/alpine quiet splash"
signing_cert="/usr/share/secureboot/keys/db/db.pem"
signing_key="/usr/share/secureboot/keys/db/db.key"
@ -101,12 +104,6 @@ output_dir="/esp/efi/linux"
output_name="alpine-linux-{flavor}.efi"
```
Here `<uuid>` has to be replaced with the UUID of the partition which contains the volume group:
```
# blkid /dev/<disk>2 >> /etc/kernel-hooks.d/secureboot.conf
```
Use `sbctl` to create secureboot keys and sign them.
```
@ -116,7 +113,13 @@ Use `sbctl` to create secureboot keys and sign them.
> Whilst enrolling the keys it might be necessary to add the `--microsoft` flag if you are unable to use custom keys.
Now to see if everything went succesfully run:
Set the cache-file of the ZFS pool.
```
# zpool set cachefile=/etc/zfs/zpool.cache tank
```
Now to see if everything went successfully, run:
```
# apk fix kernel-hooks
@ -124,7 +127,7 @@ Now to see if everything went succesfully run:
and it should give no warnings if done properly.
As discussed earlier `grub` will be replaced, install `gummiboot` as a bootloader.
To install `gummiboot` as friendly bootloader:
```
# apk add gummiboot
@ -133,28 +136,28 @@ As discussed earlier `grub` will be replaced, install `gummiboot` as a bootloade
# cp /usr/lib/gummiboot/gummibootx64.efi /esp/efi/boot/bootx64.efi
```
Sign the bootloader with `sbctl`
Sign the bootloader with `sbctl`.
```
# sbctl sign -s /esp/efi/boot/bootx64.efi
```
and also remove some remnants of `grub`.
```
# rm -rf /boot/grub
# rm -rf /etc/default
# cd /boot && unlink boot && cd ..
```
> One may verify the signed files by running `sbctl verify`, in this case `ESP_PATH=/esp` should be defined to work properly.
`gummiboot` can be configured with the file `/esp/loader/loader.conf` with which the timeout and the default OS can be specified.
```
default alpine-linux-<flavor>.efi
timeout 2
default alpine-linux-lts.efi
timeout 5
editor no
```
> Here, there should be lines explaining the setup of automatic decryption with TPM using Clevis. Which is still in development...
```
# clevis encrypt tpm2 '{}' << ''
```
Before finishing the installation `networkmanager` will be installed for networking. Also install `networkmanager-wifi` and `wpa_supplicant` for Wi-Fi functionality.
```
@ -163,16 +166,15 @@ Before finishing the installation `networkmanager` will be installed for network
# rc-update add networkmanager default
```
Wi-Fi will not yet work. For Wi-Fi configuration see the [network section](post-install/network).
Wi-Fi will not yet work. For Wi-Fi configuration see the network section.
> If internet does not work after reboot create the config file as described in the [network section](post-install/network) and restart the service.
> If internet does not work after reboot create the config file as described in the network section and restart the service.
Now exit the chroot and you should be able to reboot into a working Alpine system.
```
# exit
# umount -lf /mnt
# zpool export tank
# reboot
```
When booting up your screen might appear blank, this is the encryption prompt. Enter the encryption key and press enter to boot.

View file

@ -9,15 +9,24 @@ To set it up `setup-interfaces` and `setup-apkrepos` will be used.
# setup-apkrepos -c1
```
> To use wifi simply run `setup-interfaces -r` and select `wlan0` or similar.
A few packages will have to be installed first:
```
# apk add e2fsprogs cryptsetup lvm2 lsblk sgdisk wipefs dosfstools acpid
# apk add zfs lsblk sgdisk wipefs dosfstools acpid
```
and load the ZFS kernel module
```
# modprobe zfs
```
Wipe the existing disk partitions
```
# zpool labelclear -f /dev/<disk>
# wipefs -a /dev/<disk>
# sgdisk --zap-all /dev/<disk>
```
@ -41,45 +50,48 @@ Then, format the ESP with a FAT32 filesystem
# mkfs.fat -F 32 -n esp /dev/<disk>1
```
## Volume group creation
## ZFS pool creation
The root partition of the system is going to be encrypted using `cryptsetup`. First generate a key that will be used to encrypt the device and save it temporarily to the file `/tmp/luks.key` with:
The ZFS system pool is going to be encrypted. First generate an encryption key and save it temporarily to the file `/tmp/tank.key` with:
```
# cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1 > /tmp/luks.key && cat /tmp/luks.key
# cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1 > /tmp/tank.key && cat /tmp/tank.key
```
> Later on in the guide `clevis` will be used for automatic decryption. So, this key only has to be entered a few times. However, if any changes are made to the BIOS or secure-boot then this key will be needed again, so make sure to write it down.
> Later on in the guide `clevis` will be used for automatic decryption, so this key only has to be entered a few times. However, if any changes are made to the bios or secureboot then this key will be needed again, so make sure to write it down.
Then format the partition using `cryptsetup`:
Create the system pool:
```
# cryptsetup luksFormat /dev/<disk>2 --type luks2 --cipher aes-xts-plain64 --hash sha512 --iter-time 4000 --key-size 512 --pbkdf argon2id
[Enter the generated key]
# cryptsetup open --type luks /dev/<disk2> luks
# zpool create -f \
-o ashift=12 \
-O canmount=off \
-O compression=lz4 \
-O acltype=posix \
-O xattr=sa \
-O dnodesize=auto \
-O atime=off \
-O normalization=formD \
-O encryption=on \
-O keyformat=passphrase \
-O keylocation=prompt \
-m none \
tank /dev/<disk2>
```
Create the LVM volume group
Then create the system datasets:
```
# vgcreate vg /dev/mapper/luks
# zfs create -o mountpoint=none tank/root
# zfs create -o mountpoint=legacy -o quota=24g tank/root/alpine
# zfs create -o mountpoint=/home -o setuid=off -o devices=off -o quota=<home-quota> tank/home
# zfs create -o mountpoint=/var -o exec=off -o setuid=off -o devices=off -o quota=16g tank/var
```
Then create partitions inside the volume group:
> Setting the `<home-quota>` depends on the total size of the pool, generally try to reserve some empty space in the pool.
Finally, export the zpool:
```
# lvcreate --name alpine_root -L 24G vg
# lvcreate --name home -L <home-quota> vg
# lvcreate --name var -L 16G vg
# lvcreate --name nix -L 32G vg
```
> Setting the `<home-quota>` depends on the total size of the volume group, generally try to reserve some empty space in the volume group.
Create the filesystems on the logical partitions:
```
for i in alpine_root home var nix; do
> mkfs.ext4 /dev/vg/$i
> done
# zpool export tank
```

View file

@ -1,5 +1,5 @@
# An Alpine Linux server installation
This guide will demonstrate how to install [Alpine Linux](https://www.alpinelinux.org/) for server application. Alpine Linux will run on a raid configured encrypted ZFS filesystem with automatic decryption using TPM. User containers will be configured with `podman` and managed with `runsvdir`.
This guide will demonstrate how to install [Alpine Linux](https://www.alpinelinux.org/) for server application. Alpine Linux will run on a raid configured encrypted ZFS filesystem with automatic decryption with TPM. User containers will be configured with podman and managed with runsvdir.
Alpine Linux makes a good base for a server because of its simplicity, lightweightness and security. Check out the [Alpine Linux wiki](https://wiki.alpinelinux.org/wiki/Main_Page) for additional resources and information.

View file

@ -2,36 +2,38 @@
To install the Alpine Linux distribution on the system, the datasets of the system pool and the EFI partitions have to be mounted to the main system.
First import and decrypt the system pool:
First import and decrypt the system pool.
```
# zpool import -N -R /mnt rpool
# zfs load-key -L file:///tmp/rpool.key rpool
# zpool import -N -R /mnt tank
# zfs load-key -L file:///tmp/tank.key tank
```
Mount the datasets in the system pool and decrypt the home dataset:
Mount the datasets in the system pool and decrypt the home dataset.
```
# mount rpool/root/alpine /mnt -t zfs -o noatime
# zfs mount rpool/home
# zfs mount rpool/var
# zfs mount tank/root/alpine
# zfs mount tank/home
# zfs mount tank/var
```
Mount the ESP:
Mount the ESP.
```
# mkdir /mnt/esp
# mount /dev/md/esp /mnt/esp -t vfat
```
Then install Alpine Linux:
Then install Alpine Linux.
```
# export BOOTLOADER=none
# setup-disk -m sys /mnt
```
To have a functional chroot into the system, bind the system process directories:
> This will also add `grub` as bootloader which will be replaced but for now it will reside on the ESP.
To have a functional chroot into the system, bind the system process directories.
```
# for dir in dev proc sys run; do
@ -65,7 +67,7 @@ clock_hctosys="NO"
clock_systohc="NO"
```
Configure the ESP raid array to mount:
Configure the ESP raid array to mount.
```
# modprobe raid1
@ -75,52 +77,61 @@ Configure the ESP raid array to mount:
# rc-update add mdadm-raid boot
```
Configure ZFS to mount:
Configure ZFS to mount.
```
rc-update add zfs-import sysinit
rc-update add zfs-mount sysinit
rc-update add zfs-load-key sysinit
```
> If a faster boot time is preferred, `zfs-import` and `zfs-load-key` can be omitted in certain cases.
Edit `/etc/fstab` for correct mounts:
```
/dev/md/esp /esp vfat defaults,nodev,nosuid,noexec 0 2
tmpfs /tmp tmpfs rw,nodev,nosuid,noexec,mode=1777 0 0
proc /proc proc nodev,nosuid,noexec,hidepid=2 0 0
/dev/md/esp /esp vfat defaults,nodev,nosuid,noexec 0 2
tmpfs /tmp tmpfs rw,size=4G,nr_inodes=5k,nodev,nosuid,noexec,mode=1777 0 0
proc /proc proc nodev,nosuid,noexec,hidepid=2 0 0
```
Install the following packages to make `mkinitfs` compatible with secureboot and TPM decryption:
By default, Alpine Linux uses `mkinitfs` to create an initial ram filesystem, although it is minimal that also means that it lacks some functionality which is needed for a proper setup. Because of this `mkinitfs` and `grub-efi `will be replaced with `booster` and `secureboot-hook`.
```
# apk add secureboot-hook sbctl tpm2-tools zlevis
# apk add booster secureboot-hook sbctl
# apk del mkinitfs grub-efi
```
Configure `/etc/mkinitfs/mkinitfs.conf` to disable trigger and to add the `zlevis-hook`:
To configure booster edit `/etc/booster.yaml`:
```
features="... zlevis"
disable_trigger="yes"
enable_zfs: true
busybox: false
modules: vfat,nls_cp437,nls_iso8859_1
```
> The `mkinitfs` package that supports `zlevis` is as of this moment not yet in the alpine package repository, for the relevant steps see the [zlevis mkinitfs-implementation wiki](https://git.bijl.us/luc/zlevis/wiki/mkinitfs-implementation).
The most important step is the creation of a UKI using `secureboot-hook` which also automatically signs them. Configure `/etc/kernel-hooks.d/secureboot.conf` to set kernel cmdline options and secureboot:
The most important step is the creation of a UKI using `secureboot-hook` which also automatically signs them. First the hook itself will have to be tweaked to use `booster` instead of `mkinitfs`, edit `/etc/kernel-hooks.d/50-secureboot.hook` and change the line:
```
cmdline="rw root=ZFS=rpool/root/alpine rootflags=noatime quiet splash"
/sbin/mkinitfs -o "$tmpdir"/initramfs "$NEW_VERSION-$FLAVOR"
```
signing_cert="/var/lib/sbctl/keys/db/db.pem"
signing_key="/var/lib/sbctl/keys/db/db.key"
to:
```
/usr/bin/booster build "$tmpdir"/initramfs --kernel-version "$NEW_VERSION-$FLAVOR"
```
and configure `/etc/kernel-hooks.d/secureboot.conf` for cmdline and secureboot.
```
cmdline="rw zfs=tank/root/alpine quiet splash"
signing_cert="/usr/share/secureboot/keys/db/db.pem"
signing_key="/usr/share/secureboot/keys/db/db.key"
output_dir="/esp/efi/linux"
output_name="alpine-linux-{flavor}.efi"
```
Use `sbctl` to create secureboot keys and sign them:
Use `sbctl` to create secureboot keys and sign them.
```
# sbctl create-keys
@ -129,10 +140,10 @@ Use `sbctl` to create secureboot keys and sign them:
> Whilst enrolling the keys it might be necessary to add the `--microsoft` flag if you are unable to use custom keys.
Set the cache-file of the ZFS pool:
Set the cache-file of the ZFS pool.
```
# zpool set cachefile=/etc/zfs/zpool.cache rpool
# zpool set cachefile=/etc/zfs/zpool.cache tank
```
Now to see if everything went successfully, run:
@ -143,7 +154,7 @@ Now to see if everything went successfully, run:
and it should give no warnings if done properly.
To install `gummiboot` as friendly bootloader:
As discussed earlier `grub` will be replaced, install `gummiboot` as a bootloader.
```
# apk add gummiboot
@ -152,7 +163,7 @@ To install `gummiboot` as friendly bootloader:
# cp /usr/lib/gummiboot/gummibootx64.efi /esp/efi/boot/bootx64.efi
```
Sign the bootloader with `sbctl`:
Sign the bootloader with `sbctl`.
```
# sbctl sign -s /esp/efi/boot/bootx64.efi
@ -160,7 +171,15 @@ Sign the bootloader with `sbctl`:
> One may verify the signed files by running `sbctl verify`, in this case `ESP_PATH=/esp` should be defined to work properly.
`gummiboot` can be configured with the file `/esp/loader/loader.conf` with which the timeout and the default OS can be specified:
Remove some remnants of `grub`.
```
# rm -rf /boot/grub
# rm -rf /etc/default
# cd /boot && unlink boot && cd ..
```
`gummiboot` can be configured with the file `/esp/loader/loader.conf` with which the timeout and the default OS can be specified.
```
default alpine-linux-lts.efi
@ -168,11 +187,13 @@ timeout 2
editor no
```
> Here, there should be lines explaining the setup of automatic decryption with TPM using Clevis. Which is still in development...
Now exit the chroot and you should be able to reboot into a working Alpine system.
```
# exit
# umount -lf /mnt
# zpool export rpool
# zpool export tank
# reboot
```

View file

@ -7,18 +7,12 @@ https://dl-cdn.alpinelinux.org/alpine/latest-stable/main
https://dl-cdn.alpinelinux.org/alpine/latest-stable/community
```
This will use the latest stable repository of Alpine (for example `v3.19`). To use a different version of Alpine simply change `latest-stable` to whatever version you want. Do note that you can not (easily) downgrade your system's version. There also is the `edge` repository which contains the latest packages but it is not recommended because it can result in faster breakage of your system.
This will use the latest stable repository of Alpine (for example `v3.19`). To use a different version of Alpine simply change `latest-stable` to whatever version you want. Do note that you can not (easily) downgrade your system's version. There also is the `edge` repository which contains more packages but it is not recommended because it can result in faster breakage of your system.
If a package is not yet in a stable release one may configure in `/etc/apk/repositories`:
## apk-ample
We also host our own repository which contains some packages not found in the stable repository but also our own packages like `linux-hardened`. If you want to add it to your system edit `/etc/apk/repositories` and add this line under the other repositories:
```
@<repository> https://dl-cdn.alpinelinux.org/alpine/edge/<repository>
https://git.bijl.us/lnco/apk-ample/raw/branch/main/alpine/
```
for the relevant `<repository>` and perform:
```
# apk add <package>@<repository>
```
for the relevant `<package>`.

View file

@ -7,7 +7,7 @@ ZFS opens up new methods to safely update the system. These methods are describe
To be able to rollback the system after a system update one may create a snapshot of the root filesystem.
```
# zfs snapshot rpool/root/alpine@previous
# zfs snapshot tank/root/alpine@previous
```
> Tip:`zfs list -t snapshot` can be used to list snapshost and `zfs destroy` can be used to remove snapshots.
@ -24,7 +24,7 @@ Perform a system update.
If the system does not behave accordingly after reboot, one may rollback to the previous snapshot.
```
# zfs rollback -r rpool/root/alpine@previous
# zfs rollback -r tank/root/alpine@previous
```
## Post-update
@ -32,7 +32,7 @@ If the system does not behave accordingly after reboot, one may rollback to the
To maintain the performance of the SSDs in the system, perform a trim on the zfs-pool.
```
# zpool trim --secure --wait rpool
# zpool trim --secure --wait tank
```
> Some devices may not support the option `--secure`.
@ -40,13 +40,13 @@ To maintain the performance of the SSDs in the system, perform a trim on the zfs
Thereafter, perform a scrub on the zfs-pool which checks and repairs the data in the pool.
```
# zpool scrub rpool
# zpool scrub tank
```
This may take a while, the progress can be checked with:
```
# zpool status rpool
# zpool status tank
```
> A ZFS scrub only repairs if mirror or a zraid mode is set in the pool.

View file

@ -1,8 +1,6 @@
# Provisioning
Flash the Alpine Linux extended ISO and make sure the secureboot keys are reset and TPM is enabled in the BIOS of the host.
After booting the Alpine Linux extended ISO, partition the disks. For this action internet is required since `zfs`, `sgdisk` and various other necessary packages are not included on the extended ISO, therefore they need to be obtained from the alpine package repository.
After flashing the Alpine Linux extended ISO, partition the disks. For this action internet is required since `zfs` and `sgdisk` are not included on the extended ISO, therefore it needs to be obtained from the repository.
To set it up `setup-interfaces` and `setup-apkrepos` will be used.
@ -11,23 +9,19 @@ To set it up `setup-interfaces` and `setup-apkrepos` will be used.
# setup-apkrepos -c1
```
> To use Wi-Fi simply run `setup-interfaces -r` and select `wlan0` or similar.
A few packages will have to be installed first,
A few packages will have to be installed first:
```
# apk add zfs lsblk sgdisk wipefs dosfstools acpid mdadm zlevis
# apk add zfs lsblk sgdisk wipefs dosfstools acpid mdadm
```
> The `zlevis` package is as of this moment not yet in the alpine package repository. Try to get it into the `/usr/bin` directory via a different method and add its dependencies `tpm2-tools` and `jose`.
and load the ZFS kernel module
```
# modprobe zfs
```
Define the disks you want to use for this install,
Define the disks you want to use for this install
```
# export disks="/dev/disk/by-id/<id-disk-1> ... /dev/disk/by-id/<id-disk-n>"
@ -37,7 +31,7 @@ with `<id-disk-n>` for $n \in \mathbb{N}$ the `id` of the disk.
> According to [openzfs-FAQ](https://openzfs.github.io/openzfs-docs/Project%20and%20Community/FAQ.html) using `/dev/disk/by-id/` is the best practice for small pools. For larger pools, using serial Attached SCSI (SAS) and the like, see [vdev_id](https://openzfs.github.io/openzfs-docs/man/master/5/vdev_id.conf.5.html) for proper configuration.
Wipe the existing disk partitions:
Wipe the existing disk partitions
```
# for disk in $disks; do
@ -47,7 +41,7 @@ Wipe the existing disk partitions:
> done
```
Create on each disk an `EFI system` partition (ESP) and a `Linux filesystem` partition:
Create on each disk an `EFI system` partition (ESP) and a `Linux filesystem` partition
```
# for disk in $disks; do
@ -56,13 +50,13 @@ Create on each disk an `EFI system` partition (ESP) and a `Linux filesystem` par
> done
```
Create device nodes:
Create device nodes
```
# mdev -s
```
Define the EFI partitions:
Define the EFI partitions
```
# export efiparts=""
@ -72,7 +66,7 @@ Define the EFI partitions:
> done
```
Create a `mdraid` array on the EFI partitions:
Create a `mdraid` array on the EFI partitions
```
# modprobe raid1
@ -80,7 +74,7 @@ Create a `mdraid` array on the EFI partitions:
# mdadm --assemble --scan
```
Format the array with a FAT32 filesystem:
Format the array with a FAT32 filesystem
```
# mkfs.fat -F 32 /dev/md/esp
@ -98,15 +92,15 @@ Define the pool partitions
> done
```
The ZFS system pool is going to be encrypted. First generate an encryption key and save it temporarily to the file `/tmp/rpool.key` with:
The ZFS system pool is going to be encrypted. First generate an encryption key and save it temporarily to the file `/tmp/crypt-key.txt` with:
```
# cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1 > /tmp/rpool.key && cat /tmp/rpool.key
# cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1 > /tmp/tank.key && cat /tmp/tank.key
```
> While `zlevis` will be used for automatic decryption, if any changes are made to the bios or secureboot then this key will be needed, so make sure to save it.
> Later on in the guide `clevis` will be used for automatic decryption, so this key only has to be entered a few times. However, if any changes are made to the bios or secureboot then this key will be needed again, so make sure to write it down.
Create the system pool:
Create the system pool
```
# zpool create -f \
@ -117,36 +111,26 @@ Create the system pool:
-O dnodesize=auto \
-O encryption=on \
-O keyformat=passphrase \
-O keylocation=prompt \
-O keylocation=file:///tmp/tank.key \
-m none \
rpool raidz1 $poolparts
tank raidz1 $poolparts
```
> Additionally, the `spare` option can be used to indicate spare disks. If more redundancy is preferred than `raidz2` and `raidz3` are possible [alternatives](https://openzfs.github.io/openzfs-docs/man/master/7/zpoolconcepts.7.html) for `raidz1`. If a single disk is used the `raidz` option can be left aside. For further information see [zpool-create](https://openzfs.github.io/openzfs-docs/man/master/8/zpool-create.8.html).
Then create the system datasets:
Then create the system datasets
```
# zfs create -o mountpoint=none rpool/root
# zfs create -o mountpoint=legacy -o quota=24g rpool/root/alpine
# zfs create -o mountpoint=/home -o atime=off -o setuid=off -o devices=off -o quota=<home-quota> rpool/home
# zfs create -o mountpoint=/var -o atime=off -o exec=off -o setuid=off -o devices=off -o quota=16g rpool/var
# zfs create -o mountpoint=none tank/root
# zfs create -o canmount=noauto -o mountpoint=/ -o atime=off -o quota=24g tank/root/alpine
# zfs create -o mountpoint=/home -o atime=off -o setuid=off -o devices=off -o quota=<home-quota> tank/home
# zfs create -o mountpoint=/var -o exec=off -o setuid=off -o devices=off -o quota=16g tank/var
```
> Setting the `<home-quota>` depends on the total size of the pool, generally try to reserve some empty space in the pool.
Write the encryption key to TPM with `zlevis`:
Finally, export the zpool
```
# zlevis encrypt rpool '{}' < /tmp/rpool.key
```
> We are using the default configuration settings for `zlevis encrypt` but a different configuration is possible by setting `'{}'` accordingly.
> To check if it worked, perform `zlevis decrypt rpool`.
Finally, export the zpool:
```
# zpool export rpool
# zpool export tank
```

View file

@ -1,47 +0,0 @@
It is recommended to install container manager [Distrobox](https://distrobox.it/) to install packages from other distributions like Void Linux. This can be necessary for application which are not compatible on Musl or are to annoying to compile on Gentoo. Installation is straight forward, simply add the correct USE flags and emerge the necessary packages:
``` title="/etc/portage/package.use/podman"
sys-libs/argp-standalone static-libs
net-firewall/iptables nftables
```
``` shell-session
sh# emerge -av argp-standalone app-containers/podman distrobox
```
Once it has finished installing create a container like a Void Linux container:
``` shell-session
sh$ distrobox create --name void -i ghcr.io/void-linux/void-glibc-full:latest -n void
```
Then you are able to enter the container like so:
``` shell-session
sh$ distrobox enter void
```
## Steam
Because Steam is propriatary it has been compiled against Glibc which means it can't run on Musl. Luckily a container can run it. Once in the container install the necessary packages:
``` shell-session
sh# xbps-install -S void-repo-{nonfree,multilib{,-nonfree}}
sh# xbps-install -S steam
sh$ distrobox-export --app steam
```
Because this is a different container the driver packages will also have to be installed like so:
``` shell-session
When using Intel:
sh# xbps-install -S linux-firmware-intel mesa mesa-dri vulkan-loader mesa-vulkan-intel intel-video-accel mesa-32bit mesa-dri-32bit mesa-vulkan-intel-32bit vulkan-loader-32bit
When using AMD:
sh# xbps-install -S linux-firmware-amd vulkan-loader mesa-vulkan-radeon amdvlk xf86-video-amdgpu mesa-vaapi mesa-vdpau mesa-dri vulkan-loader-32bit amdvlk-32bit mesa-32bit mesa-dri-32bit
Or when using Nvidia:
sh# xbps-install -S nvidia nvidia-opencl nvidia-libs-32bit
sh# ldconfig
```
Now you should be able to launch Steam through an application launcher like Fuzzel.

View file

@ -1,108 +0,0 @@
River is a wayland tiling window manager which is configured only using its `riverctl` interface. It is rather minimal but still remains functional. River is coded using Zig but this is by default masked on Gentoo so first unmask them:
``` title="/etc/portage/package.accept_keywords/zig"
dev-lang/zig ~amd64
app-eselect/eselect-zig ~amd64
```
And login manager is a small graphical interface providing a nice login screen for getting into a graphical session. In this guide it is assumed that River will be used as window manager and as such it will also be used as the backend for the login manager. Before emerging the necessary packages first add some USE flags for river and keywords for `gtkgreet`:
``` title="/etc/portage/package.use/river"
gui-wm/river X
gui-libs/wlroots X
x11-libs/libxkbcommon X
media-libs/libepoxy X
media-libs/libglvnd X
media-libs/mesa X
```
``` title="/etc/portage/package.accept_keywords/gtkgreet"
gui-apps/gtkgreet ~amd64
```
Then emerge River and the `greetd` components:
```
sh# emerge -av river gtkgreet greetd display-manager-init swaybg
```
Now `greetd` has to be configured to launch River with `gtkgreet`. Besides that styling `gtkgreet` can be done using css files and GTK themes and using this configuration a wallpaper which resides at `/etc/greetd/current_wallpaper.png`.
``` title="/etc/greeld/config.toml"
[terminal]
vt = 7
[default_session]
command = "river -c /etc/greetd/river.init -no-xwayland"
user = "greetd"
```
``` title="/etc/greetd/river.init"
#!/bin/sh
riverctl spawn "swaybg -m fill -i /etc/greetd/current_wallpaper.png"
riverctl spawn "GTK_THEME='Orchis-Dark-Compact' gtkgreet -l -s /etc/greetd/gtkgreet.css; riverctl exit"
```
> Make sure `/etc/greetd/river.init` is executable!
``` title="/etc/greetd/gtkgreet.css"
@import url("/etc/greetd/wal/colors-waybar.css");
* {
color: @foreground;
background-color: transparent;
font-family: "Roboto";
}
box#body {
padding: 10px;
background-color: @background;
border-radius: 2px;
}
```
``` title="/etc/greetd/environments"
dbus-run-session -- river
bash
```
``` title="/etc/greetd/wal/colors-waybar.css"
@define-color foreground #c3c4c7;
@define-color background #121320;
@define-color cursor #c3c4c7;
@define-color color0 #121320;
@define-color color1 #5D629A;
@define-color color2 #6E729D;
@define-color color3 #7E82A9;
@define-color color4 #9698AB;
@define-color color5 #9195BC;
@define-color color6 #9EA1C0;
@define-color color7 #c3c4c7;
@define-color color8 #5e6073;
@define-color color9 #5D629A;
@define-color color10 #6E729D;
@define-color color11 #7E82A9;
@define-color color12 #9698AB;
@define-color color13 #9195BC;
@define-color color14 #9EA1C0;
@define-color color15 #c3c4c7;
```
Finally configure `display-manager` to start `greetd` upon boot:
``` title="/etc/conf.d/display-manager"
CHECKVT=7
DISPLAYMANAGER="greetd"
```
Then enable the `display-manager` service to start on boot:
```
sh# rc-update add display-manager default
```
> Before enabling the `display-manager` service it is recommend to simply first start it ones to see if it works.

View file

@ -1,20 +0,0 @@
Session management is necessary for tracking and giving rights to certain users. For a functional setup install both `elogind` and `turnstile` and enable their corresponding services.
``` shell-session
sh# emerge -av elogind turnstile
sh# rc-update add elogind boot
sh# rc-update add turnstiled
```
Then configure `pam` to turnstile to track the user:
``` shell title="/etc/pam.d/system-login"
...
session optional pam_turnstile.so
```
When a user logs in it should now be able to start a graphical session. This should be done with:
``` shell-session
sh$ dbus-run-session -- <window_manager>
```

View file

@ -1 +0,0 @@
If following the guide correctly then River will have already been installed on the system with the desired USE flags which only leaves the configuration of the desktop.

View file

@ -1,5 +0,0 @@
# A Gentoo Linux Desktop installation
This guide will demonstrate how to install [Gentoo Linux](https://www.gentoo.org/) on a desktop. It is meant to be used as a quick overview of all the necessities. It is recommended to read the [Handbook](https://wiki.gentoo.org/wiki/Handbook:AMD64) before attepting this installation.
This Gentoo installation covers how to install Gentoo Musl AMD64 with UEFI secureboot on an encrypted ZFS root which will be automatically decrypted upon boot using [Zlevis](https://git.bijl.us/luc/zlevis). It will also show how to create a functional graphical session using [River](https://isaacfreund.com/software/river/).

View file

@ -1,384 +0,0 @@
Now is the time to actually install Gentoo.
First import the pool again:
``` shell-session
sh# zpool import -N -R /mnt rpool
sh# zfs load-key -L file:///tmp/rpool.key rpool
```
Then mount the datasets and the ESP on `/mnt`:
``` shell-session
sh# mount -t zfs rpool/root/gentoo /mnt
sh# mkdir /mnt/var
sh# mount -t zfs rpool/root/gentoo/var /mnt/var
sh# mkdir /mnt/efi
sh# 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.
``` shell-session
sh# cd /mnt
sh# 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 `/mnt/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:
``` shell-session
sh# 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.
``` shell-session
sh# cp /etc/resolv.conf /mnt/etc/.
sh# cp /tmp/rpool.key /mnt/tmp
sh# for i in dev proc sys run; do
> mount --rbind --make-rslave /$i /mnt/$i
> done
sh# 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:
``` title="/etc/portage/make.conf"
# 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 apparmor 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`.
``` shell-session
sh# emaint sync
...
Action: sync for repo: gentoo, returned code = 0
sh# 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`:
``` shell title="/etc/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:
``` shell-session
sh# emerge -av sys-libs/timezone-data
```
Select the correct timezone with:
``` shell title="/etc/env.d/00local"
TZ="/usr/share/zoneinfo/<region>/<city>"
```
Update the environment of your shell-session:
``` shell-session
sh# 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:
``` shell-session
sh# emerge -av net-misc/openntpd
sh# rc-update add ntpd default
sh# rc-service ntpd start
```
### Set up locales
Musl also does not support locales out of the box. They aren't necessary but some programs rely on them to set the language of their application. To be able to use locales install the `musl-locales` package:
``` shell-session
sh# emerge -av sys-apps/musl-locales
```
And to allow the system to know where the locales are located:
``` shell title="/etc/env.d/01musl_locales"
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 different one should not break the system. Choose the desired locale with $n \in \mathbb{N}$:
``` shell-session
sh# env-update && source /etc/profile
sh# eselect locale list
sh# eselect locale set <n>
```
### 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 <hostname> with the desired name:
``` shell-session
sh# 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. On top of this `dnsmasq` can be used for managing DNS queries. Before emerging them, consider adding some USE flags to your liking:
``` title="/etc/portage/package.use/network"
net-misc/networkmanager dhcpcd -wext -ppp
net-dns/dnsmasq dnssec
```
Also make sure the `networkmanager` USE flag is enabled in your `make.conf`. Then emerge `networkmananger` and `dnsmasq`:
``` shell-session
sh# emerge -av net-misc/networkmanager net-dns/dnsmasq
```
Now configure NetworkManager and Dnsmasq. This is a generally secure recommended setup:
``` title="/etc/NetworkManager/NetworkManager.conf"
[main]
hostname-mode=none
plugins=ifupdown,keyfile
dns=dnsmasq
[ifupdown]
managed=true
[device]
wifi.scan-rand-mac-address=yes
[connection-mac-randomization]
ethernet.cloned-mac-address=random
wifi.cloned-mac-address=random
```
``` title="/etc/NetworkManager/dnsmasq.d/dnssec"
dnssec
trust-anchor=.,20326,8,2,E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D
trust-anchor=.,38696,8,2,683D2D0ACB8C9B712A1948B27F741219298D0A450D612C483AF444A4C0FB2B16
dnssec-check-unsigned
```
Then disable any other network services before enabling the `NetworkManager`service:
``` shell-session
sh# 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:
``` shell-session
sh# emerge -av app-eselect/eselect-repository
sh# eselect repository enable guru
sh# emaint sync --repo guru
```
To allow unstable packages from GURU set the `~amd64` keyword for it:
``` title="/etc/portage/package.accept_keywords/guru"
*/*::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`:
``` shell-session
sh# emerge -av sbctl
```
> Verify that Secureboot mode is on and in setup mode with `sbctl status`
Then create and enroll keys into the system.
``` shell-session
sh# sbctl create-keys
Created Owner UUID abcde....
Creating secure boot keys...✔
Secure boot keys created!
sh# 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:
``` shell-session
sh# eselect repository add portage-ample git https://git.bijl.us/lnorg/portage-ample
sh# emaint sync -r portage-ample
```
Then before emerging add the `dracut` flag for zlevis:
``` title="/etc/portage/package.use/zlevis"
app-crypt/zlevis dracut
```
Then simply install it:
``` shell-session
sh# emerge -av app-crypt/zlevis
```
Now add `zlevis` to the pool with
``` shell-session
sh# 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`:
``` title="/usr/lib/kernel/install.conf"
layout=uki
initrd_generator=dracut
uki_generator=ukify
```
``` title="/etc/kernel/uki.conf"
[UKI]
SecureBootSigningTool=sbsign
```
Portage also has to be told to generate a UKI when installing a kernel. Set the corresponding required USE flags:
``` title="/etc/portage/package.use/uki"
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`:
``` title="/etc/portage/package.license"
# 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:
``` shell title="/etc/dracut.conf.d/zlevis.conf"
nofsck="yes"
add_dracutmodules+=" zlevis "
```
Before installing a kernel define a minimal kernel command line which allows the initramfs to find the root:
``` title="/etc/kernel/cmdline"
rw root=ZFS=rpool/root/gentoo quiet splash
```
Then finally install the packages mentioned which are required for a running system:
``` shell-session
sh# 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:
``` shell-session
sh# 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:
``` shell-session
sh# rc-update add zfs-import sysinit
sh# rc-update add zfs-mount sysinit
```
Now exit the chroot and unmount the filesystem with:
``` shell-session
sh# umount -lf /mnt
```
The system should be functional after a reboot!

View file

@ -1,35 +0,0 @@
`ccache` is a program which can save compiling cache, speeding up recompile's of big software. First install it:
``` shell-session
sh# emerge -av dev-util/ccache
```
And create a configuration file for `ccache`.
``` title="/etc/ccache.conf"
cache_dir = /var/cache/ccache
max_size = 20G
umask = 002
hash_dir = false
compiler_check = %compiler% -dumpversion
compression = true
compression_level = 1
```
Configure `portage` to allow `ccache` for specified packages:
``` title="/etc/portage/env/enable-ccache.conf"
FEATURES="ccache"
CCACHE_DIR="/var/cache/ccache"
```
Then for every package with which you want to use `ccache` add them:
``` title="/etc/portage/package.env/ccache"
sys-kernel/gentoo-kernel enable-ccache.conf
sys-kernel/firefox enable-ccache.conf
...
```

View file

@ -1,5 +0,0 @@
Video drivers are necessary for a graphical session to function. In Gentoo it is as simple as specifying what video card the system uses using USE flags:
``` title="/etc/portage/package.use/00video"
*/* VIDEO_CARDS: -* <amdgpu radeonsi || intel || nvidia>
```

View file

@ -1,20 +0,0 @@
Security is an important factor when it comes to an operating system. Hardening the system is done to prevent as many exploits as possible. There are multiple factors which should be considered.
## Apparmor and LSM
Apparmor is a Mandatory Access Control (MAC) system that restricts capabilities from a program on a computer. It can dissallow access to files which the program would not require. Make sure the `apparmor` USE flag is enabled and install the necessary programs:
``` shell-session
sh# emerge -av apparmor apparmor-utils
sh# rc-update add apparmor boot
```
Then add apparmor and other Linux Security Modules (LSM) to the `cmdline` and rebuild the initramfs:
``` title="/etc/kernel/cmdline"
... apparmor=1 lsm=landlock,lockdown,yama,capability,integrity,apparmor
```
``` shell-session
sh# emerge --config gentoo-kernel # or gentoo-kernel-bin etc.
```

View file

@ -1,32 +0,0 @@
Adding a user to the system is essential for actually using it as a desktop. It is pretty straight forward:
``` shell-session
sh# useradd -m -G <wheel,>plugdev,pipewire -s /bin/bash <username>
sh# passwd <username>
...
passwd: password updated successfully
```
> The `pipewire` group will not exist yet until the corresponding package is installed.
The `wheel` group should ideally only be assigned to one singular admin account. The users in the group are allowed to use the `doas` command to gain root privileges. This is necessary for installing packages and changing system files but not for a normal user.
## Doas
Installing and configuring `doas` should be done like so.
``` title="/etc/portage/package.use/doas"
app-admin/doas persist
```
> This USE flag is necessary when typing the user's password every few seconds gets to annoying.
``` shell-session
sh# emerge -av doas
```
``` title="/etc/doas.conf"
permit persist :wheel as root
```
Now users who are in the `wheel` group are allowed to use the `doas` command to gain root privileges.

View file

@ -1,107 +0,0 @@
To install Gentoo this guide will be using the Alpine Extended ISO. It provides all of the necessary utilities for bootstrapping Gentoo. Make sure to boot with secureboot in setup mode or to already have keys ready to deploy.
After booting the Alpine Linux extended ISO, partition the disks. For this action internet is required since `zfs`, `sgdisk` and various other necessary packages are not included on the extended ISO, therefore they need to be obtained from the alpine package repository.
To set it up `setup-interfaces` and `setup-apkrepos` will be used.
``` shell-session
sh# setup-interfaces -ar
sh# setup-apkrepos -c1
```
> To use Wi-Fi simply run `setup-interfaces -r` and select `wlan0` or similar.
A few packages will have to be installed first:
``` shell-session
sh# apk add zfs lsblk sgdisk wipefs dosfstools zlevis
```
> The `zlevis` package is as of this moment not yet in the alpine package repository. Try to get it into the `bin` via a different method and add its dependencies `tpm2-tools` and `jose`.
and load the ZFS kernel module:
``` shell-session
sh# modprobe zfs
```
Wipe the existing disk partitions:
``` shell-session
sh# zpool labelclear -f /dev/<disk>
sh# wipefs -a /dev/<disk>
sh# sgdisk --zap-all /dev/<disk>
```
Create on the disk an `EFI system` partition (ESP) and a `Linux filesystem` partition:
``` shell-session
sh# sgdisk -n 1:1m:+512m -t 1:ef00 /dev/<disk>
sh# sgdisk -n 2:0:-10m -t 2:8300 /dev/<disk>
```
Reload the device nodes:
``` shell-session
sh# mdev -s
```
Then, format the ESP with a FAT32 filesystem:
``` shell-session
sh# mkfs.fat -F 32 -n esp /dev/<disk>1
```
## ZFS pool creation
The ZFS system pool is going to be encrypted. First generate an encryption key and save it temporarily to the file `/tmp/rpool.key` with:
``` shell-session
sh# cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1 > /tmp/rpool.key && cat /tmp/rpool.key
```
> While `zlevis` is used for automatic decryption, this key is required when making changes are made to the BIOS or secureboot, so make sure to save it.
Create the system pool:
``` shell-session
sh# zpool create -f \
-o ashift=12 \
-O compression=lz4 \
-O acltype=posix \
-O xattr=sa \
-O dnodesize=auto \
-O encryption=on \
-O keyformat=passphrase \
-O keylocation=prompt \
-m none \
rpool /dev/<disk>2
```
Then create the system datasets:
``` shell-session
sh# zfs create -o mountpoint=none rpool/root
sh# zfs create -o mountpoint=legacy -o quota=48g rpool/root/gentoo
sh# zfs create -o mountpoint=legacy -o quota=32g rpool/root/gentoo/var
sh# zfs create -o mountpoint=/home -o atime=off -o setuid=off -o devices=off -o quota=<home-quota> rpool/home
```
> Setting the `<home-quota>` depends on the total size of the pool, generally try to reserve some empty space in the pool.
Write the encryption key to TPM with `zlevis`:
``` shell-session
sh# zlevis encrypt rpool '{}' < /tmp/rpool.key
```
> We are using the default configuration settings for `zlevis encrypt` but a different configuration is possible by setting `'{}'` accordingly.
> To check if it worked, perform `zlevis decrypt rpool`.
Finally, export the zpool:
``` shell-session
sh# zpool export rpool
```

View file

@ -8,8 +8,6 @@ theme:
- navigation.tabs
- navigation.indexes
- toc.follow
- content.code.copy
- content.code.annotate
logo: assets/lnorg-logo.png
favicon: assets/lnorg-logo.png
palette:
@ -35,14 +33,6 @@ extra:
markdown_extensions:
- pymdownx.arithmatex:
generic: true
- pymdownx.highlight:
use_pygments: true
anchor_linenums: true
line_spans: __span
pygments_lang_class: true
- pymdownx.inlinehilite
- pymdownx.snippets
- pymdownx.superfences
extra_javascript:
- javascripts/mathjax.js
@ -92,22 +82,6 @@ nav:
- 'Update protocol': alpine-server-setup/post-install/update-protocol.md
- 'Containers': alpine-server-setup/post-install/containers.md
- 'Gentoo-desktop setup':
- gentoo-desktop-setup/index.md
- 'Provisioning': gentoo-desktop-setup/provisioning.md
- 'Installation': gentoo-desktop-setup/installation.md
- 'Post installation':
- 'Firmware and drivers': gentoo-desktop-setup/post-install/drivers.md
- 'Swap': gentoo-desktop-setup/post-install/swap.md
- 'Users': gentoo-desktop-setup/post-install/users.md
- 'Ccache': gentoo-desktop-setup/post-install/ccache.md
- 'Security': gentoo-desktop-setup/post-install/security.md
- 'Graphical session':
- 'Session manager': gentoo-desktop-setup/graphical-session/session-manager.md
- 'Login manager': gentoo-desktop-setup/graphical-session/login-manager.md
- 'Window manager': gentoo-desktop-setup/graphical-session/window-manager.md
- 'Distrobox': gentoo-desktop-setup/graphical-session/distrobox.md
- 'Void-desktop setup':
- void-desktop-setup/index.md
- 'Installation with LVM':