Install Linux Without a USB Drive: PXE Network Boot for Production Deployments
Picture a rack of servers in a data center—half have no video output, let alone USB ports. Repurposing lab desktops or automating VMs at scale? Reaching for USB sticks quickly becomes obsolete. PXE (Preboot Execution Environment) network boot offers a robust, repeatable, and zero-touch installation path for Linux, minimizing physical intervention and maximizing flexibility.
Context: Why PXE Instead of USB?
- Physical restrictions: Bare-metal cages, blade servers, thin clients.
- Scale: 20+ machines? Manual imaging does not scale.
- Automated fleet management: Standardizing installations with configuration management (Kickstart, Preseed, or cloud-init).
PXE leverages DHCP and TFTP to deliver bootloaders and OS kernels over the wire. It’s not new—but in 2024, it’s still faster than hunting for a trustworthy flash drive (and avoids the “/dev/sdb was missing” headache).
Minimum Requirements
- DHCP server (can be an existing router but granular control preferred)
- TFTP server (often
tftpd-hpa
ordnsmasq
) - Linux ISO image (verify integrity first:
sha256sum ubuntu-22.04.4-live-server-amd64.iso
) - PXELINUX (from
syslinux
package) - Target machines with PXE/network boot enabled in BIOS/UEFI
- Optional: NFS/HTTP server if network-based install media is needed
PXE Boot Sequence (High-level)
┌───────────────┐ ┌──────────────┐
│ PXE Client │──────────────▶│ DHCP Server │
└──────┬───────┘ DHCPDISCOVER └──────┬──────┘
│ ◀─────────────── │
│ DHCPOFFER (PXE opts) │
┌──────▼───────┐ ┌──────▼──────┐
│ PXE Client │──────────────▶│ TFTP Server │
└──────┬───────┘ TFTP GET └─────────────┘
│
[Loads pxelinux.0 → kernel/initrd → installer]
Step 1: Install and Configure TFTP
Debian/Ubuntu 22.04+:
sudo apt update
sudo apt install tftpd-hpa
Edit /etc/default/tftpd-hpa
:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure"
sudo mkdir -p /srv/tftp
sudo chown -R tftp:tftp /srv/tftp
sudo systemctl enable tftpd-hpa --now
Note: SELinux/AppArmor can silently block file access on some distros—check logs if transfers fail.
Step 2: Extract PXE Boot Components from ISO
Mount ISO and copy required files:
sudo mkdir -p /mnt/iso
sudo mount -o loop ubuntu-22.04.4-live-server-amd64.iso /mnt/iso
sudo cp /mnt/iso/casper/vmlinuz /srv/tftp/
sudo cp /mnt/iso/casper/initrd /srv/tftp/
PXELINUX Loader:
sudo apt install syslinux-common
sudo cp /usr/lib/PXELINUX/pxelinux.0 /srv/tftp/
sudo mkdir -p /srv/tftp/pxelinux.cfg
Step 3: Configure DHCP for PXE
For a dedicated ISC DHCP server:
# /etc/dhcp/dhcpd.conf example
subnet 10.0.0.0 netmask 255.255.255.0 {
range 10.0.0.100 10.0.0.200;
option routers 10.0.0.1;
filename "pxelinux.0";
next-server 10.0.0.2; # TFTP server IP
}
Restart DHCP service. Known issue: Some routers truncate filename strings; enterprise networks often block TFTP.
Step 4: Configure PXELINUX
Create /srv/tftp/pxelinux.cfg/default
:
DEFAULT linux
LABEL linux
KERNEL vmlinuz
APPEND initrd=initrd ip=dhcp --- quiet
Tip: Add auto=true priority=critical url=http://10.0.0.2/preseed.cfg
for automated installs with Preseed. For UEFI-based systems, supplement with grubnetx64.efi
and adjust DHCP accordingly.
Step 5: Serve Installation Media (NFS/HTTP/FTP)
If using NFS (common for large ISOs):
sudo apt install nfs-kernel-server
sudo mkdir -p /srv/install/ubuntu
sudo rsync -a /mnt/iso/ /srv/install/ubuntu/
echo "/srv/install/ubuntu *(ro,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports
sudo exportfs -ra
sudo systemctl restart nfs-kernel-server
Firewall adjustment required: NFS uses 2049/tcp (and sometimes rpcbind/111).
Step 6: Network Boot Target Machines
Set boot order: “Network (PXE)” before local disk. Common vendor quirks: some BIOS/UEFI firmware disables IPv4 PXE by default.
Expected client output if successful:
Trying to load: pxelinux.0
Loading vmlinuz...........
Loading initrd............
Troubleshooting:
- TFTP errors usually mean misconfigured firewall, owner, or SELinux label.
- PXE client drops to shell? Check kernel/initrd filenames for typos.
Non-obvious Details & Tips
- DHCP/TFTP on same host simplifies things; DNSMasq can serve both.
- Automated installation: Serve Preseed/Kickstart configs over HTTP for true unattended installs.
- For UEFI-only hardware: Legacy PXELINUX does not support Secure Boot; use GRUB2 EFI network boot binaries.
- VMware/VirtualBox PXE requires “Bridged” mode to reach external PXE services.
Example: Ubuntu 22.04 Automated PXE Install
Minimal pxelinux.cfg/default
:
DEFAULT auto
LABEL auto
KERNEL vmlinuz
APPEND initrd=initrd auto=true priority=critical url=http://10.0.0.2/preseed/ubuntu.cfg netcfg/choose_interface=auto ---
/srv/www/preseed/ubuntu.cfg
(served via Apache/nginx):
d-i passwd/root-password password secret
d-i passwd/root-password-again password secret
d-i clock-setup/utc boolean true
d-i partman-auto/method string regular
d-i partman-partitioning/choose_recipe select atomic
This auto-partitions and installs without manual input.
Bottom Line
PXE boot makes Linux deployments repeatable, hands-off, and fast—no USB media, just reliable network delivery. For infra at scale, or even a home lab, the initial investment in setup is quickly offset by saved hours later.
Trade-offs? Network dependencies and minor security risk if PXE is left exposed. For full automation, combine with Preseed or Kickstart—manual intervention is optional.
Practical tip: Document your PXE environment. When it breaks (it will, eventually), logs and config history are your only friends.
For distro-specific tweaks (e.g., RHEL, Debian, custom kernel args), review vendor documentation. Edge cases—multicast boot, large-scale cloud PXE—require deeper engineering.
Questions or unusual edge cases? Drop them below for practical debugging advice.