Diskless netboot

Revision as of 16:40, 23 May 2014 by WikiFreak (talk | contribs)

Diskless server / workstation using netboot


NFS is a technology that allow you to share some files and folders over the network. So:

  • All the clients will share the installation, configuration files and so on.
  • Each client will run a dedicated instance of the operating system
  • Logs will be centralized on the common NFS server - so we don't loose data on each reboot.

You must have a working DHCP server + NetBoot before starting this part.


Requirements:



Aim

In order to be super effective:

  • Each client distribution will have its own kernel support (vmlinuz + initrd.img files)
  • All the distributions will be under the same root
  • Both NFS and TFTP will share the same root folder
  • The user will be able to choose the O.S to use using a PXE menu


Target folder tree:

/pxe-boot/                                 # TFTP + NFS root
/pxe-boot/pxelinux.0                       # Initial boot file - only use to load the PXE NetBoot manager
/pxe-boot/{menu.c32 || vesamenu.c32}       # PXE interactive menu managers (text or graphical)

/pxe-boot/pxelinux.cfg/                    # PXE configuration(s)
/pxe-boot/pxelinux.cfg/default             # default PXE configuration

/pxe-boot/images/                          # This is where the distributions will be. 
                                           # Each distribution [configuration] will be in a dedicated folder.

/pxe-boot/images/trusty/                   # Ubuntu 14.04 [Trusty] distribution - ready to be used


/pxe-boot/images/trusty/vmlinuz            # specific kernel for ubuntu 14.04 distrubution
/pxe-boot/images/trusty/initrd.img         # specific initrd for ubuntu 14.04 distribution



Installation

NFS support

apt-get install nfs-kernel-server nfs-common

Debootstrap (manage netboot image)

apt-get install debootstrap


Initramfs (to manage "virtual disks")

apt-get install initramfs-tools



NFS server setup

Preparation

You have to create a dedicated folder on your server where you will host the client image.

mkdir -p /pxe-boot/pxelinux.cfg
mkdir /pxe-boot/images
chmod -R 777 /pxe-boot


Configuration

The NFS configuration is done in the /etc/exports file

vim /etc/exports


Add something like that:

  /pxe-boot      192.168.2.0/24(ro,no_root_squash,no_subtree_check,async,insecure)


Adjust "192.168.2.0/24" to your own network address

  • rw : Allow clients to read as well as write access
  • ro : Read only access
  • insecure : Tells the NFS server to use unpriveledged ports (ports > 1024).
  • no_subtree_check : If the entire volume (/users) is exported, disabling this check will speed up transfers.
  • async : async will speed up transfers.
  • no_root_squash: This phrase allows root to connect to the designated directory.


- NOTE -

It's always a good idea to use Read-Only if you plan to share this disk.

That will avoid user to mess with your image!


Security

Like TFTP, this part is insecure !

You must restrict the access to your NFS server by a firewall script and filtering BEFORE reaching the LAN !


NFS is using dynamic ports numbers because it runs over rpcbind. Making NFS using specifics port is a pain in the ass !! :(

So, instead of that you should allow your LAN communication.


    IPTABLES=`which iptables`
    LAN_ADDRESS="192.168.2.0/24"

    # Allow LAN communication
    $IPTABLES -A INPUT -s $LAN_ADDRESS -d $LAN_ADDRESS -m state ! --state INVALID -j ACCEPT
    $IPTABLES -A OUTPUT -s $LAN_ADDRESS -d $LAN_ADDRESS -m state ! --state INVALID -j ACCEPT


Management

service nfs-kernel-server {status|start|stop|restart}


Test the server

Install the NFS v4 client:

apt-get install nfs-common


To mount the default path:

mount -t nfs nfs-server:/ /mnt

You'll see: "/mnt/pxe-boot"


It's better to do:

mount -t nfs nfs-server:/pxe-boot /mnt



NFS client image

There are different way to setup a NFS client image.

The main ones are:

  • debootstrap
  • copying the install from your server
  • Manual install on a client, then, when the system is ready, copy everything to the NFS share


Debootstrap: setup client distribution

Setup distribution folder

You have to create one target for each distribution you want to serve:

mkdir -p /pxe-boot/images/trusty

- NOTES -

  • The folder name should match your NetBoot settings. Folder name = a LABEL in the NetBoot config.
  • The folder name should match a Linux (Debian like) distribution name


Populate the content

cd /pxe-boot/images/trusty
debootstrap trusty /pxe-boot/images/trusty


Configure client distribution

Access distribution

# "mount" the system
chroot /pxe-boot/images/trusty/

From here you can perform operation as if you were on a separate machine.

Only the current distribution (= the client one) will be affected.


Adjust default login/password

First of all, you have to create / adjust the default user.

# Add new user
adduser <username>
# Add user to sudoers group
usermod -a -G sudo <username>


Now you can use that user:

su <username>
sudo -s

You can check that you really are in the "Virtual machine" by checking "/srv/". It should be empty !


Update sources.list and install key packages

Your client need to have some key packages in order to work. Without these package even the NetBoot will fail !!


First of all: edit your sources.list

apt-get install vim
vim /etc/apt/sources.list


Put the following:

### Custom repositories list
#
# May 2014 - Guillaume Diaz
# This is an ajdustement of the default "debootstrap" sources.list
# This is required to provided update, security and advanced tools to all our clients
#

# Official repositories
deb http://se.archive.ubuntu.com/ubuntu/ trusty main restricted universe multiverse
deb http://se.archive.ubuntu.com/ubuntu/ trusty-updates main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu trusty-security main restricted universe multiverse

# Official updates 
deb http://se.archive.ubuntu.com/ubuntu/ trusty-backports main restricted universe multiverse

# Canonical partners
deb http://archive.canonical.com/ubuntu trusty partner

# Community partners
deb http://extras.ubuntu.com/ubuntu trusty main


Update your package list:

apt-get update && apt-get upgrade


Now, you can install the basic programs:

# NFS client. This is ABSOLUTELY MANDATORY ! That's the only way to mount the /root
apt-get install nfs-common
apt-get install initramfs-tools

# NFS is a bit low, and if you're using many client it might result in time faults. 
# You must install NTP to overcome this !!
apt-get install ntp ntpdate

# Basic set of utilities
apt-get install unzip zip
apt-get install make autoconf automake cpp gcc build-essential
apt-get install htop
apt-get install python3

# Advanced APT manager (require to add repository from command line)
apt-get install software-properties-common python-software-properties


# JAVA (that is required for my application)
# Depending on your target usage you might not need it.
add-apt-repository ppa:webupd8team/java 
apt-get update && apt-get upgrade
apt-get install oracle-java7-installer oracle-jdk7-installer


Adjust bash and vim configuration

Edit your VIM configuration:

vim /etc/vim/vimrc

Enable dark background, set nu, set ruler


Edit your bash configuration files to adjust the alias and enable auto-completion:

vim /etc/bash.bashrc
vim /home/<username>/.bashrc
vim /root/.bashrc


Install a local kernel

To install a local kernel, you have to:

  • mount /proc
  • unpack linux-headers-generic
  • unpack linux-image-generic


mount /proc
apt-get install -y linux-headers-generic
apt-get install -y linux-image-generic


Check that you have some symlinks in /, either create them:

ln -s /boot/vmlinuz-3.5.0-21-generic /vmlinuz         
ln -s /boot/initrd.img-3.5.0-21-generic /initrd.img

!! Don't forget to adjust the number to your actual version !!


Edit mount points (/etc/fstab)

You must edit the mount points to get the client working!

vim /etc/fstab


/proc    /proc    proc    defaults   0 0
/sys     /sys     sysfs   defaults   0 0
/dev/nfs /        nfs     defaults   1 1



Adjust network configuration

Up to this point the client will already have got a DHCP address through the NetBoot process.

Therefore, you should prevent users / services from changing that automatic configuration.


Edit the config file:

vim /etc/network/interfaces


Put:

## Manual override of the debootstrap shipped configuration
#
# Version 1.0 - May 2014 - Guillaume Diaz
#

# Loopback
auto lo
iface lo inet loopback

# Keep the NetBoot configuration
iface eth0 inet manual

# Intel NUC trick - as the NUC uses "em1" instead of "eth0"
iface em1 inet manual


Run clients in diskless NFS mode

Now you are (finally) ready to tell the client to run in diskless mode! Edit the config file:

vim /etc/initramfs-tools/initramfs.conf


Set the following values:

MODULES = netboot 
BOOT    = nfs


Apply changes:

update-initramfs -u


Exit client distro

umount /proc
exit



Adjust TFTP root

You must adjust the TFTP root to match the NFS root !!

vim /etc/default/tftpd-hpa


Adjust the file like that:

RUN_DAEMON="yes"
OPTIONS="--secure"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/pxe-boot/"


Notice the RUN_DAEMON instruction + the new TFTP_DIRECTORY


Custom NetBoot configuration

Basic configuration

You can setup your own netboot configuration.

To do so, you can re-use one of the syslinux templates:

# Create folders
mkdir /pxe-boot/pxelinux.cfg/

# Create configuration files
cp /usr/lib/syslinux/pxelinux.0 /pxe-boot/


The pxelinux.cfg folder is mandatory. Inside you can provide:

  • configuration for a specific IP @ or hostname
  • configuration for a group
  • default configuration (required)


Create the default configuration file:

vim /pxe-boot/pxelinux.cfg/default


Put the following:

# Ubuntu 14.04
LABEL TRUSTY
    kernel images/trusty/vmlinuz
    # Set NFS share as default root 
    append boot=nfs root=/dev/nfs initrd=images/trusty/initrd.img nfsroot=192.168.2.2:/pxe-boot/images/trusty

# Prompt user for selection
PROMPT 0

TIMEOUT 30
  • Each LABEL is a specific configuration that will displayed on the NetBoot menu.
  • PROMPT 1 = enable user prompt so you can choose the configuration
  • TIMEOUT 30 = timeout (in seconds) before the default option is choosen


Note that I used a reference to "trusty/", that's a folder I need to create later on.


Advanced menu

Install menu manager

Text menu:

cp /usr/lib/syslinux/menu.c32 /pxe-boot/


Graphic menu:

cp /usr/lib/syslinux/vesamenu.c32 /pxe-boot/
cp /mySuperPicture/logo.png /pxe-boot/pxelinux.cfg/

The associate picture must be a PNG 800x600 picture.


Configure boot options

Then edit the PXE boot file:

vim /pxe-boot/pxelinux.cfg/default


Put:

#### GENERIC OPTIONS #####
# Enable text menu
#DEFAULT menu.c32
# Enable graphical menu
DEFAULT vesamenu.c32
# Prompt for user input? (0 = choose from menu, 1 = you can type anything)
PROMPT 0
# Allow or not the user to left the menu (1 = user is locked to the menu)
NOESCAPE 1
# Time before using default option
TIMEOUT 50


#### Menu settings #####
MENU TITLE my super netboot menu
MENU BACKGROUND pxelinux.cfg/logo.png
MENU WIDTH 80
MENU ROWS 14
MENU MARGIN 10


#### Distributions #####
# Ubuntu 14.04
LABEL trusty
    MENU LABEL Ubuntu 14.04 (trusty)
    MENU DEFAULT
    # Kernel and boot files
    KERNEL images/trusty/vmlinuz
    ### Boot options
    # Set NFS share as default root 
    append boot=nfs root=/dev/nfs initrd=images/trusty/initrd.img nfsroot=192.168.2.2:/pxe-boot/images/trusty

# Debian wheezy
    MENU LABEL Debian Wheezy
    # Kernel and boot files
    KERNEL images/wheezy/vmlinuz
    append boot=nfs root=/dev/nfs initrd=images/wheezy/initrd.img nfsroot=192.168.2.2:/pxe-boot/images/wheezy


Note all the "MENU" commands + PROMPT 0


Security notes

in order to work you must adjust the rights of your "/var/lib/tftpboot/".

chmod 777 /pxe-boot/*
chmod 777 /pxe-boot/pxelinux.cfg/*



DHCP note

Don't forget to adjust your DHCP configuration if you plan to serve a specific file for a client!

vim /etc/dhcp/dhcp.conf



References

Ubuntu diskless how-to: https://help.ubuntu.com/community/DisklessUbuntuHowto Super video tutorials: