Void Linux w/ LUKS & EFIBoot
- Foreword
- Internet Connectivity
- Disk Partitioning
- Boot Partitioning
- Encrypting Root
- Mounting boot and root
- System Installation
- Entering the Void
- Configuring
fstab
- Configuring
dracut
- Configuring
crypttab
- Configuring
efibootmgr
- Cleaning Up
- System Configuration
- First Reboot
- 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.
- we will be utilizing
- efibootmgr // efistub
- we will be utilizing
efibootmgr
to set up an extremely minimal boot partition entry called anefistub
supporting the above encryption
- we will be utilizing
- wpa_supplicant
- we will be using only the small, built-in wi-fi tools
wpa_supplicant
anddhcpcd
- we will be using only the small, built-in wi-fi tools
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