<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="generator" content="ReText 4.1.2">
<title>PXE_on_Ubuntu</title>
<style>
pre {
        margin-left: 2em;
}

code {
        color: blue;
}
</style>
</head>
<body>
<h1>Setting up a PXE Server on Ubuntu</h1>
<h2>Firewall requirements</h2>
<p>You will be doing this on an internal network so firewall security shouldn't need to be too srtringent. That being said if you want to be sure, you need to allow INPUT on at least port 69 (tftpd) and the file server port (80 for the example below, served over HTTP), and port 67 (DHCP)</p>
<p>Note that the IP <code>192.168.1.199</code> represents the IP of the PXE server we are configuring. Where encountered, replace it with the appropriate IP</p>
<p>If this is a VM, you need to ensure this is on a Bridged adapter, so that other machines can see the VM directly. These notes presume you are using bridged.</p>
<h2>Install required packages</h2>
<pre><code>apt install isc-dhcp-server tftp tftpd apache2 syslinux
</code></pre>
<p>The DHCP server allows the target PXE client to get an IP from our server specifically - not sure if this is a requirement for the PXE broadcast to be recognized...</p>
<p>TFTP is a lightweight implementation of a subset of FTP to allow minimal code to be implemented for embedded firmware, or that is what I understand. PXE boot specifically looks for TFTP, not regular FTP, so this is a requirement.</p>
<p>Apache is selected here as the means by which we will be serving the installation files over the internal network.</p>
<p>syslinux contains a set of bootloaders, some of which we want for creating our setup.</p>
<h2>Configure DHCP</h2>
<p>Edit <code>/etc/dhcp/dhcp.conf</code></p>
<p>Add the following near the top; comment out any conflicting items in the file.</p>
<pre><code>ddns-update-style interim;
ignore client-updates;
authoritative;
allow booting;
allow bootp;
allow-unknown-clients;

subnet 192.168.1.0 netmask 255.255.255.0 {
    range 192.168.1.200 192.168.1.250;
     # our IP:
    option domain-name-servers 192.168.1.199;
    option domain-name "mydomain.home";
    # client to route traffic via this pxe server
    option routers 192.168.1.199;
    default-lease-time 600;
    max-lease-time 7200;

    # not quite sure what this does...
    next-server 192.168.1.199;
    filename "pxelinux.0";
}
</code></pre>
<h2>Setup TFTPd service via xinetd</h2>
<p>Edit <code>/etc/xinetd.d/tftp</code></p>
<p>Change disabled option to "no", and set the server_args to <code>-s /tftpboot</code> (or other location desired)</p>
<p>If it does not exist, simply create it:</p>
<pre><code># default: off
# description: The tftp server serves files using the Trivial File Transfer
#    Protocol.  The tftp protocol is often used to boot diskless
#    workstations, download configuration files to network-aware printers,
#    and to start the installation process for some operating systems.
service tftp
{
    socket_type     = dgram
    protocol        = udp
    wait            = yes
    user            = root
    server          = /usr/sbin/in.tftpd
    server_args     = -s /tftpboot
    disable         = no
}
</code></pre>
<h2>Create the TFTP contents</h2>
<pre><code>mkdir /tftpboot
chmod 777 tftpboot
cp -v /usr/lib/syslinux/{pxelinux.0,menu.c32,memdisk,mboot.c32,chain.c32} /tftpboot
mkdir /tftpboot/pxelinux.cfg
mkdir /tftpboot/netboot
</code></pre>
<h2>Get the DVD contents</h2>
<p>Create a location in the web server for the distro</p>
<pre><code>mkdir /var/www/html/ubuntu15.04
# for example.
</code></pre>
<p>You can either mount the DVD in-place</p>
<pre><code>mount -o loop ./path/to/dvd/iso /var/www/html/ubuntu15.04
</code></pre>
<p>Or you can full-on copy the contents as appropriate</p>
<pre><code>mount -o loop ./path/to/dvd.iso /mnt
cp -rv /mnt/* /var/www/html/ubuntu15.04
umount /mnt
</code></pre>
<p>Check that you have the <code>/mnt/dists</code> directory as provided by the DVD. If you do not, you will need to copy them through from the same architecture and release DVD for Ubuntu Server</p>
<h2>Get the network boot kernel and image</h2>
<p>For Ubuntu images, you want the vmlinuz and initrd files from mini.iso corresponding to your distribution. See the Ubuntu website, download the mini.iso from there.</p>
<p><a href="https://help.ubuntu.com/community/Installation/MinimalCD">https://help.ubuntu.com/community/Installation/MinimalCD</a></p>
<p>It needs to be the matching release and architecture as your target PXE Ubuntu</p>
<pre><code>mkdir /tftpboot/mini15.04
mount ./path/to/mini.iso /mnt
cp /mnt/{linux,initrd.gz} /tftpboot/mini15.04
umount /mnt
</code></pre>
<h2>Make a kickstart file</h2>
<p>This allows the unattended install of the system</p>
<p>Edit <code>/var/www/ubuntu15.04/ks.cfg</code></p>
<p>Note - the URL must specify the IP address - using the server's network name will likely fail without extra DNS setup</p>
<pre><code>install
lang en_GB.UTF-8
keyboard uk
timezone Europe/London
auth --useshadow --enablemd5
services --enabled=NetworkManager, sshd
eula --agreed
url --url="http://192.168.1.199/ubuntu15.04"

bootloader --location=mbr
zerombr
clearpart --all --initlabel
part swap --asprimary --fstype="swap" --size=1024
part /boot --fstype xfs --size=200
part pv.01 --size=1 --grow
volgroup rootvg01 pv.01
logvol / --fstype xfs --name=lv01 --vgname=rootvg01 --size=1 --grow
rootpw --iscrypted $1$hw4S1wQ8$0GDzXkLWhlSQ.F8YsBO.n/

%packages --nobase --ignoremissing
@core
%end
</code></pre>
<p>Ensure it can be read by the web server</p>
<pre><code>chmod a+r /var/www/ubuntu15.04/ks.cfg
</code></pre>
<h2>Create a PXE boot menu</h2>
<p>Edit <code>/tftpboot/pxelinux.cfg/default</code></p>
<pre><code>default menu.c32
prompt 0
timeout 100
MENU TITLE My PXE Menu

LABEL ubuntu1504
MENU LABEL Ubuntu 15.04
KERNEL mini15.04/linux
APPEND initrd=mini15.04/initrd.gz instrepo=http://192.168.1.199/ubuntu15.04 ks=http://192.168.1.199/ubuntu15.04/ks.cfg boot=casper
</code></pre>
<h2>Restart the services</h2>
<pre><code>service isc-dhcpd-server restart
service xinetd restart
</code></pre>
<h1>Configure the client</h1>
<p>For VirtualBox, the following should be sufficient</p>
<ul>
<li>New VM<ul>
<li>Create the VM with the desired specifications.</li>
</ul>
</li>
<li>System: Boot Order needs network turned on<ul>
<li>For a physical machine, you may need to do this in the BIOS</li>
</ul>
</li>
<li>Network: bridged</li>
</ul>
<p>Now start the machine</p>
<ul>
<li>Start VM</li>
<li>Cancel attach ISO</li>
</ul>
<p>This should give us the option to start from the menu we defined earlier</p>
<p>This starts everything we wanted.... the installer is shown, but options are applied automatically</p>
<h1>Troubleshooting</h1>
<p>These are issues I faced when testing which I resolved.</p>
<p>When the Ubuntu server installer encounters an error, you can see details on tty4</p>
<ul>
<li>
<p>If your machine does not boot from PXE, or complains that no boot medium is found, powercycle it. For some reason, sometimes the PXE broadcast is not detected - this could be a network interference, but I'm not sure how the PXE server makes itself known to the client...</p>
</li>
<li>
<p>If you manage to get the PXE menu but it just repeats the countdown ad infinitam, check for typos in the boot menu <code>/tftpboot/pxelinux.cfg/default</code></p>
</li>
<li>
<p>If the installer complains about "Bad mirror" (can't find archive), check that you are indeed using the server's IP address not its name</p>
</li>
<li>
<p>If the installer complains about "Bad mirror" (can't find archive), check that you have <code>/var/www/html/ubuntu15.04/dists/vivid/Release</code> (or trusty, precise, etc as appropriate)</p>
</li>
</ul>
<h1>Known issues</h1>
<ul>
<li>
<p>I don't know how to add extra options to the kickstart file - not sure where it's properly documented, but I will find this out and send on</p>
</li>
<li>
<p>Ubuntu installation fails at "Install the system" step; from what I find on mailing lists, there's an issue with apt trying to get files from the repository under the "security" section (not included on the DVD), and so the installer bails. Need to deactivate this, or redirect this.</p>
</li>
</ul>
</body>
</html>