PXE network boot using netboot.xyz under Docker

Andrew Buldyzhov February 17, 2020

Computer boot up options

For low-level computer maintenance (working with partitions and hard disk images, data recovery, fighting viruses and cyber attacks, etc.) and for installing the operating system, you can use bootable USB flash drives, for example: Ubuntu Live, Clonezilla, SergeyStrelec.

However, this solution has disadvantages:

  • there are many different tools and distributions, so you have to keep many USB flash drives or constantly overwrite them, including when a new version appears;
  • the computer may not support booting from a USB flash drive or it may be disabled;
  • you can simply forget to take a flash drive on a business trip;
  • servicing a large fleet of computers with a USB flash drive is much slower than over a network.

In addition, when using Gigabit Ethernet, network booting is faster.

Under Windows, I usually used tftpd32 to boot over the network — a convenient, portable, small, but quite powerful open source program. However, I have recently been trying to get away from Windows, so I decided to figure out how to solve this problem under Linux.

The search yields quite a few options, but netboot.xyz stands out as a mature solution with good support. The unique advantage of this project is that there are collected and updated images of many OS distributions and utilities that can be used directly from the Internet or cached to a local disk. There is a boot menu that you can edit and extend, including via Git. You can boot from ISO images, but not all: for example, SergeyStrelec didn’t work.

The most convenient way to install netboot.xyz is with the Docker container. It gives such advantages:

  • quick and easy installation and configuration;
  • you can quickly start/stop and uninstall the software;
  • high reliability and security — isolation from the main OS thanks to virtualization, while the resources used (disk space, RAM, CPU) are much less than when using a virtual machine.

There are also several Docker containers for netboot.xyz; the most mature one seems to be this. Also here is its additional description.

This container lacks its own DHCP server, which can be both good and bad. If you already have DHCP on the network, for example, in a router, then you should use it to avoid conflicts. If there is no router, or you can’t configure it, you can also install a DHCP server on the computer using a Docker container, for example, this. Or use another container with netboot.xyz with built-in DHCP, for example this. Or use a container that implements PXE and DHCP without netboot.xyz, for example, this.

Install and configure netboot.xyz

However, we will look at the linuxserver/netbootxyz container here. Here are the main extracts from official documentation, as well as something that was missing there.
Install Docker for Ubuntu. We use the docker.io version from the official Ubuntu repository — it used to be outdated, but its support has recently resumed. Accordingly, we delete other versions (if they were not installed, no harm):

sudo apt-get update
sudo apt-get remove docker docker-engine docker.io docker-ce docker-ce-cli containerd.io
sudo apt install docker.io docker-compose
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker

There are several ways to run this container, the most convenient one is using docker-compose. You should create the docker-compose.yml file:

version: "2"
services:
  netbootxyz:
    image: linuxserver/netbootxyz
    container_name: netbootxyz
    environment:
      - PUID=1000
      - PGID=1000
    volumes:
      - ./netbootxyz-config:/config
      - /media/d1/Dist/OS/netbootxyz:/assets # put here the path for the local downloaded images
    ports:
      - 3000:3000
      - 69:69/udp
      - 8080:80
    restart: unless-stopped

Next, edit the path /media/d1/Dist/OS/netbootxyz in docker-compose.yml — the downloaded images will be stored there. For convenience of launching, you can also create the start.sh file in the same directory (commented-out lines are for Windows 10 installation):

#!/bin/bash
#mkdir /media/d1/Dist/OS/netbootxyz/win
#sudo mount -o loop /media/d1/Dist/OS/Windows10_orig/WIN10_64_En.ISO /media/d1/Dist/OS/netbootxyz/win
docker-compose up --build
#sudo umount /media/d1/Dist/OS/netbootxyz/win                                             

To start the container — sh start.sh in the terminal, to stop — Ctrl-C.
Next, configure the DHCP server in the router. For example, for OpenWRT (in our example, the address of the computer with the container is 192.168.1.2):
Network -> DHCP and DNS -> TFTP Settings -> Enable -> Network boot image:
for Legacy BIOS:

netboot.xyz.kpxe,,192.168.1.2

for UEFI:

netboot.xyz.efi,,192.168.1.2

You can already try to boot over the network. Images will be downloaded from the Internet each time you boot up.
To speed up the booting, and to be able to work without the Internet (which is often the case at industrial facilities), you should cache the images on a local disk. To do this, open the program’s web interface in a browser (http://localhost:3000/) and click on the Local Assets link in the top menu.

I’ve decided to download the following utilities (they collectively take up 7.3 GB):

Kali Live KDE
Ubuntu 19.10 Gnome/Default
Kaspersky Rescue Disk 
DBAN
4MLinux
Breakin
Rescatux
GParted Live
GRML
Clonezilla Debian stable

You also need to edit the menu files in the ./netbootxyz-config/menus subdirectory:

4mlinux.ipxe
clonezilla.ipxe
dban.ipxe
gparted.ipxe
kaspersky.ipxe
live-kali.ipxe
live-ubuntu.ipxe
utils-efi.ipxe
utils-pcbios.ipxe

In these files, add the following line after the #!ipxe header:

set live_endpoint http://192.168.1.2:8080

Installing Windows

Although this option is provided in netboot.xyz, it does not work out of the box. It was possible to make it work only for Windows 10 (maybe Windows 8.1 will also work, I haven’t tried it, but Windows 7 didn’t work).

So, you need to edit the windows.ipxe file:

  • add this line after the header:
set win_base_url http://192.168.1.2:8080/win
  • replace everywhere in the text the string “${win_base_url}/${win_arch}” with “${win_base_url}” — my Windows distributions did not have the x86/x64 subfolder.
  • replace the line “kernel http://${boot_domain}/wimboot” with “kernel http://192.168.1.2:8080/wimboot”, and also copy the wimboot file from ./netbootxyz-config/menus/ to /media/d1/Dist/OS/netbootxyz/ — to enable booting up without the Internet.

Next, you need to Samba-share the directory /media/d1/Dist/OS/netbootxyz/win , into which the ISO image should be unpacked or mounted (before starting the container).
Eventually, when the first screen of the Windows installer opens (where the language, time format and keyboard are selected), you should press Shift+F10 and execute the following commands (taken from here):

wpeinit
net use S: \\192.168.1.2\Dist /user:guest password
S:\OS\netbootxyz\win\sources\setup.exe

Boot up from ISO images

In the netboot.xyz menu, there is the item “Test Distribution ISO”. For this function to work without the Internet, you need to copy the memdisk file from ./netbootxyz-config/menus/ to /media/d1/Dist/OS/netbootxyz/ and edit the file ./netbootxyz-config/menus/boot.cfg:
replace

set memdisk http://${boot_domain}/memdisk

with

set memdisk http://192.168.1.2:8080/memdisk

Leave a comment

Your email address will not be published. Required fields are marked *