Setup PXE Server Ubuntu

In this tutorial, I will guide you through the process of creating a PXE server on an Ubuntu Host. This guide also includes complete setup instructions for the PXE client and DHCP server. I will also guide you through an effective storage/deployment method so that you may quickly deploy identical PXE images.
——-
[[[TOC]]]
——-
= Install Server Dependencies =

# Update & clean current packages, then install the packages that are required for this tutorial.
{{{
sudo apt-get update -y && sudo apt-get dist-upgrade -y &&
sudo apt-get install -y isc-dhcp-server tftpd-hpa syslinux \
syslinux nfs-kernel-server initramfs-tools \
debootstrap syslinux
}}}
——-
= Setup NFS root =

# Create desired directory structure. In my configuration, the pxe directory is in the root and I store all of my pxe images in pxe-boot/images/*.
{{{
sudo mkdir -p /pxe-boot/{pxelinux.cfg,images/{base-cluster-image}}
}}}

# Copy the PXE boot file to the PXE root.
{{{
sudo cp /usr/lib/syslinux/pxelinux.0 /pxe-boot
}}}

# Share new directory via NFS
{{{
sudo nano /etc/exports
}}}
{{{
/pxe-boot 192.168.69.100(rw,no_root_squash,async,insecure) #< You will want to modify the IP }}} # Sync exports {{{ sudo exportfs -rv }}} # Download base system via debootstrap to `pxe-boot/images/base-cluster-image`. Add desired packages to the include parameter. This will take a while..you can continue with the other sections in another screen session if you want to save time. You can also change the arch or distribution (quantal) to fit your desired setup. {{{ sudo debootstrap --variant=minbase --include=procps,screen,passwd,less,nano,bash,nfs-common \ --arch amd64 quantal /pxe-boot/images/base-cluster-image http://archive.ubuntu.com/ubuntu }}} # Chroot to the image directory. {{{ sudo chroot /pxe-boot/images/base-cluster-image/ }}} # Setup the hostname (replace `base-cluster-image` with your desired hostname) {{{ echo base-cluster-image > /etc/hostname
}}}

# Setup the hosts file.
{{{
nano /etc/hosts
}}}
{{{
127.0.0.1 localhost
127.0.1.1 base-cluster-image #< (replace `base-cluster-image` with your desired hostname) # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters }}} # Setup the fstab. It should look similar to the below (adding other mounts if necessary) {{{ nano /etc/fstab }}} {{{ /proc /proc proc defaults 0 0 /sys /sys sysfs defaults 0 0 /dev/nfs / nfs defaults 1 1 }}} # Setup interfaces (client already discovered DHCP during boot process, so the interface needs to be set to manual). {{{ nano /etc/network/interfaces` }}} {{{ # Loopback auto lo iface lo inet loopback # Don't discover DHCP iface eth0 inet manual }}} # Add network adapter names to `/etc/initramfs-tools/modules` (such as ar8121, r8169, etc. - one per line) # Mount `/proc`. {{{ mount /proc }}} # Set the root password. {{{ passwd Enter new UNIX password: Retype new UNIX password: }}} # Generate/update locale settings. {{{ locale-gen en_US.UTF-8 dpkg-reconfigure locales }}} # Edit sources `nano /etc/apt/sources.list` and add: {{{ deb http://archive.ubuntu.com/ubuntu quantal main restricted universe multiverse deb http://archive.ubuntu.com/ubuntu quantal-updates main restricted universe multiverse deb http://archive.ubuntu.com/ubuntu quantal-security main restricted universe multiverse }}} # Update app cache {{{ apt-get update }}} # Install system kernel {{{ apt-get install -y linux-headers-generic apt-get install -y linux-image-generic }}} # Link kernel to a better spot and set permissions. This will allow you to upgrade kernels without changing configuration files. {{{ ln -s /boot/vmlinuz-3.5.0-21-generic /vmlinuz #< Substitute for your kernel version ln -s /boot/initrd.img-3.5.0-21-generic /initrd.img #< Substitute for your kernel version chmod 777 -R /vmlinuz /initrd.img /boot/ #< /boot could probably be left out of this.. }}} # Edit initramfs.conf `nano /etc/initramfs-tools/initramfs.conf` and make the following options match {{{ MODULES = netboot BOOT = nfs }}} # Update initramfs with new params `update-initramfs -u` # Install any source packages your image needs (or any you did not have in the debootstrap --include) # Exit chroot {{{ umount /proc exit }}} ------- =TFTP= # Open the config file. {{{ sudo nano /etc/default/tftpd-hpa }}} # Make it look like the below (replace TFTP_DIRECTORY with PXE root) {{{ # /etc/default/tftpd-hpa RUN_DAEMON="yes" OPTIONS="--secure" TFTP_ADDRESS="0.0.0.0:69" TFTP_USERNAME="tftp" TFTP_DIRECTORY="/pxe-boot/" }}} # Create default boot config {{{ DEFAULT images/base-cluster-image/vmlinuz APPEND boot=nfs root=/dev/nfs initrd=images/base-cluster-image/initrd.img nfsroot=192.168.69.100:/pxe-boot/images/base-cluster-image,rw ip=dhcp rw }}} ## [[https://help.ubuntu.com/community/PXEInstallMultiDistro#Putting_it_All_Together|Follow this for pxe menu setups]] ## [[http://www.syslinux.org/wiki/index.php/PXELINUX#How_do_I_Configure_PXELINUX.3F|Or, you can serve a different pxe config file per system]] # Permissions `sudo chmod 777 /pxe-boot` # Start tftp server `sudo /etc/init.d/tftpd-hpa start` # Verify server is listening {{{ dlasley@server:/$ ss -apu | grep tftp UNCONN 0 0 *:tftp *:* }}} ------- =DHCPD= Note that the below configurations are redundant, and should be chosen depending on your environment. Windows users would use the GUI. ==Linux== # Edit config `sudo nano /etc/default/isc-dhcp-server` to listen on specific interfaces (space separate). Configure everything else to your liking {{{ INTERFACES="bond0" }}} # Edit `dhcpd.conf` `sudo nano /etc/dhcp/dhcpd.conf`. Mine is below (minus unrelated static clients), edit for your config (IPs, hostnames, MACs, etc.) {{{ ddns-update-style none; option subnet-mask 255.255.255.0; option broadcast-address 192.168.69.255; option routers 192.168.69.254; option domain-name-servers 192.168.69.110, 192.168.69.100, 192.168.69.254; option domain-name "dlasley.net"; default-lease-time 86400; max-lease-time 604800; #option time-offset -18000; authoritative; log-facility local7; allow booting; allow bootp; # Reserve >100 for static
subnet 192.168.69.0 netmask 255.255.255.0 {
range 192.168.69.1 192.168.69.99;

get-lease-hostnames on;
use-host-decl-names on;

next-server 192.168.69.100;
filename “/pxe-boot/pxelinux.0”;
}

host cluster_1 {
hardware ethernet 00:21:97:32:D6:B5;
fixed-address 192.168.69.103;
#filename “/pxe-boot/pxelinux.0”; #< Can also define on a #next-server 192.168.69.104; # client-by-client basis } }}} # Restart DHCP server `sudo service isc-dhcp-server restart` ==Ubiquiti EdgeRouter Lite== # Login to router via ssh, enter configure more {{{ lang=bash configure }}} # Add `bootfile-server` to DHCP config {{{ lang=bash edit service dhcp-server shared-network-name dlasley.net subnet 192.168.69.0/24 set bootfile-server 192.168.69.100 }}} # Add `filename` options to DHCP config. **Make sure to encapsulate the file path in `"`** {{{ lang=bash set subnet-parameters "filename "/pxe-boot/pxelinux.0";" }}} # Commit and save {{{ lang=bash commit save }}} ------- = Storing/Deploying Images (Optional)= # Compress base image for storage {{{ tar cvpjf base-cluster-image.tar.bz2 ./base-cluster-image rm -Rf ./base-cluster-image }}} # Extract base image {{{ tar xvpfj ./base-cluster-image.tar.bz2 -C ./ }}} # Rename folder {{{ mv ./base-cluster-image ./cluster-0 }}} # Setup the hostname (replace `base-cluster-image` with your hostname) {{{ echo cluster-0 > ./cluster-0/etc/hostname
}}}

# Setup hosts file `nano /etc/hosts` (note 127.0.1.1 is now cluster-0 instead of base-cluster-image)
{{{
127.0.0.1 localhost
127.0.1.1 cluster-0
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
}}}
——-
= Booting (On The Client) =

# Setup BIOS to boot from NIC

# Client should get net config from DHCP server, download pxe file from TFTP server, then begin booting

## If permissions issues arise, it may be acls. Try:

{{{
sudo setfacl -bR /pxe-boot/
}}}
——-
=Add Swap Space (Optional)=
You can add swap space using either a network share, or an external device (flash drive)
==Network Share==
This will create swap space on the network share
# On the booted client
{{{
sudo apt-get install dphys-swapfile #< Install, sets up swap at `/var/swap` that is 2x current RAM (or 2048MB per default config) sudo losetup /dev/loop0 /var/swap #< Set up and control loop devices (swap) sudo swapon /dev/loop0 #< Enable for paging and swapping }}} # Run top to verify that you have swap space. {{{ KiB Swap: 2097148 total, 0 used, 2097148 free, 1462084 cached }}} # Make the change permanent. {{{ sudo nano /etc/fstab }}} {{{ /dev/loop0 none swap sw 0 0 #< Add this }}} ==External Device== This will create swap space on an external device # Umount the drive {{{ sudo umount /media/mounted_swap }}} # Find the device with fdisk. For the purposes of this article, I will be using /dev/sdc1 {{{ sudo fdisk -l }}} # Write the swap file to the device {{{ sudo mkswap /dev/sdc1 }}} # Activate the swap device. {{{ sudo swapon –p 32767 /dev/sdc1 }}} # Run top to verify that you have swap space. {{{ KiB Swap: 2097148 total, 0 used, 2097148 free, 1462084 cached }}} # Make the change permanent. {{{ sudo nano /etc/fstab }}} {{{ /dev/sdc1 none swap sw 0 0 #< Add this }}} ------- = Credits = * [[https://help.ubuntu.com/community/PXEInstallMultiDistro|PXEInstallMultiDistro]] * [[https://help.ubuntu.com/community/DisklessUbuntuHowto|DisklessUbuntuHowTo]] * [[https://help.ubuntu.com/community/PXEInstallServer|PXEInstallServer]] * [[https://help.ubuntu.com/community/Installation/OnNFSDrive|OnNFSDrive]] * [[http://www.syslinux.org/wiki/index.php/PXELINUX|PXE Linux]] * Various manpages ;)


Posted

in

by

Comments

12 responses to “Setup PXE Server Ubuntu”

  1. Olive R. Avatar

    Hi,
    Can this be used for windows client?
    I mean the server is ubuntu and the clients are windows XP..
    Thanks in advance :)

    1. dlasley Avatar

      This tutorial is compatible with Linux clients only. I’m not exactly sure of a way to boot a Windows client via PXE without a Windows server.

  2. khaleel Avatar
    khaleel

    Hi ,
    I am doing diskless booting . i can’t able to mount the file system which we gave in default file in pxelinux.cfg folder.

    Let me eloborate my question

    I am having two computers . one acts like server and other acts like client. I am having linux kernel image in server. and i configured my dhcp.conf file in server as follows

    # DHCP Server Configuration file.
    # see /usr/share/doc/dhcp*/dhcpd.conf.sample
    allow booting;
    allow bootp;

    use-host-decl-names on;
    ddns-update-style interim;
    ignore client-updates;
    next-server 172.16.6.238;

    subnet 172.16.6.0 netmask 255.255.255.0 {
    option subnet-mask 255.255.255.0;
    range dynamic-bootp 172.16.6.10 172.16.6.254;
    default-lease-time 21600;
    max-lease-time 43200;
    option domain-name-servers 127.0.0.1;
    option routers 172.16.6.1;
    filename “pxelinux.0”;
    }

    host pxe_client {
    hardware ethernet 7client mac address; #client mac address
    fixed-address 172.16.6.237;
    }

    group {
    next-server 172.16.6.238; # our Server
    host tftpclient {
    filename “pxelinux.0”;
    }
    }

    my client is getting correct ip-address

    It able to load the kernel which is present in server

    problem is client can’t able to mount the filesystem while booting , where the filesystem is present in server . my kernel boot arguments are

    default openwrt
    label openwrt
    kernel openwrt-x86-generic-vmlinuz
    append boot=nfs root=/dev/nfs nfsroot=172.16.6.237:/nfsroot ip=dhcp rw

    my client is not mounting the file system while booting

    Please give me required suggestions

    1. dlasley Avatar

      You are missing the initrd declaration in the kernel boot arguments. Initrd loads the root file system into memory during the Kernel boot process; not having this is likely causing the issue. Try adding the initrd declaration; and if that doesn’t work, what error message are you receiving from the client?

  3. Wrenaqua Avatar
    Wrenaqua

    Hiya, im pretty much a newbie tro ubuntu, but tried setting up this server by following all the instructions,
    i executed
    Download base system via debootstrap to pxe-boot/images/base-cluster-image. Add desired packages to the include parameter. This will take a while..you can continue with the other sections in another screen session if you want to save time. You can also change the arch or distribution (quantal) to fit your desired setup.

    sudo debootstrap –variant=minbase –include=procps,screen,passwd,less,nano,bash,nfs-common \
    –arch amd64 quantal /pxe-boot/images/base-cluster-image http://archive.ubuntu.com/ubuntu

    and then tried sudo chroot /pxe-boot/images/base-cluster-image/
    but now i get the error
    chroot: failed to run command `/bin/bash’: Exec format error
    what am i doin wrong? plz help and thnx in advance

    1. David Lasley Avatar

      Hi, and thanks for reading my blog! There could be a few possibilities here, but the error basically means that your jail doesn’t have a shell or some other required library. My immediate thought is that the host server is 32-bit and the chroot is 64-bit. What is the output of `uname -a` on the server?

  4. Ferrets Avatar
    Ferrets

    Hi, I’ve read your blog and it did great help for me. But I’ve met something weird, stuck me at the boot process.
    It seems happened at the nfs mount, my whole screen filled with
    Begin: Retrying nfs mount ... Begin: Running /scripts/nfs-premount ... done.
    mount call failed - server replied: No such file or directory.
    Begin: Retrying nfs mount ... Begin: Running /scripts/nfs-premount ... done.
    mount call failed - server replied: No such file or directory.
    Begin: Retrying nfs mount ... Begin: Running /scripts/nfs-premount ... done.
    mount call failed - server replied: No such file or directory.
    Begin: Retrying nfs mount ... Begin: Running /scripts/nfs-premount ... done.
    mount call failed - server replied: No such file or directory.
    Begin: Retrying nfs mount ... Begin: Running /scripts/nfs-premount ... done.
    mount call failed - server replied: No such file or directory.
    Begin: Retrying nfs mount ... Begin: Running /scripts/nfs-premount ... done.
    mount call failed - server replied: No such file or directory.
    Begin: Retrying nfs mount ... Begin: Running /scripts/nfs-premount ... done.
    mount call failed - server replied: No such file or directory.

    I’ve do some google but it doesn’t help, do you have any ideas about how to fix it?

    1. Ferrets Avatar
      Ferrets

      A~ what a shame, according to my nfs server log, I’ve found that I typed in the wrong path in the configuration file. It works now. Thank you.

      1. Dave Lasley Avatar

        I’m happy to hear that you got it up and running. This is a tricky process, no doubt ;)

  5. John Avatar

    Dave – great tutorial, thanks for the writeup. I have an EdgeRouter Lite; is the Linux DHCP is necessary since I am using the ERL as my DHCP server? I guess I am confused with having two DHCP servers on the network and how to de-conflict, or am I missing something?

    1. Dave Lasley Avatar

      Nope – no need for two DHCPs, the ERL is perfectly fine. I should have specified that the DHCP section is an either/or – updating now!

  6. John Avatar

    Awesome, thanks!

Leave a Reply to John Cancel reply

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