Skip to content
/ vms Public

Automated multi-platform virtual machine creation for various teaching purposes

License

Notifications You must be signed in to change notification settings

ouspg/vms

Repository files navigation

Custom UEFI-based Arch Linux builds for AArch64 and x86_64 architectures

The popularity of ARM-based Macbooks has increased the need for multi-architecture virtual machines in teaching.

This repository contains automated build instructions for custom Arch Linux for multi-platform and multi-architecture. Supported builds include Arch Linux with Black Arch repositories for

  • AAarch64 with UTM/QEMU support (Arch Linux ARM)
  • x86_64 with VirtualBox/VMware support (Arch Linux x86_64)

Note There is a slight difference in the packages between ARM and x86_64, because repositories are different.

The publishing process for the csc.fi platform is also briefly documented.

As an alternative to popular Kali Linux, Parrot OS and Black Arch virtual machines, we have a bit more lightweight and opinionated virtual machine for teaching purposes.

Build process

Below is the example process for ARM architecture. For x86_64 builds, Packer is used directly, for now.

sequenceDiagram
    build_arm.sh->>+build_arm.sh: Initiates ARM build process
    build_arm.sh->>+build_arm.sh: Downloads EFI firmware
    build_arm.sh->>+Packer: Launches Packer
    Packer->>+QEMU: Uploads required files
    Packer->>+QEMU: Initiates Archinstall script
    Packer->>+QEMU: Post-install configurations
    Packer->>+build_arm.sh: Provides built .qcow2 image
    build_arm.sh->>+build_arm.sh: Compresses the resulting image
Loading

Build dependencies

  • QEMU
  • wget
  • Packer
  • UTM (optional, for improved testing experience)
  • (indirect) archinstall
  • p7zip (for compression)
  • VirtualBox (for .ova x86_64 builds)

Install with Nix:

nix-env -iA nixpkgs.qemu nixpkgs.wget nixpkgs.packer nixpkgs.p7zip

Applications with GUI might be more reasonable to install as brew casks instead to save some mental health.

brew install --cask utm

Pre-processor

Building QEMU images requires the use of corresponding EFI reference implementation. We will use the EFI Development Kit by the TianoCore community, aka EDK2 releases. EDK2 release binary must be downloaded for AARCH64 before the Archboot version of the Arch Linux ARM can be booted.

Unofficial releases have been used: https://retrage.github.io/edk2-nightly/

The build ARM script automates this process, but likely the checksum needs to be changed manually once per day.

Archinstall

Archinstall automates most of the installation process. Currently, there is no need to offer other distributions as custom virtual machines, so Ansible et. al. might be a bit overkill.

Configuration files are found in the archinstall directory.

ARM limitations

Archinstall is meant for x86_64 architecture. There are some caveats; the GRUB bootloader is installed with hardcoded parameters for x86_64, but systemd-bootctl works well enough. We only need to rename the Kernel image from /boot/loader/entries/ configurations to make the ARM machine UEFI bootable.

Debug environment for Python archinstall script

Create docker image from

curl -OL http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz

And import

cat ArchLinuxARM*.tar.gz | podman import - archlinuxarm

Update keyring

pacman-key --populate archlinuxarm

Building

For ARM builds, use build_arm.sh.

bash build_arm.sh # Bash must be used

For x86_64 builds, use packer directly, for now.

packer build -var="output_dir=$OUTPUT_DIR" -only="virtualbox-iso.archlinux" archlinux.pkr.hcl

Deployment

Deploy dependencies

Publishing into the Allas object storage requires some additional tools

Install rclone with Nix, for example:

nix-env -iA nixpkgs.rclone

Configuration, based on docs:

wget https://raw.githubusercontent.com/CSCfi/allas-cli-utils/master/allas_conf
source allas_conf -u your-csc-username -p your-csc-project-name

Rclone usage: https://docs.csc.fi/data/Allas/using_allas/rclone/

Signing

As good practice, it is recommended to sign the builds and distribute the signature.

To sign builds manually:

gpg --output archlinuxarm.sig --detach-sig archlinuxarm.7zip

To verify:

gpg --verify archlinuxarm.sig archlinuxarm.7zip

Allas URL shortening

Currently, ouspg.org is a bit abused as a URL shortener with client-side redirects.

See for ARM

Testing and running

UTM

To get the best out of UTM, enable retina support, select GPU accelerated display driver, e.g. virtio-gpu-gl-pci, and scale Gnome to 200% for an improved GUI experience.

However, GPU acceleration should be disabled (use virtio-gpu-pci) if the browser must be used inside the guest VM, for now.

Linux & Windows

Customisation

The virtual machines will include all regular Arch Linux repositories, including AUR and Black Arch repositories. Any package should be straightforward to install if needed.

Click below to see brief summary of the modifications.

Gnome setting changes cannot be applied automatically at the moment.

Customisations ↓

To include Black Arch sources:

curl https://blackarch.org/strap.sh | sh

Gnome tweaks

Finnish as the first keyboard layout:

gsettings set org.gnome.desktop.input-sources sources "[('xkb', 'fi'), ('xkb', 'us')]"

Print the favourites from desktop

gsettings get org.gnome.shell favorite-apps

Set custom apps (string array)

gsettings set org.gnome.shell favorite-apps

['org.gnome.Nautilus.desktop', 'org.wezfurlong.wezterm.desktop', 'firefox.desktop', 'codium.desktop', 'org.gnome.Settings.desktop']

yay is included in blackarch-misc. Hurray! -> pacman -S yay

AUR packages

yay -S vscodium-bin

Codium ~/.config/VSCodium/User/settings.json

{
    "workbench.colorTheme": "Default Dark+",
    "window.titleBarStyle": "custom"
}

Future ideas

If there is ever a switch for Ansible, seems good tutorial https://github.com/diffy0712/arch-boot

Issues

Audio packages must be installed before Gnome. Otherwise, pipewire and pulse will conflict. Root partition needs mountpoint /

Boot Linux Kernel from UEFI shell

Change to the correct directory:

fs0:

The need for booting from UEFI Shell might arise if the kernel parameters or something else is incorrect, and there is a need to find the correct ones.

Default parameters are located in /loader/entries Modify the default parameters with edit command. When building ARM version with archinstall script, the name of the kernel image might be wrong. It should be changed to /Image.

bcfg boot add 0 fsX:\loader\entries\your_entry_file.conf "Arch Linux"

Reset with reset command.

To fix BlackArch keyring issues

Either https://blackarch.org/faq.html#collapseFour

or

sudo pacman -Syu
sudo echo F9A6E68A711354D84A9B91637533BAFE69A25079:4: >> /usr/share/pacman/keyring/blackarch-trusted
sudo pacman-key --init
sudo pacman-key --populate archlinuxarm blackarch
sudo pacman -Syu

BlackArch/blackarch#4034

Manually sign Arch Linux ARM builder key (Weak key because of SHA1?)

pacman-key --lsign-key 68B3537F39A313B3E574D06777193F152BDBE6A6

Network issues

Start systemd-networkd and systemd-resolved

Package specific

Arch Linux AUR `dieharder`` not maintained anymore, upstream repo deleted.

Install from: https://github.com/eddelbuettel/dieharder