Common Void Linux Setup

May 22 2026
Home | Hardware Guides
Public Domain · No Babies

@ Update the System

Update all packages:

sudo xbps-install -Su

@ Install Intel Microcode Updates

Install the intel-ucode package and regenerate initrmfs per the Void Handbook (this example assumes you are running Linux kernel 6.6.z):

sudo xbps-install -S void-repo-nonfree
sudo xbps-install -S intel-ucode
sudo xbps-reconfigure --force linux6.6

@ Install Development Tools

For example:

sudo xbps-install -S clang git make zig

@ Install Xorg

Install X and the Mesa OpenGL library:

sudo xbps-install -S xorg-minimal libX11-devel libXft-devel libXinerama-devel freetype-devel mesa

Install some recommended fonts:

sudo xbps-install -S freefont-ttf google-fonts-ttf liberation-fonts-ttf nerd-fonts noto-fonts-ttf xorg-fonts

Per the Void Linux Handbook, disable bitmap fonts:

sudo ln -s /usr/share/fontconfig/conf.avail/70-no-bitmaps.conf /etc/fonts/conf.d/
sudo xbps-reconfigure -f fontconfig

Then exit and restart your X session if you are already running one.

Many PDFs (such as financial statements) cannot render properly with the default fonts and the ones in the previous section. You have to configure font replacements so that programs use your fonts instead of common but non-free ones like Arial.

Run Firefox. In the URI bar, enter "about:config" and find the gfx.font_rendering.fontconfig.max_generic_substitutions setting and set it to 127. (It defaults to a low number like 3.) This allows Firefox to use more substitute fonts.

$HOME/.config/fontconfig/fonts.conf is an XML file that configures Fontconfig. Among other things, it can specify substitute fonts. Here is my fonts.conf:

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<fontconfig>
	<description>my font settings</description>
	<alias>
		<family>Arial</family>
		<prefer>
			<family>Liberation Sans</family>
			<family>DejaVu Sans</family>
		</prefer>
	</alias>
	<alias>
		<family>Arial MT</family>
		<prefer>
			<family>Liberation Sans</family>
			<family>DejaVu Sans</family>
		</prefer>
	</alias>
	<alias>
		<family>ArialMT</family>
		<prefer>
			<family>Liberation Sans</family>
			<family>DejaVu Sans</family>
		</prefer>
	</alias>

	<alias>
		<family>Times New Roman</family>
		<prefer>
			<family>Liberation Serif</family>
			<family>DejaVu Serif</family>
		</prefer>
	</alias>
	<alias>
		<family>Times New Roman MT</family>
		<prefer>
			<family>Liberation Serif</family>
			<family>DejaVu Serif</family>
		</prefer>
	</alias>
	<alias>
		<family>TimesNewRomanMT</family>
		<prefer>
			<family>Liberation Serif</family>
			<family>DejaVu Serif</family>
		</prefer>
	</alias>
	<alias>
		<family>TimesNewRomanPSMT</family>
		<prefer>
			<family>Liberation Serif</family>
			<family>DejaVu Serif</family>
		</prefer>
	</alias>
</fontconfig>

@ Install Other Packages

I installed these packages:

sudo xbps-install -S exfatprogs firefox gnupg lynx neovim signify wget xterm xz

@ Install dwm

Download the latest dwm release. As of this writing, the latest is 6.6, so the download is:

wget https://dl.suckless.org/dwm/dwm-6.6.tar.gz

Alternatively, clone the git(1) repo:

git clone https://git.suckless.org/dwm

Change config.def.h as you like. I changed the terminal from "st" to "/usr/bin/xterm".

When you are done changing the source, build it:

make dwm

If you do not have gcc(1), change "CC" in Makefile to another compiler, such as /usr/bin/clang.

Install the dwm executable file wherever you want. Remember its path. In my case, I put it in $HOME/bin.

Put the full path to the dwm executable file (where you installed it) into $HOME/.xinitrc. For example, mine looks like this:

exec /home/myuser/bin/dwm

startx(1) should load dwm.

@ Configure FIDO2 Security Keys

You have to make udevd(8) recognize your security key via a rule. First, plug your security key in and, assuming it is a USB device, get its vendor and product IDs from lsusb(8):

lsusb

Create /etc/udev/rules.d/70-u2f.rules as follows. Set the correct vendor and product IDs. My setup:

# Yubico Security Key
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0664", GROUP="plugdev", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0120"
# Yubico.com Yubikey 4/5 U2F
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0664", GROUP="plugdev", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0402"
# Token2 PIN+ Dual Release3.2 Octo FIDO2.1 Security Key
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0664", GROUP="plugdev", ATTRS{idVendor}=="349e", ATTRS{idProduct}=="0024"

This should let non-root users (in the plugdev group) use the device. Add your user to the plugdev group to give it access:

sudo usermod -a -G plugdev YOURUSER

If you want to create ed25519-sk or ecdsa-sk ssh(1) keys, install openssh-sk-helper:

sudo xbps-install -S openssh-sk-helper

@ Install doas(1) and Create Basic Rules

doas(1) is much simpler than sudo(1) — no surprise given its OpenBSD origins. Install it thus:

sudo xbps-install -S opendoas

Configure it by creating /etc/doas.conf, owned by root:root. See doas.conf(5) for the syntax. Here is a great initial doas.conf:

permit nopass YOURUSER as root cmd /usr/bin/reboot args
permit nopass YOURUSER as root cmd /usr/bin/shutdown args -h now
permit nopass YOURUSER as root cmd /usr/bin/xbps-install args -Su
permit nopass YOURUSER as root cmd /usr/bin/xbps-install args -S xbps
permit nopass YOURUSER as root cmd /usr/bin/xbps-remove args -O -o

This permits the user YOURUSER to reboot, shutdown, update the system, and remove stale packages without entering a password.

@ Configure Audio

Install the alsa-utils, pipewire, and sof-firmware packages. You will need the void-repo-nonfree package to get the latter one:

sudo xbps-install -S alsa-utils pipewire sof-firmware

Enable the dbus service on system startup (this will also immediately start it):

sudo ln -s /etc/sv/dbus /var/service/

Create system-wide PipeWire configuration for wireplumber(1) and the pipewire-pulse interface:

mkdir -p /etc/pipewire/pipewire.conf.d
ln -s /usr/share/examples/wireplumber/10-wireplumber.conf /etc/pipewire/pipewire.conf.d/
ln -s /usr/share/examples/pipewire/20-pipewire-pulse.conf /etc/pipewire/pipewire.conf.d/

Ensure that your user's profile defines the XDG_RUNTIME_DIR environment variable. Here’s a good value:

export XDG_RUNTIME_DIR=/tmp//$(id -u)
/usr/bin/mkdir -p -m 0700 "$XDG_RUNTIME_DIR"

Reboot your system and log in as a user in the audio group.

You need to run pipewire(1) in a D-Bus session, usually via dbus-run-session(1). To do this for your X window manager, run the window manager in a D-Bus session in your .xinitrc. For example, if your window manager is dwm, your .xinitrc might look like this:

exec dbus-run-session -- /path/to/dwm

Run pipewire(1) as a user in the audio group:

pipewire

Use wpctl(1) to control wireplumber(1). To see everything:

wpctl status

To set device 53 to 75% volume:

wpctl set-volume 53 0.75

To toggle mute on an audio input or output device, such as device 53:

wpctl set-mute 53 toggle

@ CD Ripping

Install abcde, cdparanoia (for reading raw CD data), an audio encoder such as the Opus encoder, and cd-discid:

sudo xbps-install -S abcde cdparanoia opus-tools cd-discid

abcde(1) will rip the CD into a subdirectory of the current directory. Here is a good way to rip music CDs to Opus:

abcde -l -o opus:"--bitrate 128" -x

@ Configure Printing

Install cups and cups-filters:

sudo xbps-install -S cups cups-filters

Enable cupsd(8):

sudo ln -s /etc/sv/cupsd /etc/runit/runsvdir/default

Some printer manufacturers have additional drivers. For example, if you have an HP printer, install hplip:

sudo xbps-install -S hplip

Then run hp-setup thus after cupsd(8) starts. The defaults are usually sufficient:

sudo hp-setup -i

If hp-setup(1) cannot find your printer's PPD file, look for it in /usr/share/ppd/HP and provide the full path to hp-setup when it asks for it. You might also have to run a dbus session to finish installation; in that case, change your $HOME/.xinitrc so that it runs your window manager with dbus-run-session(1). I use dwm, so my .xinitrc looks something like this:

/usr/bin/dbus-run-session -- /path/to/dwm

enscript(1) is helpful for printing plain text files:

sudo xbps-install -S enscript

Then printing a plain text file named document.txt is as simple as:

enscript -B -p document.ps -M Letter document.txt
lpr -P my_printer -o sides=two-sided-long-edge document.ps

You can print PostScript and PDF files directly with lpr(1) as above.

@ Importing a ZFS Pool

Install ZFS:

sudo xbps-install -S zfs

You should be able to see your pool:

zpool import

If you see it, import it (in this case, it is called "shared"):

zpool import shared

If your ZFS filesystems are encrypted and the keys are files on a USB flash drive, plug the flash drive in, then determine the label of the partition the key files are in. The partition should appear in /dev/disk/by-partlabel:

ls /dev/disk/by-partlabel

Supposing the partition is /dev/disk/by-partlabel/keydisk and contains a FAT filesystem, put the following in /etc/fstab:

PARTLABEL=keydisk /mnt/rootonly/keys vfat auto,ro,nofail,noatime,nosuid,nodev,noexec,nosymfollow 0 2

The above assumes that /mnt/rootonly/keys is a root-owned directory with restrictive permissions, preferably 0700, so that only root can read it. This prevents other users from reading the ZFS keys.

Reboot your system or run:

sudo mount -a

Now you can mount your encrypted ZFS filesystems. To automatically mount encrypted ZFS filesystems on boot, put the following into a new /etc/runit/core-services/80-encrypted-zfs.sh file:

# vim: set ts=4 sw=4 et:

[ -n "$IS_CONTAINER" ] && return 0

if [ -x /usr/bin/zpool -a -x /usr/bin/zfs ]; then
	msg "Mounting encrypted ZFS filesystems..."
	/usr/bin/zfs mount -a -l
fi

You have to do this because runit(8)’s default /etc/runit/core-services scripts try to mount ZFS filesystems before mounting non-ZFS filesystems (that is, traditional filesystems managed by fstab(5) and mount(8)), including your USB flash drive containing the encryption keys. The above script tries to mount all ZFS filesystems again, and the high numeric prefix in the filename ensures that it runs after the script that mounts traditional filesystems.

@ Enabling sshd(8)

Create /etc/ssh/sshd_config.d/local.conf, owned by root:root and with restrictive permissions, and put these overrides in there:

KbdInteractiveAuthentication no
PasswordAuthentication no
PermitEmptyPasswords no
PermitRootLogin no
PubkeyAuthentication yes
X11Forwarding no

Suppose you have two users, alice and bob, and you want to restrict ssh(1) logins to them. Add this to /etc/ssh/sshd_config.d/local.conf to do so:

AllowUsers alice bob

If you did not already enable sshd(8) via the Void Linux installer, run:

ln -s /etc/sv/sshd /etc/runit/runsvdir/default/

If you change settings while sshd(8) is running, run:

sv restart sshd

@ References