🧰 PXE Boot & Install Ubuntu Desktop 25.10 (HTTP ISO, No NFS)

Boot Ubuntu Desktop 25.10 over the network via PXE using only dnsmasq and apache2, with full UEFI Secure Boot and HTTP ISO support - no NFS, USB, or IP forwarding required.
🧰 PXE Boot & Install Ubuntu Desktop 25.10 (HTTP ISO, No NFS)

This guide explains how to set up a minimal PXE environment to boot Ubuntu Desktop Live ISOs (24.04–25.10) entirely over HTTP, without NFS or IP forwarding.
It works using only dnsmasq (for DHCP+TFTP) and apache2 (for HTTP), and supports both Ethernet and Wi-Fi PXE servers.

✅ Tested on:

  • Ubuntu 24.04, 25.04 and 25.10 Desktop & Server

  • Both Wi-Fi (wlp0s20f3) and USB-C Ethernet (enx0…) as PXE servers;
    NOTE: You must use Ethernet as PXE client!

  • Clients booting via UEFI Secure Boot

  • NVIDIA RTX 4090 and other GPUs


🪜 1. Install prerequisites

sudo apt update
sudo apt install dnsmasq apache2

🧩 2. Find your PXE server IP and interface

List your active connections:

nmcli connection show
ip -4 a

Pick your serving interface:

  • Wi-Fi → usually wlp0s20f3

  • Wired → enx0… or eno1

Find its IP (e.g. 192.168.8.117) — this will be PXE_SERVER_IP in the config below.


🏗️ 3. Download and expose the Ubuntu Desktop ISO

sudo mkdir -p /srv/http/ubuntu
cd /srv/http/ubuntu
wget https://releases.ubuntu.com/25.10/ubuntu-25.10-desktop-amd64.iso

Link for Apache (no restart required):

sudo ln -sv /srv/http/ubuntu /var/www/html/ubuntu

Confirm:

curl -I http://192.168.8.117/ubuntu/ubuntu-25.10-desktop-amd64.iso

⚙️ 4. Prepare TFTP root and signed EFI bootloaders

sudo mkdir -p /srv/tftp/amd64/grub
cd ~/signed-efi
apt download shim-signed grub-efi-amd64-signed
dpkg-deb --fsys-tarfile shim-signed_*_amd64.deb | tar -x ./usr/lib/shim/shimx64.efi.signed.latest
dpkg-deb --fsys-tarfile grub-efi-amd64-signed_*_amd64.deb | tar -x ./usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed

sudo cp usr/lib/shim/shimx64.efi.signed.latest /srv/tftp/amd64/shimx64.efi
sudo cp usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed /srv/tftp/amd64/grubx64.efi

🧱 5. (Optional) Copy kernel & initrd from the ISO

This makes booting faster since the kernel/initrd don’t need to be downloaded each time.

sudo mkdir -p /srv/tftp/amd64/desktop /mnt/iso
sudo mount -o loop /srv/http/ubuntu/ubuntu-25.10-desktop-amd64.iso /mnt/iso
sudo cp /mnt/iso/casper/{vmlinuz,initrd} /srv/tftp/amd64/desktop/
sudo umount /mnt/iso
sudo chmod 644 /srv/tftp/amd64/desktop/{vmlinuz,initrd}

📄 6. Configure GRUB menu

/srv/tftp/amd64/grub/grub.cfg

set default=0
set timeout=5

# Use the Desktop ISO's kernel+initrd you copied to /srv/tftp/amd64/desktop/
# Pure-HTTP boot like 24.04 guides (no NFS)

menuentry "Ubuntu 25.10 Desktop (HTTP ISO, casper)" {
    linux /desktop/vmlinuz boot=casper rd.neednet=1 ip=dhcp url=http://192.168.8.117/ubuntu/ubuntu-25.10-desktop-amd64.iso live-media-path=/casper rootfs_name=minimal.squashfs maybe-ubiquity ---
    initrd /desktop/initrd
}

# Fallback: same idea but with the netboot kernel/initrd from the tarball
menuentry "Ubuntu 25.10 Desktop (HTTP ISO via netboot kernel)" {
    linux /linux boot=casper rd.neednet=1 ip=dhcp url=http://192.168.8.117/ubuntu/ubuntu-25.10-desktop-amd64.iso live-media-path=/casper rootfs_name=minimal.squashfs toram ---
    initrd /initrd
}

This works too:

# cat /srv/tftp/amd64/grub/grub.cfg
set default=0
set timeout=5

menuentry "Ubuntu 25.10 Desktop (HTTP ISO, casper)" {
    linux  /linux ip=dhcp boot=casper iso-url=http://192.168.8.129/ubuntu/ubuntu-25.10-desktop-amd64.iso toram ---
    initrd /initrd
}

(Replace 192.168.8.117 with your own PXE_SERVER_IP.)


📡 7. Configure dnsmasq DHCP/TFTP

/etc/dnsmasq.d/pxe.conf

interface=wlp0s20f3             # or your Ethernet NIC
bind-interfaces
dhcp-range=192.168.8.100,192.168.8.150,12h
dhcp-boot=shimx64.efi,,192.168.8.117  # PXE server IP (next-server)
enable-tftp
tftp-root=/srv/tftp/amd64
tftp-no-blocksize                 # fixes buggy PXE stacks (no blksize OACK)
log-dhcp
dhcp-authoritative

Restart dnsmasq:

sudo systemctl restart dnsmasq

🚀 8. Boot the client PC

  1. Enter BIOS/UEFI → enable PXE Boot (UEFI IPv4).

  2. Use F12/F8 to open boot menu → select PXE IPv4.

  3. You should see:

    Fetching shimx64.efi
    Fetching grubx64.efi
    

    then the GRUB menu.

Select Ubuntu 25.10 Desktop (HTTP ISO, casper).
It will:

  • Load kernel/initrd over TFTP (~7 min on Wi-Fi)

  • Download ISO via HTTP (~2–3 min)

  • Boot to the full Ubuntu Desktop Live session


🌐 9. Fix networking after PXE boot

A) If PXE server is on Wi-Fi (and client has Wi-Fi)

List your connections and prioritize Wi-Fi:

nmcli connection show
nmcli connection modify "Wi-Fi connection" ipv4.route-metric 100
nmcli connection down "Wi-Fi connection"
nmcli connection up "Wi-Fi connection"

This ensures Internet uses Wi-Fi, not the PXE Ethernet.


B) If client is Ethernet-only

The PXE server’s DHCP assigns itself as the gateway (e.g. 192.168.8.117).
Remove that route so your router takes over (e.g. 192.168.8.1):

ip route
ip route delete default via 192.168.8.117 dev eno1
ip route show default
# should now show: default via 192.168.8.1 dev eno1

Now the installer has Internet connectivity while keeping PXE active.


🧹 10. Cleanup PXE server when done

When you no longer need PXE boot:

sudo systemctl stop dnsmasq apache2
sudo apt remove dnsmasq apache2
sudo rm -rf /root/signed-efi /srv/tftp /srv/http /var/www/html/ubuntu /etc/dnsmasq.d/pxe.conf

⚙️ 11. Disable Cloud-Init inside PXE-booted Ubuntu Desktop

When Ubuntu Desktop is booted via PXE, cloud-init may run automatically even though this is a local live session.
This can cause:

  • Slow boot or stuck splash screen

  • Network reconfiguration that breaks connectivity

  • Extra cloud metadata lookups

To disable and remove it cleanly:

sudo systemctl disable --now cloud-config.service cloud-final.service cloud-init-local.service cloud-init-main.service cloud-init-network.service

sudo systemctl mask cloud-init.service
sudo systemctl reset-failed

sudo apt purge -y cloud-init
sudo rm -rf /etc/cloud /var/lib/cloud

Reboot once after this if you plan to keep using the PXE-booted session long-term.


🕒 Boot Performance (reference)

Phase Typical Duration
PXE kernel/initrd transfer ~6–8 min (over Wi-Fi)
ISO download over HTTP ~2–3 min
GUI live session ready ~10 min total

✅ Working Setup Summary

Component Example
PXE Server Interface wlp0s20f3 (Wi-Fi) or enx0… (USB-C NIC)
PXE Server IP 192.168.8.117
Client IP (DHCP) 192.168.8.100–150
HTTP ISO URL http://192.168.8.117/ubuntu/ubuntu-25.10-desktop-amd64.iso
RootFS minimal.squashfs
Bootloader Secure Boot shimx64.efigrubx64.efi
Protocols DHCP, TFTP, HTTP only
Works with Ubuntu 22.04 → 25.10 Desktop Live ISOs

🧠 Notes & Troubleshooting

  • tftp-no-blocksize is essential for buggy UEFI PXE stacks that choke on OACK.

  • If you get a black screen on NVIDIA GPUs → it’s loading; framebuffer may take ~1–2 min.

  • To show progress messages, append to the linux line:

    splash=off debug=1 ---
    
  • Apache access log (/var/log/apache2/access.log) confirms ISO download progress.

  • PXE Desktop tip: disable cloud-init using Section 11 to prevent unwanted background reconfiguration.


🏁 Example Successful Boot Sequence

Fetching shimx64.efi
Fetching grubx64.efi
GRUB menu appears
Loading vmlinuz and initrd…
Downloading ubuntu-25.10-desktop-amd64.iso via HTTP…
Loopback detected capacity change
Starting casper (live session)...
Welcome to Ubuntu 25.10 Live!
Write a comment
No comments yet.