void

  1. Foreword
  2. Internet Connectivity
  3. Disk Partitioning
  4. Boot Partitioning
  5. Encrypting Root
  6. Mounting boot and root
  7. System Installation
  8. Entering the Void
  9. Configuring fstab
  10. Configuring dracut
  11. Configuring crypttab
  12. Configuring efibootmgr
  13. Cleaning Up
  14. System Configuration
    1. Setting a Locale
    2. Setting a Hostname
    3. Adding a User
    4. Finalization
  15. First Reboot
    1. Logging In
    2. Enabling Wireless
    3. Wireless Network Access
  16. Further Reading

Foreword

This guide was written primarily as a means to help me understand Void’s chroot installation method with greater depth. Come to find out, it’s pretty much the same as installing Arch but with a few minor differences. An explanation of what each command does will preceed the command itself.

Commands in explanations will be highlighted in green

Files and directories will be highlighted in blue

Here is what the end state of this guide is.

  • Bare Minimal Install
    • Only 3 extra packages will be installed; efibootmgr, cryptsetup and nano
  • LUKS Full Disk Encryption
    • we will be utilizing cryptsetup to set up strong full disk encryption.
  • efibootmgr // efistub
    • we will be utilizing efibootmgr to set up an extremely minimal boot partition entry called an efistub supporting the above encryption
  • wpa_supplicant
    • we will be using only the small, built-in wi-fi tools wpa_supplicant and dhcpcd

Internet Connectivity

the easiest way to get online in the live environment is via the XFCE network widget on the top right. you may want to do it via wpa_cli however, as this will be what we do after installation the ip link command can be used to determine what device is going to be used with wpa_cli

$ ip link

look for the keyword link/ether in the output above, in my case it was wlp7s0

$ wpa_cli -i wlp7s0

now we’re inside the wpa_cli environment. this consists of scanning via scan and scan_results, adding a network via add_network, setting it’s properties via set_network, then activating it via select_network.

$ add_network

by default, it will create an empty network “0”, let’s configure it. let’s scan to ensure our device can find the SSID

> scan
> scan_results

# You should now see all local networks, look for yours. 
# The SSID will be the name of the wifi network. let's connect to it

> set_network 0 ssid "mywifiname" # the quotes are needed
> set_network 0 password "wifipassword" 
> set_network 0 psk "wifipassword"

# we're done configuring the network, now let's activate it.
> select_network 0

# give it a few moments, then exit the program via ctrl+c

Disk Partitioning

cfdisk is a robust ncurses utility that will let us partition the target disk to what we want. in this, we’re formatting the NVMe. remember to write these changes and exit the program once complete.

$ cfdisk /dev/nvme0n1

Your partitions should look something like:

  • 256MB EFI Partition # Hex code ef00
  • 100% Remaining Linux Filesystem partition, Hex code 8300

Boot Partitioning

We will be using mkfs.vfat to turn nvme0n1p1 (the boot partition) into a vfat partition, we will turn this to the boot partition later

$ mkfs.vfat /dev/nvme0n1p1

Encrypting Root

cryptsetup is the tool which will allow us to first encrypt /dev/nvme0n1p2 (the non-boot paritition), then subsequently unlock it for further usage. we are only targetting nvme0n1p2, as that will be the partition with all of our data later. nvme0n1p1 will not be encrypted, as it is the boot partition.

$ cryptsetup -c aes-xts-plain64 -y -s 512 luksFormat /dev/nvme0n1p2

with cryptsetup we will now be opening our newly encrypted partition and telling it to go to /dev/mapper/$ cryptroot once it’s open

$ cryptsetup luksOpen /dev/nvme0n1p2 cryptroot

now we will be using mkfs.ext4 to change the encrypted volume “cryptroot” an ext4 filesystem

$ mkfs.ext4 /dev/mapper/cryptroot

Mounting boot and root

These commands mount the newly created ext4 partition /dev/mapper/cryptroot to /mnt. this will allow us to install the system with xbps later.

$ mount /dev/mapper/cryptroot /mnt
$ mkdir /mnt/boot
$ for dir in dev proc sys run; do mkdir -p /mnt/$dir ; mount --rbind /$dir /mnt/$dir ; mount --make-rslave /$ mnt/$dir ; done


$ mount /dev/nvme0n1p1 /mnt/boot

System Installation

Now that we’ve partitioned, formatted, encrypted and booted the correct storage volumes, we’re ready to use xbps to install the system to /mnt (remember, /mnt currently has /dev/mapper/cryptroot mounted. that is the root directory for the system we’re about to install)

first, we need to copy the xbps keys from the live iso to the mounted filesystem. we’ll copy our /etc/resolv.conf as well.

$ mkdir -p /mnt/var/db/xbps/keys
$ cp /var/db/xbps/keys/* /mnt/var/db/xbps/keys/
$ cp /etc/resolv.conf /mnt/etc/
$ xbps-install -S -R https://alpha.de.repo.voidlinux.org/current -r /mnt base-system cryptsetup efibootmgr nano
Package Description
base-system includes the kernel, runit, linux etc.
cryptsetup needed to handle LUKS
efibootmgr needed to manage efistub
nano simple text editor, we will be using this later

Entering the Void

now let’s change root into the newly installed system

$ PS1='(chroot) # ' chroot /mnt/ /bin/bash

Configuring fstab

in void, we must make our own fstab entries. this is actually pretty straightforward. we only need to define 4 locations; /tmp, /root, /boot and firmware. let’s do that in nano, use ctrl+w to find keywords and navigate to them. use ctrl+x to save the document.

assuming you’ve followed the naming scheme above, ensure your fstab looks like the below

$ nano /etc/fstab
...
tmpfs /tmp tmpfs defaults,nosuid,nodev
/dev/mapper/cryptroot / ext4 rw,noatime 0 0
efivarfs /sys/firmware/efi/efivars efivarfs defaults  0 0
/dev/nvme0n1p1 /boot vfat defaults

Configuring dracut

dracut is a tool similar to mkinitcpio which will generate the initramfs used by the bootloader, in this case, efibootmgr.

enter the lines from the table below. ensure to include the spaces and quotes like below. the entry crypt is not explicitly needed unless you wish to automate the unlocking and mounting of other (non-root) encrypted devices during runit phase 1 as discussed here

$ nano /etc/dracut.conf.d/30.conf
...
hostonly="yes"
use_fstab="yes"
install_items+=" /etc/crypttab "
add_drivers+=" vfat "
add_dracutmodules+=" crypt "

Configuring crypttab

fstab draws from crypttab, as we’ve told fstab to map cryptoot as the root drive, we must actually tell the system what “cryptroot” is, we will do this below

first, we must get the UUID of nvme0n1p2, which is our encrypted root drive. we can do this with the command below

# outputs all block ID's including UUID's
$ lsblk -f

# now let's put the target UUID in crypttab
$ nano /etc/crypttab
...
# replace "asdfjkl-1234" with whatever your UUID is
cryptroot UUID=asdfjkl-1234 none luks

Configuring efibootmgr

Configuring efibootmgr kernel hooks we’re almost done, now let’s make the file the efibootmgr will refer to when we update our system. this last file ties everything together and allows the bootloader to function

make sure your file looks like the one below. replace “asdfjkl-1234” with your actual UUID.

$ nano /etc/default/efibootmgr-kernel-hook 
...
MODIFY_EFI_ENTRIES=1
OPTIONS="quiet loglevel=0 rd.luks.name=asdfjkl-1234=cryptroot root=/dev/mapper/cryptroot"
DISK="/dev/nvme0n1"
PART=1

Cleaning Up

the final step is to create some symlinks and appending a few files to ensure runit doesn’t double mount partitions as we defined above. do the following.

$ ln -s /etc/fstab /etc/fstab.sys
$ mv /etc/runit/core-services/03-filesystems.sh{,.bak}
$ echo noextract=/etc/runit/core-services/03-filesystems.sh > /etc/xbps.d/xbps.conf 

System Configuration

Setting a Locale

Now we’re going to symbolically link the timezone in /usr/share/zoneninfo to our /etc/localtime. US Central Time. use tab in /zoneinfo/ to more quickly find your appropriate locale

$ ln -sf /usr/share/zoneinfo/America/Chicago /etc/localtime

Now we’re going to use nano to set your locale. use ctrl+w to find your locale and uncomment it, ctrl+x to save.

$ nano /etc/default/libc-locales

These will append locale settings to /etc/locale.conf. the >> mark means append, not write over.

$ echo LANG=en_US.UTF-8 >> /etc/locale.conf
$ xbps-reconfigure -f glibc-locales

Setting a Hostname

Now we will use echo to write the input to the pointed file. one > means write over. Let’s set the hostname.

$ echo MYHOSTNAME > /etc/hostname

Adding a User

Now let’s create your user as well as set the root user’s password. It’s generally a good idea to have a root password set even if you never plan on logging into it as a means to reset your own user’s password should something go awry. After each passwd command with a username entered, it’ll prompt you for a password. If you do not wish to set a root password, skip that last line.

$ useradd -mG wheel USERNAMEHERE
$ EDITOR=nano visudo
$ passwd USERNAMEHERE
$ passwd root

Finalization

this command will write all settings we did above with fstab, crypttab, dracut and efiboot

$ xbps-reconfigure -fa

now you may exit the chroot environment and restart the machine.

# exits the chroot
$ exit
# unmounts everything we have mounted
$ umount -R /mnt
# self explanitory
$ reboot

First Reboot

Log In

This will be the username and password we set earlier with useradd.

Enabling Wireless

let’s set up wpa_supplicant as well it’s backend services. we will be setting up the appropriate daemons, and making the wpa_supplicant settings persistent

before we can use wpa_cli, we must first enable wpa_supplicant and dhcpcd as services in runit, void’s init. to enable a service in runit, we must first make a symlink from /etc/sv/ to /var/service and utilize the sv command to turn them on.

$ ln -s /etc/sv/dhcpcd /var/service
$ ln -s /etc/sv/wpa_supplicant /var/service
$ sv up dhcpcd
$ sv up wpa_supplicant

Wireless Network Access

the ip link command can be used to determine what device is going to be used with wpa_cli

$ ip link
# look for the keyword link/ether in the output above, in my case it was wlp7s0
$ wpa_cli -i wlp7s0
# now we're inside the wpa_cli environment.  
> add_network
# by default, it will create an empty network "0", let's configure it. let's scan to ensure our device can find the SSID
> scan
> scan_results
# you should now see all local networks, look for yours. the SSID will be the name of the wifi network. let's connect to it
> set_network 0 ssid "mywifiname" the quotes are needed
> set_network 0 password "wifipassword" 
> set_network 0 psk "wifipassword" 

Now that we’ve finished configuring the network, let’s activate it using the command below

> select_network 0

Give it a few moments, then exit the program and ping a website to verify the config works

Upon verification that it’s a good config, re-enter wpa_cli and enter save_config to save the config, this will persist through restarts and require no further changing unless you change your SSID/wireless password.


Further Reading

Now that you have a functioning void system, perhaps look at

XBPS Package Management

Cryptsetup, Encryption and Password Best Practices