Skip to content

Quickstart

Evan edited this page Sep 10, 2023 · 33 revisions

Introduction

This article describes the steps necessary to get a basic but functional Gobble setup on a single server, and use it to boot the Ubuntu Server 22.04 installer.
Note that this guide is a quick, simple and 'batteries included' setup. It includes components that might be not be necessary or optimal for your scenario.
As such, I encourage you to see this guide as more of an explanation of how it works instead of an actual viable setup, and maybe use specific parts of it where necessary.

Components

Overview

This guide and all the commands in it are based on a clean install of Ubuntu 22.04.

For a basic setup, the following components are required:

  • An Ubuntu Server 22.04 ISO. It should (hopefully) also work with other versions or Linux distributions, but those might require a slightly different configuration.
  • A DHCP server to hand out IP addresses to clients and point them towards the TFTP server (to retrieve the iPXE firmware) and to Gobble (to retrieve the iPXE script).
  • A TFTP server to serve the iPXE firmware to these clients.
  • A separate webserver to serve the kernel, initrd and ISO file for Ubuntu Server. This can also be done over TFTP, but iPXE supports doing so over HTTP which is way cooler :).
  • Gobble to serve the iPXE scripts to clients, this is self-explanatory.

DHCP server

For this guide, the Kea DHCP server software is used, which is the official replacement for the 'standard' ISC DHCP server (dhcpd).

To install it, run:

apt install kea

The default configuration file for the DHCPv4 server is located at /etc/kea/kea-dhcp4.conf. The JSON snippet seen below is an example of a configuration file that will handle iPXE chainloading and point the client to the proper URL afterwards.

Make sure to replace the subnet, pool addresses, next-server and the boot-file-name URL for iPXE clients with the proper values for your environment!

{
  "Dhcp4": {
    "interfaces-config": {
      "interfaces": ["eth0"],
      "dhcp-socket-type": "raw"
    },
    "valid-lifetime": 4000,
    "renew-timer": 1000,
    "rebind-timer": 2000,
    "subnet4": [{
      "pools": [{"pool": "192.168.1.100-192.168.1.119"}],
      "subnet": "192.168.1.0/24",
      "id": 1
    }],
    "next-server": "192.168.1.10",
    "boot-file-name": "snponly.efi",
    "client-classes": [
      {
        "name": "iPXE",
        "test": "substring(option[77].hex,0,4) == 'iPXE'",
        "boot-file-name": "http://192.168.1.10/api/pxe-config?mac=${net0/mac}"
      },
      {
        "name": "Legacy",
        "test": "substring(option[60].hex,0,20) == 'PXEClient:Arch:00000'",
        "boot-file-name": "undionly.kpxe"
      }
    ],
    "loggers": [{
      "name": "*",
      "severity": "DEBUG"
    }]
  }
}

In short, this configuration file will hand out IP addresses in the subnet 192.168.1.0/24, specifically from the range 192.168.1.100-192.168.1.119.
Additionally, it will point clients that are PXE booting to a TFTP server located at 192.168.1.10.
By default, it will tell them to retrieve and use snponly.efi (suitable for UEFI systems). If the client turns out to be a legacy BIOS system, it will instead tell them to use undionly.kpxe.
Lastly, if the client is already running iPXE (either natively or chainloaded through one of the above files), it will point them to Gobble to retrieve the iPXE script instead.

After writing and saving this configuration file to /etc/kea/kea-dhcp4.conf, restart the DHCP server to apply these changes:

systemctl restart kea-dhcp4-server.service

TFTP server

Installation

Install the tftp-hpa server and client:

apt install tftpd-hpa tftp-hpa

iPXE

At this point, the service should have automatically started and is serving files from /srv/tftp. Now you will need to download and place the iPXE firmware in the TFTP root.

Firstly, download the iPXE firmware from the official Ubuntu repositories (or directly use the upstream iPXE ISO/files):

apt install ipxe

Now, the iPXE firmware is located under /usr/lib/ipxe. For the sake of simplicity, there are two files from this directory that we will be using:

  • undionly.kpxe: used for legacy (BIOS) clients
  • snponly.efi: used for UEFI clients

Copy both of these files into /srv/tftp.

Verify that the TFTP server works and the file(s) are available by running the following commands (somewhere outside of the TFTP root, like your home directory):

tftp localhost
tftp> get undionly.kpxe
tftp> get snponly.efi
tftp> quit
ls

If everything works correctly, the files that we have just downloaded should be present in the current directory and visible in the output of the ls command.

At this point you can try to network boot your client to check if it can successfully chainload iPXE, before continuing to follow this guide. It should at least output that it has loaded iPXE, and will then fail to retrieve its iPXE script from Gobble because it has not been set up yet.

NGINX

Installation

Install NGINX:

apt install nginx

At this point, NGINX should already be running and available over HTTP on port 80. However, since Gobble also listens on port 80 by default, we are going to change the port on which NGINX listens.

To do so, open the configuration file for the default site, /etc/nginx/sites-available/default, in your favorite text editor. In this file, the following configuration is present:

listen 80 default_server;
listen [::]:80 default_server;

In this section, replace 80 with 8080 (or some other port if necessary), so that it looks like the following snippet:

listen 8080 default_server;
listen [::]:8080 default_server;

Save the file, and restart NGINX:

systemctl restart nginx.service

Now, verify that NGINX is running on the new port:

curl http://localhost:8080/

Serving the Ubuntu Server files

Place the Ubuntu Server ISO file in the NGINX document root, located at /var/www/html/ by default. Afterwards, mount the ISO and copy the kernel/initrd into the document root.

mkdir /var/www/html/ubuntu
mv /path/to/ubuntu.iso /var/www/html/ubuntu/
mount -o loop /var/www/html/ubuntu/ubuntu.iso /mnt
cd /mnt/casper
cp initrd vmlinuz /var/www/html/ubuntu/
umount /mnt

Gobble

Installation

The recommended way to run Gobble is to use Docker and Docker Compose. Ensure that these are installed by following the installation instructions from the official Docker documentation.

Now, you will need the following two files from this GitHub repository:

  • docker-compose.yml
  • schema.sql (this is the database schema, which the application currently does not import by itself. Place it in the same directory as the Docker Compose file, and it will automatically be imported when the containers are started)

Download and place these files in the same directory, and please replace the default database password (GOBBLE_DB_PASS and POSTGRES_PASSWORD) in the Docker Compose file with a secure password!
Afterwards, run the following command to start the application:

docker compose up -d

At this point, Gobble should be reachable over HTTP on port 80:

curl http://localhost/

Usage

This section contains a few example commands (using cURL) that demonstrate how to use the API to change the administrator password, create your first profile and system, and how/where to retrieve the rendered iPXE script.

For further information about the API and the available endpoints, check out the OpenAPI spec in this repository.

Firstly, change the default administrator password for the API. Replace $PASSWORD with a secure password:

curl http://localhost/api/users/62fb65af-2d12-4758-93d6-7b58eadde3f1 -u admin:admin -X PUT -d '{"name": "admin", "password": "$PASSWORD"}'

Add the Ubuntu Server 22.04 profile. Make sure to replace $SERVER_IP_ADDRESS with the IP address of your server.

curl http://localhost/api/profiles -u admin:password -X POST -d '{"name": "Ubuntu22.04", "description": "Ubuntu 22.04", "kernel": "http://$SERVER_IP_ADDRESS:8080/ubuntu/vmlinuz", "initrd": "http://$SERVER_IP_ADDRESS:8080/ubuntu/initrd", "kernelParameters": ["initrd=initrd", "root=/dev/ram0", "ramdisk_size=3000000", "ip=dhcp", "url=http://$SERVER_IP_ADDRESS:8080/ubuntu/ubuntu.iso"]}'

Make sure to copy the UUID for the profile from the API output! This is used down below to match a system to this profile.

Register the system you want to PXE boot. Make sure to replace $PROFILE_UUID and $SYSTEM_MAC_ADDRESS with the UUID of the profile you have just created and the MAC address of the interface that the client is going to PXE boot from respectively.

curl http://localhost/api/systems -u admin:password -X POST -d '{"name": "system1", "description": "First system", "profile": "$PROFILE_UUID", "mac": "$SYSTEM_MAC_ADDRESS"}'

Afterwards, verify that the rendered PXE config for this system can be retrieved from the API. Once again, make sure to replace $SYSTEM_MAC_ADDRESS with the MAC address of the system that you have just registered.

curl http://localhost/api/pxe-config?mac=$SYSTEM_MAC_ADDRESS

If this is the case and everything is configured correctly, your system should now network boot successfully and load the Ubuntu Server 22.04 installer.