Compare commits
2 commits
main
...
zfs-deskto
Author | SHA1 | Date | |
---|---|---|---|
|
b8e473b64f | ||
|
440a2b9dce |
22 changed files with 190 additions and 967 deletions
|
@ -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.
|
||||
|
|
|
@ -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.
|
|
@ -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
|
||||
```
|
||||
|
|
|
@ -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.
|
|
@ -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
|
||||
```
|
|
@ -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>`.
|
|
@ -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.
|
|
@ -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
|
||||
```
|
|
@ -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.
|
|
@ -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.
|
|
@ -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>
|
||||
```
|
|
@ -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.
|
|
@ -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/).
|
|
@ -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!
|
||||
|
|
@ -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
|
||||
...
|
||||
```
|
||||
|
|
@ -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>
|
||||
```
|
|
@ -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.
|
||||
```
|
|
@ -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.
|
|
@ -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
|
||||
```
|
26
mkdocs.yml
26
mkdocs.yml
|
@ -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':
|
||||
|
|
Loading…
Reference in a new issue