Since posting this article I have found a much easier way to do this. This article is still great background information and goes into more detail if you want to take this further, but you should consider reading my new article.
Well, I promised something technical and here it is. It’s turned into a bit of a mammoth post, but the end result is pretty cool!
The idea of being able to install your favourite Linux distro over the network and so do away with burning CD’s (which ultimately get used once and then thrown away) is tantalizing. Not to mention the serious geek points for anyone who has a boot server on their network.
I started out using this article as a reference, as the process seemed relatively simple. However, I soon found out that this article wasn’t strictly accurate and didn’t explain some things too brilliantly! So I decided to see if I could do better.
The following is my account of setting up my own boot server on a spare box I had lying around (though you can just as easily do it on your main computer). I started from a base install of Ubuntu Server 8.10 (Intrepid Ibex) which I installed in the normal way (i.e. from a CD).
Prerequisites
Once my server was up and running and I could ssh into it, the fun really started. The article I linked to above tells you what you need, namely:
- A dhcp server (sudo apt-get install dhcp3-server)
- An Ubuntu CD image (the alternate CD not the live CD one, though presumably the server version works too).
- A TFTP server (more on this below)
- A web server, such as apache (sudo apt-get install apache2)
Out of those, only the TFTP server caused me problems, I dutifully installed the suggested package (tftpd), only to find much later that it didn’t support one of the options needed by the bootloader. To avoid this use the tftpd-hpa package instead (sudo apt-get install tftpd-hpa).
What happens…
At this stage, it might help if I run through the actual netbooting process as this will give you a general understanding of what we need to configure:
- When you choose the netboot option on the machine you want to boot (usually in the boot order settings in the bios), the bios will run a small program stored in on the motherboard (PXE-ROM). This program is essentially a DHCP client, which sends out broadcasts on the network looking for someone to provide it with an IP address and information on what to do next.
- The DHCP server on your network respond to the broadcast and dishes out an IP address to the client. It also passes it the IP address of a boot server and the name of the bootloader file to request.
- The client contacts the boot server (which can actually be the same machine as the DHCP server) and requests the bootloader file and executes it.
- The bootloader loads it’s configuration from the server and displays a menu of the boot options.
- When the user selects an option, the bootloader requests the kernel and initrd images from the server and boots the kernel.
Our kernel will run the Ubuntu installer so that we can install an Ubuntu system on the client machine, but to get the packages we will use apache to serve them out for us across the network.
Let’s get down to it
OK, let’s configure some stuff, first up is the DHCP server. Here’s my configuration:
default-lease-time 600;
max-lease-time 7200;
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.1.255;
option routers 192.168.1.3;
option domain-name-servers <ns1>, <ns2>;
option domain-name "mydomain.com";
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.2 192.168.1.51;
}
next-server 192.168.1.5;
filename "pxelinux.0";
This goes in /etc/dhcp3/dhcpd.conf (sudo nano /etc/dhcp3/dhcpd.conf). I’m actually only going to expalin the last two lines (the rest is pretty standard DHCP stuff which you can find out about somewhere else. The last two lines are expalined below:
- next-server 192.168.1.5; – gives the client the address of your boot server, in most cases this will be the same as your DHCP server address (I’m running all this on my one server box). Change the address to the address of the machine you want to use.
- filename “pxelinux.0”; – the bootloader file to use, just leave this as it is.
Once you’ve done that, restart the DHCP server with ‘sudo /etc/init.d/dhcp3-server restart’. Also if you’re running a commercial (wireless) router, you’ll need to disable the DHCP server on the router from it’s control panel.
TFTP or not TFTP
The TFTP server needs very little configuration. All I did was create directory in the root of my filesystem to serve from:
sudo mkdir /tftpboot
Then you just need to make sure that tftpd serves from that directory (I spent ages wondering why mine wasn’t working because of this!), by changing the ftpd line in /etc/inetd.conf to:
tftp          dgram  udp    wait   root /usr/sbin/in.tftpd /usr/sbin/in.tftpd -s /tftpboot
(I basically changed the path at the end). Then restart the inetd service (sudo /etc/init.d/openbsd-inetd restart).
Serving the iso files from Apache
Now we’re going to copy everything out of the iso image to somewhere that Apache can find it:
sudo mkdir -p /var/www/netinstall/ubuntu8.10-alternate
sudo mount -o loop ubuntu-8.10-alternate.iso /mnt
sudo cp -a /mnt/* /var/www/netinstall/ubuntu8.10-alternate/
sudo umount /mnt
First, we made the required directories to serve our files from. Structuring the directories like this allows us to serve other versions out from the same server if we want to. Secondly, we mounted the iso file on the /mnt directory, then we copied all the files from that to our server directory and finally unmounted the iso image.
If you now go to http://<serveraddress>/netinstall/ubuntu8.10-alternate, you should see a listing of the files that were on the CD. That was easy, let’s move on.
The elusive pxelinux.0
You should recognise ‘pxelinux.o’ from the filename perameter in the DHCP config above, this is the bootloader that loads our kernel. Unfortunately, I couldn’t find it (and the other article gave me no clue!). I eventually found it in the files I copied from the iso (I’ve since learned that you can also get it from the ‘syslinux’ package). To copy it to the correct place use:
sudo cp /var/www/netinstall/ubuntu8.10-alternate/install/netboot/pxelinux.0 /tftpboot/
Next we need a kernel and initrd image we’ll also get these from the files we just copied:
sudo mkdir /tftpboot/ubuntu8.10-alternate
sudo cp /var/www/netinstall
/ubuntu8.10-alternate/install/netboot/ubuntu-installer/i386/linux /tftpboot/ubuntu8.10-alternate/
sudo cp /var/www/netinstall
/ubuntu8.10-alternate/install/netboot/ubuntu-installer/i386/initrd.gz /tftpboot/ubuntu8.10-alternate/
Now we need to configure pxelinux to find our kernel, the configuration goes in /tftpboot/pxelinux.cfg/default:
default 1
timeout 200
prompt 1
display pxelinux.cfg/msgs/boot.msg
# begin list of available boot options
# Local hard disk boot
label 1
localboot 0
# Ubuntu 8.10 Alternate install CD
label 2
kernel ubuntu8.10-alternate/linux
append initrd=ubuntu8.10-alternate/initrd.gz
The first two lines select the default boot entry (see below) to use and give us a timeout of 20 seconds after which that option will be selected (the timout value is measure in tenths of a second). The next two display a menu of the available kernels (which goes in /tftpboot/pxelinux.cfg/msgs/boot.msg).
Next we have our boot entries. Each of these have a label line which enables us to identify the listing later. The first listing just has a directive telling pxelinux to boot from the local hard disk. As this option is selected as the default (above) the computer will attempt to boot from it’s hard disk once the timout has occured.
The second listing is more interesting, we have the kernel directive with the path relative to the /tftpboot/ directory, this tells pxelinux what kernel should be booted if this option is selected (duh!). We have the append line, which adds options to the kernel, in this case we tell it to use our initrd image, but you can add any valid kernel option. Obviously this file can have as many listing as you want to give boot options, there’s also support for multiple different menu’s and help screen, but I’m keeping it at this for now.
OK, now all we need is our display message. I put mine in the msgs directory (mkdir /tftpboot/pxelinux.o/msgs) and put this in the file (boot.msg):
^Y^LÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ^O0fNETWORK BOOT OPTIONS^O07
Select one of the options below, or press enter for the default:
1 - Local Hard disk boot [Default]
2 - Install Ubuntu 8.10 'Intrepid Ibex'
NB: Default will be selected after 20 seconds
That’s it! Just make sure the bit before the hyphen matches the label field we used above, so that the user knows what to type at the prompt. The funny characters in the file correspond to specially interpreted charaters for clearing the screen, etc. I just copied them from another file!
Booting Clients
The first client I tried to boot was my ASUS EeePC 901. I succesfully configured the bios to boot from the network and got to the menu screen. Booting the Ubuntu kernel worked and I was able to get into the installer, however a few steps in it told me that my ethernet adaptor was unsupported so it was unable to get packages for installation. Apparently, the next version of Ubuntu (Jaunty) is going to have the driver included by default in it’s kernel, so maybe that’ll work (I’ll try it at some point and report back).
Next I decided it would be cool to try and boot a virtual machine from my network. Having done some research I found that if I used VirtualBox with host networking I should be able to get an IP address from my network (rather than VirtualBox’s build in DHCP) and so boot from the network. I currently had the Open Source edition of VirtualBox installed, which is an older version (2.04) which doesn’t support host based networking without a lot of fiddling around.
I decided to take the easy way out and upgraded to version 2.1 via the VirtualBox repository. Once this was installed I was able to select ‘Host Network Interface’ in the virtual machine network settings and then select eth0 as my interface. In the advanced settings I set network as the first boot device and then booted the machine:
As you can see from the screenshot, this worked just fine, as did proceeding to the installer. When I reached the step in the install which asked me to select a mirror I scrolled up and selected ”. On the next few screens I had to enter information about the server I was using, namely the IP address (192.168.1.5) and the path to the repository (/netinstall/ubuntu8.10-alternate/). See the screenshots below for details:
The rest of the install proceeded just fine, with the packages being retrieved and installed from the network. I ended up with a functional desktop system (in a virtual machine) just as I would get if I had used a CD.
Next Steps…
Wow, that turned out to be pretty long. Hopefully you’ve made it this far and I’ve managed to help you get to grips with this. I still have a few things I want to try to setup with this and I’ll report back if I make any progress:
- It would be really great to have Clonezilla and/or some kind of rescue toolkit distribution available for booting over the network, that way I can just plug in a machine and boot up whatever I need.
- I eventually want to have a go at making a completely diskless system, which doesn’t look that difficult as I seem to have done most of the work. Ideally it would be nice to be able to install/design a system in a virtual machine on my desktop and then deploy it across the network when it’s ready!
I hope you’ve enjoyed this How-To and have found it informative, if you have any problems, corrections or just want to say thanks, feel free to post a comment. Bye for now!
Leave a Reply