Are you tired of using bootable USB medium every time you want to install Linux based operating system?. Here we present to you a solution that will ease your journey to automated Linux and Unix systems installation on baremetal or Virtualized environments. This will surely save you lots of time and makes the process of OS installation interesting and fast.

The tool that we are talking about in none other than netboot.xyz. This software was created to enable its users to boot into many types of operating systems through its lightweight tooling that gets you up and running in seconds or minutes depending on the speed of your internet. You can explore and test any operating system without the need to download ISO and rewrite media over and over again. netboot.xyz is also usable in rescue operating systems which is key in sysadmin roles.

The netboot.xyz tooling uses iPXE project to provide a user friendly menu within BIOS from where you can choose an operating system to install while customizing boot flags. This is made possible by the Preboot Execution Environment (PXE) available on most systems over the network. We’ve created this article to demonstrate how you can perform the installation, configurations and using netboot.xyz iPXE on Ubuntu or Debian

In our installation we take good advantage of Docker or ansible to setup netboot.xyz iPXE environment on Ubuntu or Debian Linux machine. These methods automates generation of custom templates from default configurations but you can override them. This enables you customize a netboot.xyz environment to suit your specifications.

1. Updating your system

Login to your server where netboot.xyz is to be configured and update it.

sudo apt update && sudo apt upgrade -y

Sometimes a reboot is required after an update.

[ -f /var/run/reboot-required ] && sudo reboot -f

2. Setup netboot.xyz environment

We shall consider two methods to achieve this.

Method 1: Using Docker container (recommended)

To install Docker Engine run the commands below as discussed in the article How To Install Docker Engine on Linux Systems.

Ubuntu:

sudo apt update
sudo apt -y install lsb-release gnupg apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker.gpg
sudo add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo usermod -aG docker $USER
newgrp docker

Debian:

sudo apt update
sudo apt install lsb-release gnupg2 apt-transport-https ca-certificates curl software-properties-common -y
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/debian.gpg
sudo add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo usermod -aG docker $USER
newgrp docker

Check version of docker to confirm installation was successful.

$ docker --version
Docker version 25.0.0, build e758fe5

Create directory that will have container contents.

mkdir ~/netboot_xyz && ~/netboot_xyz

Create docker compose file

vim docker-compose.yml

Here are the contents you can modify.

---
services:
  netbootxyz:
    image: ghcr.io/netbootxyz/netbootxyz
    container_name: netbootxyz
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
    volumes:
      - ./config:/config
      - ./assets:/assets #optional
    ports:
      - 3000:3000
      - 69:69/udp
      - 80:80 #optional
    restart: unless-stopped

Parameters used:

Ports (-p)

ParameterFunction
3000Web configuration interface.
69/udpTFTP Port.
80NGINX server for hosting assets.

Environment Variables (-e)

EnvFunction
PUID=1000for UserID – see below for explanation
PGID=1000for GroupID – see below for explanation
TZ=Etc/UTCspecify a timezone to use, see this list.

Volume Mappings (-v)

VolumeFunction
/configStorage for boot menu files and web application config
/assetsStorage for NETBOOT.XYZ bootable assets (live CDs and other files)

Pull container image.

jkmutai@pxe:~/netboot_xyz$ docker compose pull
[+] Pulling 4/4
 ✔ netbootxyz 3 layers [⣿⣿⣿]      0B/0B      Pulled                                                                                                                                             31.2s
   ✔ 661ff4d9561e Pull complete                                                                                                                                                                  3.2s
   ✔ c5bf41c866f3 Pull complete                                                                                                                                                                 26.2s
   ✔ 6bd6a73a9b6f Pull complete                                                                                                                                                                  2.3s

Start the containers using the commands below.

$ docker compose up -d
[+] Running 1/2
 ⠼ Network netboot_xyz_default  Created                                                                                                                                                          0.4s
 ✔ Container netbootxyz         Started

You can check the status of the commands as below.

$ docker compose ps
NAME         IMAGE                           COMMAND          SERVICE      CREATED              STATUS              PORTS
netbootxyz   ghcr.io/netbootxyz/netbootxyz   "sh /start.sh"   netbootxyz   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:69->69/udp, :::69->69/udp, 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp

Access Web configuration interface on http://serverIP:3000

netboot.xyz on docker web configurator

Next go to step 3

Method 2: Using Ansible Playbook (just for reference)

Install Python 3 and pip module.

sudo apt install python3 python3-pip

Use pip python package manager to install Ansible.

pip3 install --user ansible

Add ~/.local/bin to your PATH which is not there by default.

### Bash ###
echo 'export PATH=$PATH:~/.local/bin' >>~/.bashrc

### Zsh ###
echo 'export PATH=$PATH:~/.local/bin' >>~/.zshrc

Source the bash or zsh profile to use installed ansible binary.

### Bash ###
source ~/.bashrc

### Zsh ###
source ~/.zshrc

Test installation success by checking ansible version.

$ ansible --version
ansible [core 2.16.2]
  config file = None
  configured module search path = ['/home/jkmutai/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/jkmutai/.local/lib/python3.10/site-packages/ansible
  ansible collection location = /home/jkmutai/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/jkmutai/.local/bin/ansible
  python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/usr/bin/python3)
  jinja version = 3.0.3
  libyaml = True

Install git which is used to clone netboot.xyz code from github.

sudo apt install git

Check out the netboot.xyz github repository.

git clone https://github.com/netbootxyz/netboot.xyz.git

Switch your working directory to netboot.xyz.

cd netboot.xyz

Here is the Ansible role structure

The ansible role used to setup netbootxyz environment has the following major components;

  • defaults/main.yml – Consists default settings for deployment, OS versions, Utilities, and Bootloaders
  • tasks/* – Contains all tasks for rendering templates and compiling iPXE bootloaders
  • templates/disks – Templates for iPXE bootloaders
  • templates/menus – Templates for netboot.xyz menus
  • vars/* – Contain required package lists needed to support the compile and deployment of netboot.xyz

To override the defaults, provide your overrides in user_overrides.yml. See user_overrides.yml for examples.

# set desired site name
site_name: ipxe.lab.example.com

# set desired boot domain
boot_domain: lab.example.com

bootloader_tftp_enabled: true
bootloader_https_enabled: true
bootloader_http_enabled: true

Setup your netbootxyz environment on Ubuntu or Debian system by running the ansible playbook using the commands below.

### Running as root user ###
ansible-playbook -i inventory site.yml

### Running as normal user with sudo password ###
ansible-playbook -i inventory site.yml --become --ask-become-pass 

The executed playbook will do the following;

  • Generate menus for netboot.xyz environment using default configuration settings
  • Generate iPXE Bootloaders for booting into that environment
  • Generate customized menu options for those who have additional options they want to add

A successful installation will have failed=0 in the output.

netboot.xyz on ubuntu debian

All generated content will be placed in the default web server root – /var/www/html

ls -lh /var/www/html

Example iPXE file for Ubuntu Linux.

cat /var/www/html/ubuntu.ipxe

You can open http://serverIP and http://serverIP/ipxe/ in your browser to see contents graphically.

netboot.xyz on ubuntu debian 02

Install TFTP Server

A tftp server is needed to host the iPXE files. We can also use dnsmasq

sudo apt -y install dnsmasq

Then edit configuration to /etc/dnsmasq.conf and set as below.

$ sudo vim /etc/dnsmasq.conf
enable-tftp
tftp-root=/var/www/html/
dhcp-boot=netboot.xyz.kpxe

Change systemd-resolved link to avoid conflicting on port 53

sudo ln -fs /run/systemd/resolve/resolv.conf /etc/resolv.conf

Restart both services

sudo systemctl restart dnsmasq systemd-resolved

3. Configure TFTP on DHCP Server

To PXE boot a system you will need an existing DHCP server where you can set this TFTP server as your DHCP boot destination. Our setup only provides a TFTP server hosting with the latest IPXE kernel builds from netboot.xyz.

There is an option of setting up your own DHCP server and configuring next-server parameter in the settings. See example below.

option arch code 93 = unsigned integer 16;

subnet 192.168.1.0 netmask 255.255.255.0 {
  range 192.168.1.34 192.168.0.254;       # Change this range as appropriate for your network
  next-server 192.168.1.254;               # Change this to the address of your netboot.xyz TFTP server
  option subnet-mask 255.255.255.0;
  option routers 192.168.1.1;             # Change this to the address of your router
  option broadcast-address 192.168.1.255;
  option domain-name "mylab.example.com";     # This is optional
  option domain-name-servers 1.1.1.1;
  if exists user-class and ( option user-class = "iPXE" ) {
    filename "http://boot.netboot.xyz/menu.ipxe";
  } elsif option arch = encode-int ( 16, 16 ) {
    filename "http://boot.netboot.xyz/ipxe/netboot.xyz.efi";
    option vendor-class-identifier "HTTPClient";
  } elsif option arch = 00:07 {
    filename "netboot.xyz.efi";
  } else {
    filename "netboot.xyz.kpxe";
  }
}

Where 192.168.1.254 is the IP address of netboot.xyz server.

Some router setup examples

Let’s consider some router examples on how to update DHCP server settings to configure next server address pointing to our TFFP server with boot file names.

netboot.xyz boot file types

Below is a list of bootfile names you can set as the boot file in the DHCP configuration.

bootfile namedescription
netboot.xyz.kpxeLegacy DHCP boot image file, uses built-in iPXE NIC drivers
netboot.xyz-undionly.kpxeLegacy DHCP boot image file, use if you have NIC issues
netboot.xyz.efiUEFI boot image file, uses built-in UEFI NIC drivers
netboot.xyz-snp.efiUEFI w/ Simple Network Protocol, attempts to boot all net devices
netboot.xyz-snponly.efiUEFI w/ Simple Network Protocol, only boots from device chained from
netboot.xyz-arm64.efiDHCP EFI boot image file, uses built-in iPXE NIC drivers
netboot.xyz-arm64-snp.efiUEFI w/ Simple Network Protocol, attempts to boot all net devices
netboot.xyz-arm64-snponly.efiUEFI w/ Simple Network Protocol, only boots from device chained from
netboot.xyz-rpi4-snp.efiUEFI for Raspberry Pi 4, attempts to boot all net devices

OPNsense

Navigate to Services -> DHCP Server, then choose the network name to change DHCP settings for. Set TFTP server IP

netboot.xyz on tftp opnsense 01

Set IP address of your server under “Network Booting” > Advanced section.

netboot.xyz on tftp opnsense 02

Set as below.

  • Tick to enable network booting
  • Set next-server IP to your server IP address
  • Set Default BIOS file name to netboot.xyz.kpxe
  • Set UEFI 32 and 64 bit filename to netboot.xyz.efi
netboot.xyz on tftp opnsense 03

PFSense

The settings are similar to OPNsense. See screenshot below.

netboot.xyz pfsense

Unifi Security Gateway (with the controller)

Navigate to Networks -> LAN (or other network you need to boot from) -> ADVANCED DHCP OPTIONS

  • Tick to enable network boot
  • Server – Set YOURSERVERIP
  • Filename- netboot.xyz.kpxe

4. Install Operating System using netboot.xyz

For baremetal enable network boot in BIOS settings and power on the server.

For Virtual Machine environment, create a VM without an ISO, then change boot order to start with Network boot.

netboot.xyz boot order

Next start the VM and PXE boot process should begin immediately.

netboot.xyz boot from network

Next you are presented with netboot.xyz menu.

netboot.xyz boot menu

Choose Distribution to install or Tools image if you need to boot into a live image and perform system repair or data recovery.

LEAVE A REPLY

Please enter your comment!
Please enter your name here