How to automatically install Ubuntu24.04 custom in PXE and netboot with autoinstall from Canonical ?

I needed to use these tools to automatically install and configure computers for new arrivals in our company. The computers boot in UEFI. The below diagram describes briefly the steps of the one click installation.

PXE or iPXE

In my case, iPXE wasn’t useful, as PXE provided all the functionality I needed. That is, to boot into UEFI and to load the bootloader. Don’t forget to activate the PXE boot option in your bios if you don’t find PXE in your boot option menu. To get the boot option menu, it’s F12 on the Lenovo Laptops and most brands Laptops. You need ti hit this key when your bios boot.

You can use iPXE if you want, it’s just one more step in the diagram. PXE download iPXE with the DHCP option 175 and the DHCP service sends the link to download iPXE. After that, it boots in iPXE and retrieves informations like PXE from the DHCP server. You can find more informations on the documentation site.

DHCP with Kea-dhcp

PXE/iPXE works with the options received from the dhcp server. You need to plug your ethernet cable on a network where you have a dhcp server. That’s can be an other Laptop with a dhcp server and a bridge.

In my case I used kea-dhcp as DHCP server. You cans install it: sudo apt install kea-dhcp4-server.

You need to edit the configuration of your DHCP server IPV4. You can find the config file in /etc/kea/kea-dhcp4.conf. An example of a basic config:

Test

You need to restart your kea-dhcp4-server service after each modifications. sudo systemctl restart kea-dhcp4-server.

Your computer, where you will use PXE, must be in the same subnet from your dhcp server. The option next-server gives you the Tftp IP address. You can host your dhcp server and tftp server on the same address.

Tftp server

Your TFTP (Trivial File Transfert Protocol) server is useful to give the Grub files for your computer which boot on PXE. Your Grub conf file, bootx64.efi and grubx64.efi files are hosted and distributed by your tftp server.

Download with apt the tftp server: sudo apt install tftpd-hpa

You can edit the configuration file in /etc/default/tftpd-hpa.

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftpboot"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure"

In /tftpboot folder you must add bootx64.efi and grubx64.efi then you need to create a folder grub where you will put your config file and all your modules.

tftpboot
    bootx64.efi
    grubx64.efi
    grub
        grub.cfg

Where can I get the bootx64 and grubx64 file ?

You can find these files in the netboot folder given from Ubuntu website:

  1. grubx64.efi
  2. bootx64.efi
  3. pxelinux.0 (If you use Legacy and not UEFI)

You can now create your config file for Grub: /tftpboot/grub/grub.cfg Inside the config file you need to create a menuentry and add some options on the kernel.

set timeout=10 #After 10 seconds select the default menuentry
set default=0 #The default menuentry is the first menu
menuentry "Install Ubuntu One click installation" {
        set gfxpayload=keep
        linux   vmlinuz nfsroot=10.11.12.1:/home/edufour/Documents/nfs/noble/ netboot=nfs boot=casper autoinstall ds="nocloud-net;s=http://10.11.12.1:3003/autoinstall"
        initrd  initrd
}

linux vmlinuz nfsroot=10.11.12.1:/home/edufour/Documents/nfs/noble/ netboot=nfs boot=casper autoinstall ds="nocloud-net;s=http://10.11.12.1:3003/autoinstall/" network-config=disabled. This lines explain that the kernel file is named vmlinuz and is located at the root of our tftp server. Moreover, theses option nfsroot=10.11.12.1:/home/edufour/Documents/nfs/noble/ netboot=nfs boot=casper explains where we can get our live-image with the protocol nfs and where is the boot. The nfs server part is next part. autoinstall ds="nocloud-net;s=http://10.11.12.1:3003/autoinstall/" network-config=disabled are options for autoinstall, autoinstall fetch the file from an http server and we disable the network-config to avoid several problems.

If you get an error while the autoinstall is executed and the error from the logs (/var/log/install/subiquity-server-debug.log) is Key error: Bootstrap unknown. Also if you can’t start because cloud-init never finish to start, don’t forget to disable the network-config from autoinstall.

initrd initrd This lines explain that the initrd file is named initrd and is located at the root of our tftp server.

Restart your tftp service: sudo systemctl restart tftpd-hpa

Be careful, on Arch Linux the service is tftpd and the config file is different. Check the tftpd service to chec k how the configuration works.

In the next part we will find where you can get the vmlinuxz, initrd file.

NFS server

Install the iso file for Ubuntu Desktop 24.04 on the official site.

After the download, mount your iso: mkdir -p /mnt/iso;sudo mount /<path_to_your_iso> /mnt/iso

You copy the vmlinuz and initrd file from the iso mounted to your tftp sever: sudo cp /mnt/iso/casper/{vmlinuz,initrd} /tftpboot/

Copy the live image

You must copy all the mounted iso in a folder. sudo mkdir -p ~/Documents/nfs/noble/;sudo cp -r /mnt/iso/* ~/Documents/nfs/noble/;sudo cp -r /mnt/iso/.disk ~/Documents/nfs/noble/

Now install the nfs-server: sudo apt install nfs-kernel-server

Edit the export file: sudo vim /etc/exports

Add this line at end of file: /tftpboot/ 10.11.12.0/24(ro)

restart the service: sudo systemctl restart nfs-kernel-server

Of course, don’t forget to change the config like the subnet.

Now you have a dhcp server, a tftp server and a nfs server running.

AutoInstall

You need a http server, for this tutorial we will use the module http.server from python. But you can use apache2 or nginx of course.

Create a directory for the http server: mkdir -p ~/Documents/www/autoinstall

Launch your http server: cd ~/Documents/www;sudo python3 -m http.server 3003

In a new terminal, we will add meta-data and vendor-data: touch ~/Documents/www/autoinstall/{meta-data,vendor-data}

Now we create the config file for autoinstall: vim ~/Documents/www/autoinstall/user-data

The minimal in the file must be:

The encrypted password is ubuntu

#cloud-config
autoinstall:
  version: 1
  identity:
    hostname: ubuntu-server
    password: "$6$exDY1mhS4KUYCE/2$zmn9ToZwTKLhCw.b4/b.ZRTIZM30JZ4QrOQ2aOXJ8yk96xpcCof0kxKwuX1kqLG/ygbJ1f8wxED22bTL4F46P0"
    username: ubuntu

You can find all the references in the official documentation.

You can use the late_commands section to fetch then execute your custom script. Don’t forget that you are in an environment where your identity is not created, so you don’t have the folder /home/ubuntu created.

Conclusion

With all theses composants, you have now a one click installation custom ubuntu and save a lot of time !

Be careful about cloud-init, it’s very tricky and there is few informations about it. Skip the network configuration solves all my problems.