Difference between revisions of "R-Pi PXE Server"

From eLinux.org
Jump to: navigation, search
m (Configuring the DHCP server on the RPi)
m (Added text describing skill level)
 
(11 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
Back to [[RPi Projects]].
 +
 +
 
'''Classroom boot server'''
 
'''Classroom boot server'''
  
Line 6: Line 9:
  
 
As yet, I have not decided on Fedora or Debian, so the instructions are a bit of a mix at the moment.
 
As yet, I have not decided on Fedora or Debian, so the instructions are a bit of a mix at the moment.
 
  
  
Line 12: Line 14:
 
=What does it do?=
 
=What does it do?=
  
This server allows your to use cheap PCs in a classroom/library/café which do not have their own hard disks. When the PCs are turned on, they will fetch the boot information from a PXE/netboot server. The major advantage is that the cost of each PC is reduced because individual hard disks are not needed. Also, there is no information stored locally on each PC for the user to tamper with. If the user messes up a PC, just reboot the PC to return to normal.
+
This server allows you to run a number of networked PCs, each without its own hard disk, in a classroom/library/café. When the PCs are turned on, they will fetch the boot information from a PXE/netboot server. The cost of each PC is reduced because individual hard disks are not needed. Also, there is no information stored locally on each PC for the user to tamper with - if the user messes up a PC, just reboot the PC to return to normal.
  
 
=What do you need?=
 
=What do you need?=
Line 19: Line 21:
 
*A boot SD card for the Raspberry Pi. [What size? Needs to hold ISO image]
 
*A boot SD card for the Raspberry Pi. [What size? Needs to hold ISO image]
 
*An Ethernet cable to connect to the local network.
 
*An Ethernet cable to connect to the local network.
 +
 +
=What skill level is required?=
 +
 +
This project does not require and coding or compilation. Very basic Linux and networking knowledge would be useful, but not essential.
 +
 +
You need to...
 +
*Edit configuration files on the RPi
 +
*Change a BIOS configuration parameter on each PC
 +
*Find and download a boot CD image from the internet (easier for Linux than for Windows)
 +
*Join computers together using ethernet cables
  
 
=How does it work?=
 
=How does it work?=
Line 79: Line 91:
 
   option time-offset -8;
 
   option time-offset -8;
 
  }
 
  }
 +
 
  host llama0
 
  host llama0
 
  {
 
  {
Line 94: Line 107:
 
2A alt 2) Create /etc/dhcpd.conf with the following contents:
 
2A alt 2) Create /etc/dhcpd.conf with the following contents:
  
option domain-name-servers 192.168.0.1;
+
option domain-name-servers 192.168.0.1;
default-lease-time 3600;
+
default-lease-time 3600;
max-lease-time 4800;
+
max-lease-time 4800;
authoritative;
+
authoritative;
 
+
subnet 192.168.0.0 netmask 255.255.255.0 {
+
subnet 192.168.0.0 netmask 255.255.255.0
        range 192.168.0.70 192.168.1.100;
+
{
        filename "pxelinux.0";
+
  range 192.168.0.70 192.168.1.100;
        next-server 192.168.0.50;
+
  filename "pxelinux.0";
        option subnet-mask 255.255.255.0;
+
  next-server 192.168.0.50;
        option broadcast-address 192.168.0.255;
+
  option subnet-mask 255.255.255.0;
        option routers 192.168.0.1;
+
  option broadcast-address 192.168.0.255;
}
+
  option routers 192.168.0.1;
 +
}
  
 
Here we've configured the server to give out IP addresses from the range 192.168.0.70-100, set the default gateway to be 192.168.0.1
 
Here we've configured the server to give out IP addresses from the range 192.168.0.70-100, set the default gateway to be 192.168.0.1
Line 115: Line 129:
  
 
Command:
 
Command:
service dhcpd start
+
service dhcpd start
  
 
==Configuring the tftp server on the RPi==
 
==Configuring the tftp server on the RPi==
Line 157: Line 171:
  
 
The first 8 are the hex representation of the 192.168.0.254 IP address that your PXE boot client will be assigned. The permutations allow a broader IP subnet to be searched first for matches. The last entry is the MAC address of your PXE boot client's NIC (with dashes substituted for the colons), with '01' pre-pended. The "01" at the front represents a hardware type of Ethernet, so pxelinux.0 see's the configuration string as an IP address.
 
The first 8 are the hex representation of the 192.168.0.254 IP address that your PXE boot client will be assigned. The permutations allow a broader IP subnet to be searched first for matches. The last entry is the MAC address of your PXE boot client's NIC (with dashes substituted for the colons), with '01' pre-pended. The "01" at the front represents a hardware type of Ethernet, so pxelinux.0 see's the configuration string as an IP address.
 +
 +
[Question: Why bother with the MAC? This will limit the solution to a single PC and is useless in a classroom. Much better to boot by IP subnet, probably a 192.168.0.0/24 subnet would be perfect]
  
 
3F) Now create the default pxelinux configuration inside the new file /tftpboot/pxelinux.cfg/default:
 
3F) Now create the default pxelinux configuration inside the new file /tftpboot/pxelinux.cfg/default:
Line 163: Line 179:
 
  default linux
 
  default linux
 
  timeout 100
 
  timeout 100
 
+
 
  label linux
 
  label linux
 
  kernel vmlinuz
 
  kernel vmlinuz
 
  append initrd=initrd.img ramdisk_size=9216 noapic acpi=off
 
  append initrd=initrd.img ramdisk_size=9216 noapic acpi=off
 
  
 
==Configuring the web server on the RPi==
 
==Configuring the web server on the RPi==
Line 185: Line 200:
  
 
==Test with a single PC==
 
==Test with a single PC==
 +
 +
[These instructions need a switch between the PC and the PXE server. But the RPi has an auto-sensing NIC, so a simple ethernet cable could be used instead]
  
 
5A) At this stage, you're ready to hook up the switch. You should have CAT5 running between the switch & the PXE boot server, and the client box.
 
5A) At this stage, you're ready to hook up the switch. You should have CAT5 running between the switch & the PXE boot server, and the client box.
Line 196: Line 213:
 
5E) If you run into any problems, check /var/log/messages for errors (that's where all dhcp & tftp stuff will get logged). /var/log/httpd is where apache logs, but if you get that far, your problem is an apache configuration/setup issue, and not a PXE boot issue.
 
5E) If you run into any problems, check /var/log/messages for errors (that's where all dhcp & tftp stuff will get logged). /var/log/httpd is where apache logs, but if you get that far, your problem is an apache configuration/setup issue, and not a PXE boot issue.
  
 
 
 
=Extra useful text=
 
=Extra useful text=
 
From http://www.debian-administration.org/articles/478
 
From http://www.debian-administration.org/articles/478
 +
 +
[This Debian-based instruction uses dynamic ip allocation and does not depend on the MAC address]
  
 
If you're looking to perform a lot of system recovery, or system installation, then network booting with PXE is ideal. PXE allows you to boot up a system and have it automatically get an IP address via DHCP and start booting a kernel over the network.
 
If you're looking to perform a lot of system recovery, or system installation, then network booting with PXE is ideal. PXE allows you to boot up a system and have it automatically get an IP address via DHCP and start booting a kernel over the network.
 +
 
PXE itself stands for "Pre-boot eXecution Environment", which describes how it works in the sense that the clients using it haven't booted in a traditional manner.
 
PXE itself stands for "Pre-boot eXecution Environment", which describes how it works in the sense that the clients using it haven't booted in a traditional manner.
 +
 
In order to use PXE you need to setup a boot-server which will allow client systems to :
 
In order to use PXE you need to setup a boot-server which will allow client systems to :
Request an IP address (via DHCP)
+
*Request an IP address (via DHCP)
Download a kernel (via TFTP)
+
*Download a kernel (via TFTP)
 +
 
 
With both of these services in place any system which supports PXE/network-booting (you might need to enable it in the BIOS) should be able to gain an IP address, fetch a kernel, and boot without an installed operating system.
 
With both of these services in place any system which supports PXE/network-booting (you might need to enable it in the BIOS) should be able to gain an IP address, fetch a kernel, and boot without an installed operating system.
 +
 
(This is ideal for systems which can't be booted by a traditional approach; for example your new AMD-64 system which doesn't have a CD/DVD drive!)
 
(This is ideal for systems which can't be booted by a traditional approach; for example your new AMD-64 system which doesn't have a CD/DVD drive!)
 +
 
Our Setup
 
Our Setup
 +
 
For the purposes of this article we'll assume:
 
For the purposes of this article we'll assume:
 
• We're working with a small network 192.168.1.0/24
 
• We're working with a small network 192.168.1.0/24
Line 214: Line 237:
 
• Our "boot-server" is the host "itchy" with IP address 192.168.1.50
 
• Our "boot-server" is the host "itchy" with IP address 192.168.1.50
 
• We will serve the same kernel to each host.
 
• We will serve the same kernel to each host.
 +
 
In our example we'll configure a PXE-server which will allow remote systems to run the Debian Etch installer, but nothing here is specific to that. PXE allows you to configure a system to boot from an arbitrary kernel (and matching ramdisk if you wish to use one). With the correct configuration you can even cause the clients to mount a remote file-system via NFS and have a diskless thin-client system.
 
In our example we'll configure a PXE-server which will allow remote systems to run the Debian Etch installer, but nothing here is specific to that. PXE allows you to configure a system to boot from an arbitrary kernel (and matching ramdisk if you wish to use one). With the correct configuration you can even cause the clients to mount a remote file-system via NFS and have a diskless thin-client system.
 +
 
TFTP Setup
 
TFTP Setup
 +
 
TFTP is a very simple file-transfer protocol, which is very similar to FTP but which doesn't use any kind of authentication. If you're not already running a TFTP server you can install one by running:
 
TFTP is a very simple file-transfer protocol, which is very similar to FTP but which doesn't use any kind of authentication. If you're not already running a TFTP server you can install one by running:
root@itchy:~# apt-get install tftpd-hpa
+
 
 +
root@itchy:~# apt-get install tftpd-hpa
 +
 
 
Once installed you'll need to enable it by editing the file /etc/default/tftpd-hpa. You should change RUN_DAEMON to yes, leaving you with contents like these:
 
Once installed you'll need to enable it by editing the file /etc/default/tftpd-hpa. You should change RUN_DAEMON to yes, leaving you with contents like these:
#Defaults for tftpd-hpa
+
 
RUN_DAEMON="yes"
+
#Defaults for tftpd-hpa
OPTIONS="-l -s /var/lib/tftpboot"
+
RUN_DAEMON="yes"
 +
OPTIONS="-l -s /var/lib/tftpboot"
 +
 
 
Now create the root directory, if it is missing, and start the server:
 
Now create the root directory, if it is missing, and start the server:
root@itchy:~# mkdir -p /var/lib/tftpboot
+
 
root@itchy:~# /etc/init.d/tftpd-hpa start
+
root@itchy:~# mkdir -p /var/lib/tftpboot
Starting HPA's tftpd: in.tftpd.
+
root@itchy:~# /etc/init.d/tftpd-hpa start
 +
Starting HPA's tftpd: in.tftpd.
 +
 
 
Once our systems have retrieved an IP address via DHCP they will request files from beneath the /var/lib/tftpboot root directory. We'll come back to the contents of this directory shortly.
 
Once our systems have retrieved an IP address via DHCP they will request files from beneath the /var/lib/tftpboot root directory. We'll come back to the contents of this directory shortly.
 +
 
DHCP Setup
 
DHCP Setup
 +
 
If you don't already have a DHCP server configured upon your LAN you'll need to install one. If you're using a small home router, or similar, to provide local DHCP services you must disable this first. (Since we require the DHCP server to pass back some extra options to clients which the majority of routers won't allow).
 
If you don't already have a DHCP server configured upon your LAN you'll need to install one. If you're using a small home router, or similar, to provide local DHCP services you must disable this first. (Since we require the DHCP server to pass back some extra options to clients which the majority of routers won't allow).
 +
 
Discussing a full DHCP installation is mostly beyond the scope of this introduction but the thing we're trying to do is fairly simple. The goal of the DHCP server in this setup is twofold:
 
Discussing a full DHCP installation is mostly beyond the scope of this introduction but the thing we're trying to do is fairly simple. The goal of the DHCP server in this setup is twofold:
 
• We obviously want to use it to allow clients to request and receive an IP address.
 
• We obviously want to use it to allow clients to request and receive an IP address.
 
• We want to cause the DHCP "answer" to give some extra details to the clients which are requesting an address:
 
• We want to cause the DHCP "answer" to give some extra details to the clients which are requesting an address:
o The address of the TFTP server.
+
The address of the TFTP server.
o The initial filename to request from the TFTP server.
+
The initial filename to request from the TFTP server.
 +
 
 
The most common DHCP server is the dhcp-server package, and you can install this by running:
 
The most common DHCP server is the dhcp-server package, and you can install this by running:
root@itchy:~# apt-get install dhcp3-server
+
 
 +
root@itchy:~# apt-get install dhcp3-server
 +
 
 
Once installed the server is configured in the file /etc/dhcp3/dhcpd.conf, and there are a lot of available options described there. For our example we'll use the following configuration:
 
Once installed the server is configured in the file /etc/dhcp3/dhcpd.conf, and there are a lot of available options described there. For our example we'll use the following configuration:
option domain-name-servers 62.31.64.39, 62.31.112.39;
 
default-lease-time 86400;
 
max-lease-time 604800;
 
authoritative;
 
  
subnet 192.168.1.0 netmask 255.255.255.0 {
+
option domain-name-servers 62.31.64.39, 62.31.112.39;
 +
default-lease-time 86400;
 +
max-lease-time 604800;
 +
authoritative;
 +
 +
subnet 192.168.1.0 netmask 255.255.255.0 {
 
         range 192.168.1.70 192.168.1.100;
 
         range 192.168.1.70 192.168.1.100;
 
         filename "pxelinux.0";
 
         filename "pxelinux.0";
Line 249: Line 288:
 
         option broadcast-address 192.168.1.255;
 
         option broadcast-address 192.168.1.255;
 
         option routers 192.168.1.1;
 
         option routers 192.168.1.1;
}
+
}
 +
 
 
Here we've configured the server to give out IP addresses from the range 192.168.1.70-100, set the default gateway to be 192.168.1.1 and use our ISP's nameservers.
 
Here we've configured the server to give out IP addresses from the range 192.168.1.70-100, set the default gateway to be 192.168.1.1 and use our ISP's nameservers.
 +
 
We've also used next-server to point to the TFTP server we're using (which is the same host as our DHCP server, but doesn't need to be). We've chosen the default name of pxelinux.0 as the name of the file for booting clients to request.
 
We've also used next-server to point to the TFTP server we're using (which is the same host as our DHCP server, but doesn't need to be). We've chosen the default name of pxelinux.0 as the name of the file for booting clients to request.
 +
 
Using dnsmasq instead
 
Using dnsmasq instead
 +
 
Personally I use the dnsmasq package to provide DHCP services upon my LAN, since this is small and simple and provides other useful abilities, setting up PXE booting with dnsmasq just requires the addition of the following line to /etc/dnsmasq.conf:
 
Personally I use the dnsmasq package to provide DHCP services upon my LAN, since this is small and simple and provides other useful abilities, setting up PXE booting with dnsmasq just requires the addition of the following line to /etc/dnsmasq.conf:
dhcp-boot=pxelinux.0,itchy,192.168.1.50
+
 
 +
dhcp-boot=pxelinux.0,itchy,192.168.1.50
 +
 
 
(Again we've setup the filename along with the name and IP address of the TFTP server which is "itchy" / 192.168.1.50 in this example)
 
(Again we've setup the filename along with the name and IP address of the TFTP server which is "itchy" / 192.168.1.50 in this example)
 +
 
Restarting the service after this change is as simple as:
 
Restarting the service after this change is as simple as:
root@itchy:~# /etc/init.d/dnsmasq restart
+
 
Restarting DNS forwarder and DHCP server: dnsmasq.
+
root@itchy:~# /etc/init.d/dnsmasq restart
 +
Restarting DNS forwarder and DHCP server: dnsmasq.
 +
 
 
PXE Configuration
 
PXE Configuration
 +
 
Now that we've configured the TFTP and DHCP servers we need to go back and complete the configuration. By default when a client boots up it will use its own MAC address to specify which configuration file to read - however after trying several options it will fall back to requesting a default file.
 
Now that we've configured the TFTP and DHCP servers we need to go back and complete the configuration. By default when a client boots up it will use its own MAC address to specify which configuration file to read - however after trying several options it will fall back to requesting a default file.
 +
 
We need to create that that file, which will contain the list of kernels which are available to boot, we'll firstly need to create a directory to hold it:
 
We need to create that that file, which will contain the list of kernels which are available to boot, we'll firstly need to create a directory to hold it:
root@itchy:~# mkdir /var/lib/tftpboot/pxelinux.cfg
 
Now save the following as /var/lib/tftpboot/pxelinux.cfg/default:
 
DISPLAY boot.txt
 
  
DEFAULT etch_i386_install
+
root@itchy:~# mkdir /var/lib/tftpboot/pxelinux.cfg
  
LABEL etch_i386_install
+
Now save the following as /var/lib/tftpboot/pxelinux.cfg/default:
 +
 
 +
DISPLAY boot.txt
 +
 +
DEFAULT etch_i386_install
 +
 +
LABEL etch_i386_install
 
         kernel debian/etch/i386/linux
 
         kernel debian/etch/i386/linux
 
         append vga=normal initrd=debian/etch/i386/initrd.gz  --
 
         append vga=normal initrd=debian/etch/i386/initrd.gz  --
LABEL etch_i386_linux
+
LABEL etch_i386_linux
 
         kernel debian/etch/i386/linux
 
         kernel debian/etch/i386/linux
 
         append vga=normal initrd=debian/etch/i386/initrd.gz  --
 
         append vga=normal initrd=debian/etch/i386/initrd.gz  --
 
+
LABEL etch_i386_expert
+
LABEL etch_i386_expert
 
         kernel debian/etch/i386/linux
 
         kernel debian/etch/i386/linux
 
         append priority=low vga=normal initrd=debian/etch/i386/initrd.gz  --
 
         append priority=low vga=normal initrd=debian/etch/i386/initrd.gz  --
 
+
LABEL etch_i386_rescue
+
LABEL etch_i386_rescue
 
         kernel debian/etch/i386/linux
 
         kernel debian/etch/i386/linux
 
         append vga=normal initrd=debian/etch/i386/initrd.gz  rescue/enable=true --
 
         append vga=normal initrd=debian/etch/i386/initrd.gz  rescue/enable=true --
 +
 +
PROMPT 1
 +
TIMEOUT 0
  
PROMPT 1
 
TIMEOUT 0
 
 
This file instructs the client to display the contents of the file boot.txt so create that too:
 
This file instructs the client to display the contents of the file boot.txt so create that too:
- Boot Menu -
 
=============
 
  
etch_i386_install
+
- Boot Menu -
etch_i386_linux
+
=============
etch_i386_expert
+
etch_i386_rescue
+
etch_i386_install
 +
etch_i386_linux
 +
etch_i386_expert
 +
etch_i386_rescue
 +
 
 
The only remaining job is to download the official Etch installer kernel and associated files and save them in the directories specified in the default file we created:
 
The only remaining job is to download the official Etch installer kernel and associated files and save them in the directories specified in the default file we created:
root@itchy:~# cd /var/lib/tftpboot/
 
root@itchy:~# wget http://ftp.uk.debian.org/debian/dists/etch/main/installer-i386/current/images/netboot/debian-installer/i386/pxelinux.0
 
  
root@itchy:~# mkdir -p /var/lib/tftpboot/debian/etch/i386
+
root@itchy:~# cd /var/lib/tftpboot/
root@itchy:~# cd /var/lib/tftpboot/debian/etch/i386
+
root@itchy:~# wget http://ftp.uk.debian.org/debian/dists/etch/main/installer-i386/current/images/netboot/debian-installer/i386/pxelinux.0
root@itchy:~# wget http://ftp.uk.debian.org/debian/dists/etch/main/installer-i386/current/images/netboot/debian-installer/i386/linux
+
root@itchy:~# mkdir -p /var/lib/tftpboot/debian/etch/i386
root@itchy:~# wget http://ftp.uk.debian.org/debian/dists/etch/main/installer-i386/current/images/netboot/debian-installer/i386/initrd.gz
+
root@itchy:~# cd /var/lib/tftpboot/debian/etch/i386
 +
root@itchy:~# wget http://ftp.uk.debian.org/debian/dists/etch/main/installer-i386/current/images/netboot/debian-installer/i386/linux
 +
root@itchy:~# wget http://ftp.uk.debian.org/debian/dists/etch/main/installer-i386/current/images/netboot/debian-installer/i386/initrd.gz
 +
 
 
When these commands have been completed we'll have the following structure:
 
When these commands have been completed we'll have the following structure:
root@itchy:~# tree /var/lib/tftpboot/
 
/var/lib/tftpboot/
 
|-- boot.txt
 
|-- debian
 
|  `-- etch
 
|      `-- i386
 
|          |-- initrd.gz
 
|          `-- linux
 
|-- pxelinux.0
 
`-- pxelinux.cfg
 
    `-- default
 
  
4 directories, 5 files
+
root@itchy:~# tree /var/lib/tftpboot/
 +
/var/lib/tftpboot/
 +
|-- boot.txt
 +
|-- debian
 +
|  `-- etch
 +
|      `-- i386
 +
|          |-- initrd.gz
 +
|          `-- linux
 +
|-- pxelinux.0
 +
`-- pxelinux.cfg
 +
    `-- default
 +
 +
4 directories, 5 files
 +
 
 
(We only used debian/etch here in case we want to offer other installers in the future. You can put everything in one directory if you wish, just update pxelinux.cfg/default to match.)
 
(We only used debian/etch here in case we want to offer other installers in the future. You can put everything in one directory if you wish, just update pxelinux.cfg/default to match.)
 +
 
We should now be ready to test the setup.
 
We should now be ready to test the setup.
 +
 
We've installed a pxelinux.0 file which will instruct booting clients to request pxelinux.cfg/default. This will then make a list of boot options available, which are displayed by the simple boot menu file we created.
 
We've installed a pxelinux.0 file which will instruct booting clients to request pxelinux.cfg/default. This will then make a list of boot options available, which are displayed by the simple boot menu file we created.
 +
 
The files which are used for booting are stored beneath the TFTP root directory and thus accessible to booting clients.
 
The files which are used for booting are stored beneath the TFTP root directory and thus accessible to booting clients.
 +
 
Sample Run
 
Sample Run
 +
 
A sample remote boot looks like this:
 
A sample remote boot looks like this:
PXE entry point found (we hope) at 9AE5:00D6
 
My IP address seems to be C0A80146 192.168.1.70
 
FTFTP prefix:
 
Trying to load: pxelinux.cfg/01-00-14-22-a1-53-85
 
Trying to load: pxelinux.cfg/C0A80146
 
Trying to load: pxelinux.cfg/C0A8014
 
Trying to load: pxelinux.cfg/C0A801
 
Trying to load: pxelinux.cfg/C0A80
 
Trying to load: pxelinux.cfg/C0A8
 
Trying to load: pxelinux.cfg/C0A
 
Trying to load: pxelinux.cfg/C0
 
Trying to load: pxelinux.cfg/C
 
Trying to load: pxelinux.cfg/default
 
- Boot Menu -
 
=============
 
  
etch_i386_install
+
PXE entry point found (we hope) at 9AE5:00D6
etch_i386_linux
+
My IP address seems to be C0A80146 192.168.1.70
etch_i386_expert
+
FTFTP prefix:
etch_i386_rescue
+
Trying to load: pxelinux.cfg/01-00-14-22-a1-53-85
 +
Trying to load: pxelinux.cfg/C0A80146
 +
Trying to load: pxelinux.cfg/C0A8014
 +
Trying to load: pxelinux.cfg/C0A801
 +
Trying to load: pxelinux.cfg/C0A80
 +
Trying to load: pxelinux.cfg/C0A8
 +
Trying to load: pxelinux.cfg/C0A
 +
Trying to load: pxelinux.cfg/C0
 +
Trying to load: pxelinux.cfg/C
 +
Trying to load: pxelinux.cfg/default
 +
- Boot Menu -
 +
=============
 +
 +
etch_i386_install
 +
etch_i386_linux
 +
etch_i386_expert
 +
etch_i386_rescue
 +
 
 
As you can see the system here attempted to load several configuration files, based upon its MAC address (01-00-14-22-a1-53-85) initially then falling back to the octets in the IP address it was given by DHCP (192.167.1.70).
 
As you can see the system here attempted to load several configuration files, based upon its MAC address (01-00-14-22-a1-53-85) initially then falling back to the octets in the IP address it was given by DHCP (192.167.1.70).
 +
 
Finally it managed to load a working configuration using the last-chance default file we created. This in turn instructed it to show the boot menu we created.
 
Finally it managed to load a working configuration using the last-chance default file we created. This in turn instructed it to show the boot menu we created.
 +
 
From here on the system will boot into whichever kernel you specify. (We could configure the system to timeout here and just boot into a default option, but we didn't.)
 
From here on the system will boot into whichever kernel you specify. (We could configure the system to timeout here and just boot into a default option, but we didn't.)
 +
 +
 +
 +
{{Template:Raspberry Pi}}

Latest revision as of 09:42, 11 February 2012

Back to RPi Projects.


Classroom boot server

This is very preliminary, do not try to follow these instructions.

I just happen to need a PXE server at the moment, so I am documenting all of the necessary steps.

As yet, I have not decided on Fedora or Debian, so the instructions are a bit of a mix at the moment.


What does it do?

This server allows you to run a number of networked PCs, each without its own hard disk, in a classroom/library/café. When the PCs are turned on, they will fetch the boot information from a PXE/netboot server. The cost of each PC is reduced because individual hard disks are not needed. Also, there is no information stored locally on each PC for the user to tamper with - if the user messes up a PC, just reboot the PC to return to normal.

What do you need?

  • A Raspberry Pi, model B.
  • A boot SD card for the Raspberry Pi. [What size? Needs to hold ISO image]
  • An Ethernet cable to connect to the local network.

What skill level is required?

This project does not require and coding or compilation. Very basic Linux and networking knowledge would be useful, but not essential.

You need to...

  • Edit configuration files on the RPi
  • Change a BIOS configuration parameter on each PC
  • Find and download a boot CD image from the internet (easier for Linux than for Windows)
  • Join computers together using ethernet cables

How does it work?

PXE (Preboot eXecution Environment) is a method to allow a PC without a hard disk to boot from the network. It is also known as net booting or LAN13 booting.

If a PC is configured to boot over the network, it will search the local network for a DHCP (Dynamic Host Configuration Protocol) server. The DHCP server will assign an IP address to the PC and tell the PC the address of a tftp (trivial file transport protocol) server where a boot image is available.

The PC connects to the tftp server and downloads the basic boot image. This boot image will then instruct the PC to fetch the complete operating system from a web server.

The Raspberry Pi will act as the DCHP server, the tftp server, and the web server.

Overview of this project

  1. General Preparation
  2. Configuring the DHCP server on the RPi
  3. Configuring the tftp server on the RPi
  4. Configuring the web server on the RPi
  5. Test with a single PC
  6. Deploy to a live network

General Preparation

First, you need to install all of the necessary software.

1A) Connect your Raspberry Pi to a network. Check that you have an internet connection

Command:

ping www.google.com

1B) Install the following packages [To be checked: these ship with Fedora Core 4 already, so they may be part of the default RPi installation]

  • tftp-server
  • dhcp
  • httpd
  • syslinux

Command:

yum install tftp-server dhcp httpd syslinux

answer Y to all dependency/installation questions.

1C) Disconnect the Raspberry Pi from the network.

Configuring the DHCP server on the RPi

Now you need to setup the DHCP server.

2A alt 1) Create /etc/dhcpd.conf with the following contents:

ddns-update-style interim;
subnet 192.168.0.0 netmask 255.255.255.0
{
 range 192.168.0.10 192.168.0.254;
 default-lease-time 3600;
 max-lease-time 4800;
 option routers 192.168.0.1;
 option domain-name-servers 192.168.0.1;
 option subnet-mask 255.255.255.0;
 option domain-name "llama.net";
 option time-offset -8;
}

host llama0
{
 hardware ethernet 04:4B:80:80:80:03;
 fixed-address 192.168.0.254;
 option host-name "llama0";
 filename "pxelinux.0";
}

To explain – the above configuration file sets up a DHCP server that will assign IP address 192.168.0.254 to your client box that has MAC address 04:4B:80:80:80:03 assigned to its PXE-boot capable NIC. Another thing to note is that we're reserving the private 192.168 subnet for this setup. The only thing you need to change in the above, is the MAC address to match that of the NIC on your client box. This configuration says that the client PC should be informed that the file “pxelinux.0” is available.

Question – Why are we using a static IP assignment?

2A alt 2) Create /etc/dhcpd.conf with the following contents:

option domain-name-servers 192.168.0.1;
default-lease-time 3600;
max-lease-time 4800;
authoritative;

subnet 192.168.0.0 netmask 255.255.255.0
{
 range 192.168.0.70 192.168.1.100;
 filename "pxelinux.0";
 next-server 192.168.0.50;
 option subnet-mask 255.255.255.0;
 option broadcast-address 192.168.0.255;
 option routers 192.168.0.1;
}

Here we've configured the server to give out IP addresses from the range 192.168.0.70-100, set the default gateway to be 192.168.0.1

We've also used next-server to point to the TFTP server we're using (which is the same host as our DHCP server, but doesn't need to be). We've chosen the default name of pxelinux.0 as the name of the file for booting clients to request.

2B) Now start dhcpd

Command:

service dhcpd start

Configuring the tftp server on the RPi

Next you need to activate tftp within xinetd.

3A) Edit the file /etc/xinetd.d/tftp to change disable=yes to disable=no

3B) Then restart xinetd.

Command:

service xinetd restart

3C) Now we need to setup your PXE server to use a static IP on the new private subnet. Create the file /etc/sysconfig/network-scripts/ifcfg-eth0.static with the following contents:

DEVICE=eth0
BOOTPROTO=STATIC
ONBOOT=no
TYPE=Ethernet
IPADDR=192.168.0.2
NETMASK=255.255.255.0
GATEWAY=192.168.0.1

3D) Now we need to setup the PXE boot environment on the server. To do this, you need to have either the Linux distribution that you wish to install over PXE either in CD format, or all the content of the CDs available on the network.

On the first CD of every RH/FC distribution there is a subdirectory called 'isolinux'. In that directory you will find two files, vmlinuz and initrd.img. These are the kernel & initrd.img that the RH/FC bootable CDs use to get the installer (anaconda) booted for performing the installation. Copy both of those files into /tftpboot and make sure that they are world readable. If you are planning to allow more than one version/distribution to be PXE boot installable, then you should rename both files so that its clear that they are for whatever version/distribution they came from (such as vmlinuz-RHEL4, initrd-RHEL4).

Next, you need the actual pxe boot linux kernel (what is actually run immediately after your PXE boot client box gets a DHCP lease). In this case, that file is pxelinux.0, and is part of the syslinux RPM. For FC4, you can find it at /usr/lib/syslinux/pxelinux.0. Copy that file into /tftpboot and make sure that it is world readable.

3E) Next we need to configure pxelinux. First create the directory /tftpboot/pxelinux.cfg (and make it world readable). Inside that directory you need to create a number of zero size files (use touch):

touch /tftpboot/pxelinux.cfg/C
touch /tftpboot/pxelinux.cfg/C0
touch /tftpboot/pxelinux.cfg/C0A
touch /tftpboot/pxelinux.cfg/C0A8
touch /tftpboot/pxelinux.cfg/C0A80
touch /tftpboot/pxelinux.cfg/C0A800
touch /tftpboot/pxelinux.cfg/C0A800F
touch /tftpboot/pxelinux.cfg/C0A800FE
touch /tftpboot/pxelinux.cfg/01-04-4B-80-80-80-03 #Edit to match your PC

The first 8 are the hex representation of the 192.168.0.254 IP address that your PXE boot client will be assigned. The permutations allow a broader IP subnet to be searched first for matches. The last entry is the MAC address of your PXE boot client's NIC (with dashes substituted for the colons), with '01' pre-pended. The "01" at the front represents a hardware type of Ethernet, so pxelinux.0 see's the configuration string as an IP address.

[Question: Why bother with the MAC? This will limit the solution to a single PC and is useless in a classroom. Much better to boot by IP subnet, probably a 192.168.0.0/24 subnet would be perfect]

3F) Now create the default pxelinux configuration inside the new file /tftpboot/pxelinux.cfg/default:

prompt 1
default linux
timeout 100

label linux
kernel vmlinuz
append initrd=initrd.img ramdisk_size=9216 noapic acpi=off

Configuring the web server on the RPi

4A) Now you need to put the full contents of your Linux distro (all CDs) somewhere on disk. I put it under /tftpboot/RHEL4U1. In order to allow for installation over HTTP (apache), edit/etc/httpd/conf/httpd.conf and add the following:

<Directory /tftpboot/RHEL4U1>
Options Indexes
AllowOverride None
</Directory>
Alias /linux /tftpboot/RHEL4U1

4B) Start web server

Command:

service httpd start

Test with a single PC

[These instructions need a switch between the PC and the PXE server. But the RPi has an auto-sensing NIC, so a simple ethernet cable could be used instead]

5A) At this stage, you're ready to hook up the switch. You should have CAT5 running between the switch & the PXE boot server, and the client box.

5B) On the PXE boot server, bring down your DHCP network connected eth0 (ifdown eth0), disconnect the CAT5 connected to the network, and plug in the cat5 connected to your private switch. Now bring up the static IP for the PXE server with (ifup eth0.static). You can verify that it came up successfully by verifying that you have IP address 192.168.0.2 in ifconfig.

5C) Plug the PXE client box's CAT5 into the switch, and verify that the NIC appears first in the BIOS boot order. (re)boot and you should get a DHCP lease, and start booting successfully off the network.

5D) When you get into the RH/FC installer which asks you for the install method, choose HTTP. Fill in 192.168.0.2 for the name, and 'linux' for the path, and you should be all set.

5E) If you run into any problems, check /var/log/messages for errors (that's where all dhcp & tftp stuff will get logged). /var/log/httpd is where apache logs, but if you get that far, your problem is an apache configuration/setup issue, and not a PXE boot issue.

Extra useful text

From http://www.debian-administration.org/articles/478

[This Debian-based instruction uses dynamic ip allocation and does not depend on the MAC address]

If you're looking to perform a lot of system recovery, or system installation, then network booting with PXE is ideal. PXE allows you to boot up a system and have it automatically get an IP address via DHCP and start booting a kernel over the network.

PXE itself stands for "Pre-boot eXecution Environment", which describes how it works in the sense that the clients using it haven't booted in a traditional manner.

In order to use PXE you need to setup a boot-server which will allow client systems to :

  • Request an IP address (via DHCP)
  • Download a kernel (via TFTP)

With both of these services in place any system which supports PXE/network-booting (you might need to enable it in the BIOS) should be able to gain an IP address, fetch a kernel, and boot without an installed operating system.

(This is ideal for systems which can't be booted by a traditional approach; for example your new AMD-64 system which doesn't have a CD/DVD drive!)

Our Setup

For the purposes of this article we'll assume: • We're working with a small network 192.168.1.0/24 • We'll allow all local machines to boot and get an IP address via DHCP from the range 196.168.1.70-192.168.1.100 • Our "boot-server" is the host "itchy" with IP address 192.168.1.50 • We will serve the same kernel to each host.

In our example we'll configure a PXE-server which will allow remote systems to run the Debian Etch installer, but nothing here is specific to that. PXE allows you to configure a system to boot from an arbitrary kernel (and matching ramdisk if you wish to use one). With the correct configuration you can even cause the clients to mount a remote file-system via NFS and have a diskless thin-client system.

TFTP Setup

TFTP is a very simple file-transfer protocol, which is very similar to FTP but which doesn't use any kind of authentication. If you're not already running a TFTP server you can install one by running:

root@itchy:~# apt-get install tftpd-hpa

Once installed you'll need to enable it by editing the file /etc/default/tftpd-hpa. You should change RUN_DAEMON to yes, leaving you with contents like these:

#Defaults for tftpd-hpa
RUN_DAEMON="yes"
OPTIONS="-l -s /var/lib/tftpboot"

Now create the root directory, if it is missing, and start the server:

root@itchy:~# mkdir -p /var/lib/tftpboot
root@itchy:~# /etc/init.d/tftpd-hpa start
Starting HPA's tftpd: in.tftpd.

Once our systems have retrieved an IP address via DHCP they will request files from beneath the /var/lib/tftpboot root directory. We'll come back to the contents of this directory shortly.

DHCP Setup

If you don't already have a DHCP server configured upon your LAN you'll need to install one. If you're using a small home router, or similar, to provide local DHCP services you must disable this first. (Since we require the DHCP server to pass back some extra options to clients which the majority of routers won't allow).

Discussing a full DHCP installation is mostly beyond the scope of this introduction but the thing we're trying to do is fairly simple. The goal of the DHCP server in this setup is twofold: • We obviously want to use it to allow clients to request and receive an IP address. • We want to cause the DHCP "answer" to give some extra details to the clients which are requesting an address: • The address of the TFTP server. • The initial filename to request from the TFTP server.

The most common DHCP server is the dhcp-server package, and you can install this by running:

root@itchy:~# apt-get install dhcp3-server

Once installed the server is configured in the file /etc/dhcp3/dhcpd.conf, and there are a lot of available options described there. For our example we'll use the following configuration:

option domain-name-servers 62.31.64.39, 62.31.112.39;
default-lease-time 86400;
max-lease-time 604800;
authoritative;

subnet 192.168.1.0 netmask 255.255.255.0 {
       range 192.168.1.70 192.168.1.100;
       filename "pxelinux.0";
       next-server 192.168.1.50;
       option subnet-mask 255.255.255.0;
       option broadcast-address 192.168.1.255;
       option routers 192.168.1.1;
}

Here we've configured the server to give out IP addresses from the range 192.168.1.70-100, set the default gateway to be 192.168.1.1 and use our ISP's nameservers.

We've also used next-server to point to the TFTP server we're using (which is the same host as our DHCP server, but doesn't need to be). We've chosen the default name of pxelinux.0 as the name of the file for booting clients to request.

Using dnsmasq instead

Personally I use the dnsmasq package to provide DHCP services upon my LAN, since this is small and simple and provides other useful abilities, setting up PXE booting with dnsmasq just requires the addition of the following line to /etc/dnsmasq.conf:

dhcp-boot=pxelinux.0,itchy,192.168.1.50

(Again we've setup the filename along with the name and IP address of the TFTP server which is "itchy" / 192.168.1.50 in this example)

Restarting the service after this change is as simple as:

root@itchy:~# /etc/init.d/dnsmasq restart
Restarting DNS forwarder and DHCP server: dnsmasq.

PXE Configuration

Now that we've configured the TFTP and DHCP servers we need to go back and complete the configuration. By default when a client boots up it will use its own MAC address to specify which configuration file to read - however after trying several options it will fall back to requesting a default file.

We need to create that that file, which will contain the list of kernels which are available to boot, we'll firstly need to create a directory to hold it:

root@itchy:~# mkdir /var/lib/tftpboot/pxelinux.cfg

Now save the following as /var/lib/tftpboot/pxelinux.cfg/default:

DISPLAY boot.txt

DEFAULT etch_i386_install

LABEL etch_i386_install
       kernel debian/etch/i386/linux
       append vga=normal initrd=debian/etch/i386/initrd.gz  --
LABEL etch_i386_linux
       kernel debian/etch/i386/linux
       append vga=normal initrd=debian/etch/i386/initrd.gz  --

LABEL etch_i386_expert
       kernel debian/etch/i386/linux
       append priority=low vga=normal initrd=debian/etch/i386/initrd.gz  --

LABEL etch_i386_rescue
       kernel debian/etch/i386/linux
       append vga=normal initrd=debian/etch/i386/initrd.gz  rescue/enable=true --

PROMPT 1
TIMEOUT 0

This file instructs the client to display the contents of the file boot.txt so create that too:

- Boot Menu -
=============

etch_i386_install
etch_i386_linux
etch_i386_expert
etch_i386_rescue

The only remaining job is to download the official Etch installer kernel and associated files and save them in the directories specified in the default file we created:

root@itchy:~# cd /var/lib/tftpboot/
root@itchy:~# wget http://ftp.uk.debian.org/debian/dists/etch/main/installer-i386/current/images/netboot/debian-installer/i386/pxelinux.0
root@itchy:~# mkdir -p /var/lib/tftpboot/debian/etch/i386
root@itchy:~# cd /var/lib/tftpboot/debian/etch/i386
root@itchy:~# wget http://ftp.uk.debian.org/debian/dists/etch/main/installer-i386/current/images/netboot/debian-installer/i386/linux
root@itchy:~# wget http://ftp.uk.debian.org/debian/dists/etch/main/installer-i386/current/images/netboot/debian-installer/i386/initrd.gz

When these commands have been completed we'll have the following structure:

root@itchy:~# tree /var/lib/tftpboot/
/var/lib/tftpboot/
|-- boot.txt
|-- debian
|   `-- etch
|       `-- i386
|           |-- initrd.gz
|           `-- linux
|-- pxelinux.0
`-- pxelinux.cfg
    `-- default

4 directories, 5 files

(We only used debian/etch here in case we want to offer other installers in the future. You can put everything in one directory if you wish, just update pxelinux.cfg/default to match.)

We should now be ready to test the setup.

We've installed a pxelinux.0 file which will instruct booting clients to request pxelinux.cfg/default. This will then make a list of boot options available, which are displayed by the simple boot menu file we created.

The files which are used for booting are stored beneath the TFTP root directory and thus accessible to booting clients.

Sample Run

A sample remote boot looks like this:

PXE entry point found (we hope) at 9AE5:00D6
My IP address seems to be C0A80146 192.168.1.70
FTFTP prefix:
Trying to load: pxelinux.cfg/01-00-14-22-a1-53-85
Trying to load: pxelinux.cfg/C0A80146
Trying to load: pxelinux.cfg/C0A8014
Trying to load: pxelinux.cfg/C0A801
Trying to load: pxelinux.cfg/C0A80
Trying to load: pxelinux.cfg/C0A8
Trying to load: pxelinux.cfg/C0A
Trying to load: pxelinux.cfg/C0
Trying to load: pxelinux.cfg/C
Trying to load: pxelinux.cfg/default
- Boot Menu -
=============

etch_i386_install
etch_i386_linux
etch_i386_expert
etch_i386_rescue

As you can see the system here attempted to load several configuration files, based upon its MAC address (01-00-14-22-a1-53-85) initially then falling back to the octets in the IP address it was given by DHCP (192.167.1.70).

Finally it managed to load a working configuration using the last-chance default file we created. This in turn instructed it to show the boot menu we created.

From here on the system will boot into whichever kernel you specify. (We could configure the system to timeout here and just boot into a default option, but we didn't.)