Skip to content

Instantly share code, notes, and snippets.

@adamarbour
Last active July 20, 2024 12:20
Show Gist options
  • Save adamarbour/257a9f06afca6549d4bad483722e7de9 to your computer and use it in GitHub Desktop.
Save adamarbour/257a9f06afca6549d4bad483722e7de9 to your computer and use it in GitHub Desktop.
Lenovo z13 Void Linux Field Notes

Void Linux Field Notes (Lenovo z13 Edition)

This contains the notes from my installation of Void Linux onto my Lenovo z13 (gen1) laptop1 with the following specs:

  • AMD Ryzen™ 7 PRO 6860Z
  • 13.3" 2.8K (2880 x 1800) OLED
  • 32 GB LPDDR5 6400MHz
  • Integrated AMD Radeon™ 680M Graphic
  • WiFi 6E 802.11AX
  • WWAN Fibocom L860-GL-16 4G CAT16

Notes about this installation:

  • ZFS on Root
  • ZFSBootMenu
  • zram swap + s0 sleep (no hibernation - i never use it)
  • Sanoid + httm for ZFS Time Machine
  • S6/66 for service management
  • Zen kernel

NOTE: Most of this installation is opinionated and you can freel free to adapt it to your needs.

Preparation (pre-bootstrap)

# Enter the bash shell
bash

# Set the device we will use (i.e. /dev/nvme0n1)
DEVICE=/dev/nvme0n1

xbps-install -Su xbps

# Clear the disk
wipefs -a $DEVICE
blkdiscard -f $DEVICE
cfdisk $DEVICE

## Partition layout
# +256MiB	EFI
# --		Solaris root
####

# ROOTFS - zpool
modprobe zfs
zpool create -f -o ashift=12 \
 -O compression=lz4 \
 -O acltype=posixacl \
 -O xattr=sa \
 -O relatime=on \
 -o autotrim=on \
 -m none zroot "$DEVICE"p2
 
zfs create -o mountpoint=none zroot/DATA
zfs create -o mountpoint=none zroot/ROOT
zfs create -o mountpoint=/ -o canmount=noauto zroot/ROOT/default

zfs create -o mountpoint=/home zroot/DATA/home
zfs create -o mountpoint=/root zroot/DATA/home/root

zpool export zroot
zpool import -d /dev/disk/by-id -R /mnt zroot -N

zfs mount zroot/ROOT/default
zpool set bootfs=zroot/ROOT/default zroot
zpool set cachefile=/etc/zfs/zpool.cache zroot

zfs mount -a
mkdir -p /mnt/etc/zfs
cp /etc/zfs/zpool.cache /mnt/etc/zfs/zpool.cache

# EFI - vfat
mkfs.vfat -F32 -n EFI "$DEVICE"p1
mount -m -L EFI /mnt/boot/efi

Bootstrap

XBPS_ARCH=x86_64-musl xbps-install \
  -S -R https://mirrors.servercentral.com/voidlinux/current/musl \
  -r /mnt base-system
  
zgenhostid -f 0x00bab10c
cp /etc/hostid /mnt/etc

Preconfigure

xchroot /mnt /bin/bash

xbps-install -Sy zfs sanoid terminus-font void-repo-nonfree wireless_tools curl efibootmgr

HOSTNAME=localhost
TZ=UTC
LOCAL_USER=dummy

### User Account Setup
# Create an entry for anyone in the wheel group and then add a new user to the system.
echo "%wheel ALL=(ALL:ALL) NOPASSWD: ALL" > /etc/sudoers.d/01_wheel && \
useradd -m -g users -G wheel -s /bin/bash $LOCAL_USER
usermod -aG video,audio,users,xbuilder $LOCAL_USER
passwd $LOCAL_USER

# Setup hostname
sed -i 's/^#HOSTNAME=.*$/HOSTNAME="'$HOSTNAME'"/' /etc/rc.conf

# Set timezone
ln -sf /usr/share/zoneinfo/$TZ /etc/localtime
hwclock --systohc

# Setup locale
sed -i 's/^#KEYMAP=.*$/KEYMAP="us"/' /etc/rc.conf
sed -i 's/^#FONT=.*$/FONT="ter-132b"/' /etc/rc.conf
echo -e 'export LANG=en_US.UTF-8\nexport LC_COLLATE=C' > /etc/locale.conf

# Fonts
ln -s /usr/share/fontconfig/conf.avail/70-no-bitmaps.conf /etc/fonts/conf.d/ && \
xbps-reconfigure -f fontconfig

# ZRAM - swap
echo zram > /etc/modules-load.d/zram.conf

## /etc/udev/rules.d/99-zram.rules
ACTION=="add", KERNEL=="zram0", ATTR{comp_algorithm}="zstd", ATTR{disksize}="4G", RUN="/usr/bin/mkswap -U clear /dev/%k"

fstab

NOTE: There are some manual file manipulations here

# I manually wrote the file ... 

## /etc/fstab
/dev/nvme0n1p1		/boot/efi	vfat	fmask=0077,errors=remount-ro	0 0
/dev/zram0		none		swap	defaults,pri=100		0 0
tmpfs			/tmp		tmpfs	defaults,nosuid,nodev		0 0

initram

## /etc/dracut.conf.d/local.conf
hostonly=yes
compress="lz4"
nofsck="yes"
early_microcode=yes
show_modules=yes

add_dracutmodules+=" zfs "
omit_dracutmodules+=" btrfs resume "

dracut -f --regenerate-all

zfsbootmenu

DEVICE=/dev/nvme0n1

zfs set org.zfsbootmenu:commandline="quiet loglevel=3" zroot/ROOT

mkdir -p /boot/efi/EFI/ZBM
curl -o /boot/efi/EFI/ZBM/VMLINUZ.EFI -L https://get.zfsbootmenu.org/efi
efibootmgr -c -d $DEVICE -L "ZFSBootMenu" -l '\EFI\ZBM\VMLINUZ.EFI'

exit

Wrapping it up...

swapoff -a
umount -R /mnt
zpool export zroot

reboot

Footnotes

  1. https://download.lenovo.com/pccbbs/mobiles_pdf/z13_z16_gen1_hmm_en.pdf

Making shell great again! (zsh)

Proper timing ... poorly worded. It's all about the bloating of zsh...

Dotfile Magic ...

# Setup dotbot ...
curl -fsSLO https://raw.githubusercontent.com/Vaelatern/init-dotfiles/master/init_dotfiles.sh
chmod +x ./init_dotfiles.sh
./init_dotfiles.sh

Zsh ... (z-s-h)

xbps-install zsh
$ chsh -s /bin/zsh

Void httm

This is about getting the ultimate backup process running using zfs, sanoid, and my new favorite httm (hot tub time machine).

/TODO

Switching Runit out for Sixty-six (S6)

1Sixty-six is a collection of system tools built around s6 and s6-rc created to make the implementation and manipulation of service files on your machine easier. It is meant to be a toolbox for the declaration, implementation and administration of services where separate programs can be joined to achieve powerful functionality with small amounts of code.

-- Project Page

Install the unofficial void-unofficial-repo-66 repo

xbps-install -Sy --repository=https://avyssos.eu/repos/voidlinux/66/ void-unofficial-repo-66

# Install the required packages
xbps-install -S boot-66serv void-66-services s6-rc

Configure the boot tree

We will use the scripts/automated way because ... its better :)

66boot-initial-setup # NOTE: There will be some warnings because we are using zfs and zswap. That will be taken care of next.
66boot-storage-autoconf
66boot-rcdotconf

# Enable the boot tree
66-enable -t boot -F boot@system

Switch init temporarily

zfs set org.zfsbootmenu:commandline="quiet loglevel=3 init=/usr/bin/66" zroot/ROOT

# NOTE: Modify the /etc/66rc.conf if you need to make changes and rerun '66-enable -t boot -F boot@system'

reboot

If it worked, switch permanently

# Enable the runit wrapper service tree
66-enable -t runit -S runit-wrapsv@x

xbps-install -S 66-void

# No longer need the init parameter
zfs set org.zfsbootmenu:commandline="quiet loglevel=3" zroot/ROOT

xbps-install -S base-system-66

Footnotes

  1. https://web.obarun.org/software/66/v0.6.0.0/

Post Install Configuration

This contains a misc set of notes that I followed when configuring my system... lots of opinion.

Secure Boot... or something

xbps-install sbctl
sbctl create-keys
sbctl enroll-keys -im

sbctl sign -s /boot/efi/EFI/ZBM/VMLINUZ.EFI

Setup default tree services

NOTE: You may have to install the corresponding package but this is what I am using...

xbps-install dbus cronie acpid
66-enable -t default dbus
66-enable -t default cronie
66-enable -t default acpid

Setup a Network tree

# Planning on using NetworkManager but you can use what you like...
xbps-install NetworkManager

/ TODO: Add dropbear and firewall config here ...

# Create the tree an set it to start after the default tree
66-tree -nE network
66-enable -t network NetworkManager
66-tree -S default network

ZFS maintenance DIY (cron)

## /etc/cron.monthly/zpool_scrub -- File contents below
#!/bin/bash

pools=$(zpool list -H -o name)

for pool in $pools; do
    scrub_status=$(zpool status $pool | grep "scrub in progress")
    if [ -z "$scrub_status" ]; then
        echo "Starting scrub on pool $pool"
        zpool scrub -w $pool
    else
        echo "Scrub already in progress on pool $pool"
        zpool wait -t scrub $pool
    fi
done

## /etc/cron.monthly/zpool_trim -- File contents below
#!/bin/bash

pools=$(zpool list -H -o name)

for pool in $pools; do
    trim_status=$(zpool status $pool | grep "trimming")
    if [ -z "$trim_status" ]; then
        echo "Starting trim on pool $pool"
        zpool trim -w $pool
    else
        echo "Trim already in progress on pool $pool"
        zpool wait -t trim $pool
    fi
done

chmod +x /etc/cron.monthly/zpool_trim
chmod +x /etc/cron.monthly/zpool_scrub

Dodging elogind

Don't ask me why ... because I want to

xbps-install seatd dumb_runtime_dir
66-enable -t default seatd

LOCAL_USER=dummy # Set your user that you created earlier
usermod -aG _seatd $LOCAL_USER

GPG + SSH Socket + Tokens

I use physical tokens for my authentication where I can ....

xbps-install gnupg gnupg2-scdaemon

/ TODO

Graphics (xorg) - DWM

xbps-install xorg-minimal xorg-fonts mesa-dri vulkan-loader mesa-vulkan-radeon xf86-video-amdgpu mesa-vaapi mesa-vdpau xorg-input-drivers libX11-devel
@adamarbour
Copy link
Author

adamarbour commented Jul 9, 2024

Thanks for posting this @adamarbour . May I ask if this successfully enabled Secure Boot?

Yes - you can use sbctl to generate your own keys and enroll them. Dracut can utilize those keys to sign a unified kernel image to get secure boot.

...and unattended boot with TPM2 for you?

No - unfortunately this is something that is tightly integrated with the systemd-crypt-enroll functionality that I have not dissected.

However, you could use Clevis to enroll keys into TPM but its a bit outdated and you could use Booster as the initram generator if you really needed it.

I've switched to ZFS on root now and use ZFS native encryption on my home directory and unlock it at login using the PAM module. This leaves all but my personal files unencrypted which is a nice compromise.

@adamarbour
Copy link
Author

adamarbour commented Jul 10, 2024

@dfd - just to add to this. I updated this with an example of using sbctl for enrolling and signing. Below is what you would add to your dracut conf to get it to produce a unified kernel.

xbps-install gummiboot-efistub

# In the /etc/dracut.conf.d/*** file
uefi=yes
uefi_stub=/usr/lib/gummiboot/linuxx64.efi.stub
uefi_secureboot_cert=/usr/share/secureboot/keys/db/db.pem
uefi_secureboot_key=/usr/share/secureboot/keys/db/db.key

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment