Netboot Installation

Hey,

looking for useful documentation about netboot in Linux is quite difficult nowadays; of the various guides I found on the net only 1 was useful (1 of 30) … No wonder that I came to the conclusion to write my own one…

The goal is, to have a central fileserver which does nfs+dhcp+tftp to make netbooting installation images possible. That’s because I’m usually missing a install CD and I’ve got no spare recordables lying around -> all of my boxes can do netbooting, though.

Let’s install required software on the server:

lin -cr xinetd tftp-hpa dhcp nfs-utils

For Lunar Linux users, I already uploaded the Kernel and example configurations; i.e. you can get them from any lunar linux mirror. For everyone else, here’s how to do it manually (this is, what I was looking for) – Before you start to read about the kernel: basically you just need to make sure to get the kernel and initrd from the iso and you need to make sure that that kernel got nfs root enabled.

The Kernel

You have a few options here. Your first option is use some pre-compiled kernel provided by your distribution – You’ll need the kernel and if available the initrd. Your second choice is compiling your own kernel. Important: You need to enable Root file system on NFS:

File systems  ---> [*] Network File Systems  ---> <*>   NFS client support
                                                  [*]     NFS client support for NFS version 3
                                                  [*]     NFS client support for NFS version 4
                                                  [*]   Root file system on NFS

Building your own Kernel

grab a copy from kernel.org, unpack it and start menuconfig. If you need to create a kernel for a specific installer, you should stick to the kernel-version which is already shipped with that installer; because then you can easily use the already created initrd.

wget ftp://ftp.kernel.org/pub/linux/kernel/v3.0/linux-3.0.1.tar.bz2
tar -xjvf linux-3.0.1.tar.bz2
cd linux-3.0.1

optional:
you could use the config of the kernel you’re running right now; if the versions are different this might lead to problems, tho. However, that way you could make sure that you build a kernel which will run on more than one box, without going through whole menuconfig. If available you’ll find the kernel config in /proc/config.gz – In Lunar Linux you might use the config found in /boot/config-2.6.35.3.gz

now continue the compilation by issuing:

make menuconfig

make sure to configure the nfs stuff from above and then make changes to the configuration as needed. Right after you did that you can start to compile it:

make -j 4
make modules

replace the 4 by the number of your cpus / cores. As soon as that is finished, we should create an initrd for the modules. Sadly, I have no clue on how to do that correctly (the initrd) thus I didn’t used any modules. As soon as I found out how, I’ll edit this post 🙂

Configuring the applications

Let’s see. I’ll assume you’ll have /var/lib/tftpboot and a symlink from /tftboot to that directory. Also I assume that you got tftp already running using xinetd – for that you just need to write the following stuff into your /etc/xinetd.d/tftp and restart xinetd.

/etc/xinetd.d/tftp

service tftp
{
  socket_type = dgram
  protocol = udp
  wait = yes
  user = root
  server = /usr/sbin/in.tftpd
  server_args = -s /tftpboot
  disable = no
  rver_args = -s /tftpboot
  disable = no
}

Now we need to export the install images using NFS:

/etc/exports

/tftpboot/images/        *(ro,no_subtree_check,no_root_squash,fsid=root)

Instead of * you might want to use your local network (like 192.168.2.0/24). I used „ro“ because I’m creating squashfs images of the isos, and they’re read-only mounted (the CD would be readonly also, so this isn’t important), no_subtree_check is just there to avoid an error message. no_root_squash and fsid=root were needed to make the root-mount possible.

The dhcpd configuration isn’t very difficult, tho you have to think a bit about it because of a few reasons: If you already have a dhcp-server in your network, then you might want to make sure that they’ll work fine together.

Example:
192.168.2.25 is the 2nd dhcp (the netboot one) 192.168.2.1 is the 1st dhcp.
00:13:E8:B7:2B:C3 is the mac address of a client which shouldn’t use the 2nd DHCP service
On the 2nd dhcp server I use the following dhcp block rule to ignore dhcp requests from that specific MAC:

host lyra {
  hardware ethernet 00:13:E8:B7:2B:C3;
  ignore booting;
}

However, you could make a group now, so you need to write ignore booting; only once. i.e.:

  group {
    ignore booting;

#   host lyra {
#      hardware ethernet 00:26:22:75:70:8E;
#    }
  }

If I uncomment lyra, it won’t use netboot. If the comments stay, it’s netbooting. Just like I wanted that. That’s not all to do, tho. Now you need to write a subnet-block with the ip-range for netbooting. Into this global block you’d play the group/host block(s), and the following general options:

  option routers               192.168.2.1;
  option subnet-mask           255.255.255.0;
  option domain-name-servers   192.168.2.1;
  option ntp-servers           192.168.1.1;
  range dynamic-bootp          192.168.2.10 192.168.2.23;
  default-lease-time           21600;
  max-lease-time               43200;
  filename                   "/pxelinux.0";

So your whole config would look like this:

/etc/dhcpd.conf

subnet 192.168.2.0 netmask 255.255.255.0 {
  #
  # global options
  #
  option routers               192.168.2.1;
  option subnet-mask           255.255.255.0;
  option domain-name-servers   192.168.2.1;
  option ntp-servers           192.168.1.1;
  range dynamic-bootp          192.168.2.10 192.168.2.23;
  default-lease-time           21600;
  max-lease-time               43200;
  #
  # groups
  #
  group {
    # hosts in this group won't use netboot.
    ignore booting;

#   host lyra {
#      hardware ethernet 00:26:22:75:70:8E;
#    }
  }

  filename                   "/pxelinux.0";
}

Setup the PXE Stuff

Alright, NFS, DHCPD and TFTP are configured and should work. We also have a Kernel, an initrd and a iso-image of the system we’d like to use. Whats left? Right – The configuration of the pxe-stuff. Let’s go into /tftpboot. Currently we don’t have anything here. But as you’ve seen above dhcpd will need a file called pxelinux.0 and nfs wants to export the directory /tftpboot/images/. I’m going to use squashfs for the images to save a bit space. Let’s create needed directories:

mkdir -p /tftpboot/images/lunar-1.6.5-x86
mkdir -p /tftpboot/images/lunar-1.6.5-x86_64
mkdir -p /tftpboot/pxelinux.cfg

The Images (squashfs)

If you want to do it like that, also, do:

lin -cr squashfs

Now take one of your images and let’s check:

507M    lunar-1.6.5-i686.iso (as .iso)
499M    lunar (mounted)

Now create the squashfs image of it:

mksquashfs /mnt/lunar lunar.sqfs -no-duplicates

Where /mnt/lunar is the MOUNTED iso. The resulting squashfs file has:

363M    lunar.sqfs

I’d say, thats worth it. Now you just need to mount that file.

root@lunar /tftpboot # mount lunar.sqfs lunar
mount: warning: lunar seems to be mounted read-only.
root@lunar /tftpboot # df -hT | grep lunar
/dev/loop0     squashfs  363M  363M     0 100% /var/lib/tftpboot/lunar

Just like that, you can create such squashfs files for every install-iso you wanna use.

The images (non-squashfs)

Basically it’s the same approach, you just don’t create a squashfs file. Just mount the iso to the directory you wish to have it. For example: We’d like to have the lunar is mounted at /tftpboot/images/lunar-1.6.5-x86

mount -o loop,ro -t iso9660 /path/to/lunar.iso /tftpboot/images/lunar-1.6.5-x86

should do the job

Kernel / Initrd

Now let’s create a directory for kernel and initrd stuff.

mkdir -p /tftpboot/kernel-initrd

And copy the needed files into that, also rename them. For example, if you haven’t compiled your own like explained above, look into the mounted lunar iso, go into the directory isolinux and do:

 # cp linux /tftpboot/kernel-initrd/lunar-k-1.6.5-32
 # cp initrd /tftpboot/kernel-initrd/lunar-i-1.6.5-32

so basically I use distroname-k|i-version-bit where k stands for kernel and i for initrd. Bit is obviously either 32 or 64.

PXE files

Download syslinux from http://www.kernel.org/pub/linux/utils/boot/syslinux/ and unpack it. Within you’ll find 3 files which we need:

core/pxelinux.0
com32/menu/vesamenu.c32
com32/menu/menu.c32

copy them to the /tftpboot/ – You can delete the syslinux source now, if you wish to.

Menu

Let’s create a nice menu for that now. First of all you’ll need a nice background (hrhr) picture. I’m using this one:

bg-lunar

The finished menu could look like this:

lunar_netboot

lunar_netboot2

Basically the menu consists of a few files it can be easy or complex, just as you like. In my case it’s a bit complex.

default

DEFAULT installer
PROMPT 0

UI pxelinux.cfg/vesamenu.c32
MENU BACKGROUND pxelinux.cfg/bg.png

MENU TITLE Netboot Menu
MENU INCLUDE pxelinux.cfg/graphics.conf
MENU AUTOBOOT Starting local system in # seconds

LABEL localhdd
  MENU LABEL ^local boot
  MENU default
  LOCALBOOT 0
  TIMEOUT 80

LABEL installer
  MENU LABEL ^installer
  KERNEL pxelinux.cfg/vesamenu.c32
  APPEND pxelinux.cfg/graphics.conf pxelinux.cfg/installer.menu

I’m sure most options are logical. The difference between vesamenu and menu is that menu is displaying a menu like „dialog“ or like the old thing you should know from „lilo“. While vesamenu offers the possibility to use a background image and thus looks more nice.

installer.menu

MENU TITLE Installer Menu

MENU BACKGROUND pxelinux.cfg/bg.png

LABEL main menu
  MENU LABEL ^return to main menu
  KERNEL pxelinux.cfg/vesamenu.c32
  APPEND pxelinux.cfg/default

LABEL lunar 1.6.5 x86
  MENU LABEL ^Lunar Linux 1.6.5 32 Bit
  KERNEL kernel-initrd/lunar-k-1.6.5-32
  APPEND initrd=kernel-initrd/lunar-i-1.6.5-32 ramdisk_size=32768 root=/dev/nfs nfsroot=192.168.2.102:/,vers=4,clientaddr=192.168.2.11 ip=dhcp nfsrootdebug
  IPAPPEND 1

LABEL lunar 1.6.5 x86_64
  MENU LABEL ^Lunar Linux 1.6.5 64 Bit
  KERNEL kernel-initrd/lunar-k-1.6.5-64
  APPEND initrd=kernel-initrd/lunar-i-1.6.5-64 ramdisk_size=32768 root=/dev/nfs nfsroot=192.168.2.102:/,vers=4,clientaddr=192.168.2.11 ip=dhcp nfsrootdebug
  IPAPPEND 1

This one is a bit more advanced; basically nfs root fails if I don’t add vers=4 and it segfaults or fails depending on your kernel, if you don’t add „clientaddr=“ where clientaddr obviously should be some client addr. ip=dhcp means nfs will try to get the ip from dhcp (thats why I think clientaddr= is useless, however, it won’t work without here.

graphics.conf

MENU COLOR TABMSG 37;40 #80ffffff #00000000
MENU COLOR HOTSEL 30;47 #40000000 #20ffffff
MENU COLOR SEL 30;47 #40000000 #20ffffff
MENU COLOR SCROLLBAR 30;47 #40000000 #20ffffff
MENU MASTER PASSWD yourpassword
MENU WIDTH 80
MENU MARGIN 22
MENU PASSWORDMARGIN 26
MENU ROWS 6
MENU TABMSGROW 15
MENU CMDLINEROW 15
MENU ENDROW 24
MENU PASSWORDROW 12
MENU TIMEOUTROW 13
MENU VSHIFT 6
MENU PASSPROMPT Enter Password:
NOESCAPE 1
ALLOWOPTIONS 0

I took this from some example 🙂

directory/filestructure

For easyness, I thought it might be useful to give you an overview about my file/directory-structure. I marked directories bold.

  • /tftpboot
    • pxelinux.0
    • images
      • lunar.sqfs
      • lunar-1.6.5-x86
      • lunar-1.6.5-x86_64
    • kernel-initrd
      • lunar-i-1.6.5-32
      • lunar-i-1.6.5-64
      • lunar-k-1.6.5-32
      • lunar-k-1.6.5-64
    • pxelinux.cfg
      • bg.png
      • default
      • graphics.conf
      • installer.menu
      • menu.c32
      • vesamenu.c32

No Comments

Post a Comment