Technocrat's Weblog

Sat, 10 Sep 2005

LiveCD Router

The LiveCD Router is a running, statically configured router. It is powered by Gentoo Linux. Instructions orginated from this thread on Gentoo's high traffic support forums. Using the CD allows the user to convert virtually any PC, with two ethernet cards, into a router in minutes. This combined with the LiveCDs read only nature allows for fast disaster recovery.

The CDROM is based in Gentoo's install CD. Officially it is called the LiveCD. The LiveCD is simple and console only. Its primary function is to install Gentoo to a computer but, can also function as a rescue CD. The CD is open source. This allows anyone to create their own copies of the LiveCD to serve other purposes, like routers. Other types of LiveCDs include gaming CDs and Flashlinux which runs on a 256MB USB key. A full GUI LiveCD, similar to Knoppix, is scheduled for release 2005.


Features

Prerequisites

Using the Router LiveCD

The Router LiveCD is preconfigured to provide route between two networks. It is possible to change these settings, and others, while the system is running. However, those changes would be lost if the system is rebooted.

Caveat: When the Router LiveCD boots, the kernel usually assigns the networks cards to eth0 and eth1 in order, starting from the lowest numbered PCI slot (closest the top of a tower case). However, this may not always be the case. If the system appears to have no network connections swapping the ethernet cables may help.

Once the system boots, all of its services are started automatically. No user interaction is required.

Changing Services on a Running System

The services NTP, BIND, Iptables, eth0, eth1 and hostname can be changed on a running system

NTPD is controlled by /etc/ntp.conf. The NTP server is listed in the 'server' variable. The service can be restarted by issuing the command /etc/init.d/ntpd restart.

Ntp-client is a one time ntp function that, at boot time, sets the system clock. This is useful when the clock is out of sync from the NTP server by a large margin. Ntp-client is controlled by the file /etc/conf.d/ntp-client. Change the hostname listed in the NTPCLIENT_OPTS variable. Restart the service using /etc/init.d/ntp-client restart.

Bind is controlled by the files in /etc/bind. The service can be restarted with /etc/init.d/named restart.

Iptables is controlled by the file /etc/init.d/iptables. The service can be restarted with /etc/init.d/iptables restart. Caveat: There is at least one IP address listed in the iptables file. If you are changing eth0 or eth1 you may also need to change this file.

Eth0 is controlled by the file /etc/conf.d/net. This service can be restated with /etc/init.d/net.eth0 restart.

Eth1 is controlled by the file /etc/conf.d/net. This service can be restated with /etc/init.d/net.eth1 restart.

Hostname is controlled by the file /etc/hostname. This service can restared with /etc/init.d/hostname restart.

For more information see the Gentoo documentation on init scripts.

Remember that all of these changes will be lost upon reboot. If you wish to have a permanent record of any changes you make, you will need to copy them to another server.

Changing the LiveCD Router

Creating or changing the LiveCD Router requires a running Gentoo distribution and chroot'ed environment. To do this from scratch, see the Gentoo forums thread listed at the top of this document. To change the existing one use the environment setup on your host. The source files are located in /usr/src/livecd. Inside that directory there are two directories and three files:

As root cd to /usr/src/livecd. Run the script sroot. This script enters you into a chroot environment located in the source directory. After the script is run you will be able to make changes to the environment that will exsit when your finished CD is running. Here you will see that it is much like any Linux you may encounter all the usual files are there. Things you may wish to change:

To change these services simply change the configuration files listed in the Changing Services on a Running System above. If you wish to change whether or not these services start at boot you can issue the rc-update command. To prevent the ntpd service from starting issue the command rc-update del ntpd default. This tells the Gentoo system to delete the service ntpd from the default run level. Not that some services run at the boot run level. To see all the boot levels and which services run under them see the directories and files under /etc/runlevels. For more information see the Gentoo documentation on init scripts and the rc-update man page.

Adding or Updating a Service or Program

The heart of the Gentoo system is Portage. Portage is very similar to Debian's apt. The Portage system is maintained by using the command emerge.

Definitions

Portage Tree is the collection of file located in /usr/portage. These files are used by emerge to determine the latest ebuilds available as well as their depencies.

Ebuild is a file that intructs emerge to how to install a program. It is similare to a makefile.

Useful emerge commands:

  1. Before you upgrade or install any program issue an emerge sync first. This will ensure that you install the lasted package available.
  2. Update or install the desired program
  3. If prompted, run etc-update to determine whether new configuration files in /etc/ should be merged with old ones, used in place of old ones or deleted and old ones retained.

Kernel changes

Should the kernel source be upgraded by emerge or if you simply want to alter the existing kernel you will need to build a new one. The kernel source in located under /usr/src. Any new source you install will have to patched in order to offer Squashfs which is used in creating the LiveCD. The kernel configuration file is /usr/src/kernel-config. Build the kernel as you normally would. Afterward, the kernel image is copied to /boot as any name you like. The LiveCD boots using Grub. The Grub menu is located in its usual place. Be sure to update it so that it boots the new kernel.

Initrd

Certain files must be loaded into an initial ramdisk (initrd image) in order for the LiveCD to boot. Should any of the changes you perform alter update particular files you will need to build a new ramdisk image. The files in question are:

/bin/sh
/bin/cat
/bin/mount
/bin/umount
/bin/mkdir
/bin/chroot
/bin/tar
/bin/pivot_root
/dev/console
/dev/null
/dev/hda
/dev/hdb
/dev/hdc
/dev/hdd
/dev/tty
/dev/loop0
/etc/fstab
/lib/libdl.so.2
/lib/libc.so.6
/lib/ld-linux.so.2
/lib/librt.so.1
/lib/libpthread.so.0
/linuxrc

It is highly unlikely that you will need to update these files. If you do then you will need to rebuild the ramdisk image.

Creating the initrd image

This is where most of the action occures during booting. It's a very simple task once you get the hang of it. First create the image, I'm using an 8MB initrd but feel free ot expand that if you need more, just remember to set the option in your kernel configuration for the maximum ramdisk size properly.

touch /boot/initrd
dd if=/dev/zero of=/boot/initrd bs=1024k count=8
losetup /dev/loop0 /boot/initrd
mke2fs /dev/loop0
mkdir /mnt/initrd
mount /dev/loop0 /mnt/initrd

Now populate the image with required directories and files:

cd /mnt/initrd
mkdir etc dev lib bin proc new cdrom
touch linuxrc
chmod +x linuxrc
touch etc/mtab
touch etc/fstab

linuxrc is what will get executed when linux boots. More on it below.

Now you need to copy necessary files into bin and lib. For bin, copy the following:

/bin/sh
/bin/cat
/bin/mount
/bin/umount
/bin/mkdir
/bin/chroot
/bin/tar
/sbin/pivot_root

For lib, you'll need to find out which lib files are needed by each of the binaries above. The way to do it is to run 'ldd' for each file above and copy the required libs over. Example

ldd /bin/mount
        linux-gate.so.1 =>  (0xffffe000)
        libc.so.6 => /lib/libc.so.6 (0x4002e000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
cp /lib/libc.so.6 /mnt/initrd/lib/
cp /lib/ld-linux.so.2 /mnt/initrd/lib/

And so on for the rest of the binaries.

Now, we need to create necessary devices under dev directory:

mknod /mnt/initrd/dev/console c 5 1
mknod /mnt/initrd/dev/null c 1 3
mknod /mnt/initrd/dev/hda b 3 0
mknod /mnt/initrd/dev/hdb b 3 64
mknod /mnt/initrd/dev/hdc b 22 0
mknod /mnt/initrd/dev/hdd b 22 64
mknod /mnt/initrd/dev/tty c 4 0
mknod /mnt/initrd/dev/loop0 b 7 0

Finally, we need to create our linuxrc script. The script will do the follwoing:

  1. Save whatever is passed to the kernel to pass it later on to /sbin/init
  2. Locate the CDROM device (we search only in hda, hdb, hdc, and hdd, which are the most common IDE cdrom drives)
  3. Mount the cdrom on /cdrom
  4. Mount the squashed filesystem image (which is our whole gentoo installation compressed to a single file) on /new. This will become our root filesystem, which is read-only
  5. Create necessary read-write mount points (etc, var, tmp, and root) as tmpfs filesystems and fill them up
  6. Finally, pivot the root filesystem on newroot and start the real init process
#!/bin/sh
export PATH=/bin

# Get kernel CMDLINE
mount -t proc none /proc
CMDLINE=`cat /proc/cmdline`
umount /proc

# Mount CD device
CDROM=""
for x in hda hdb hdc hdd
do
  mount -t iso9660 -r /dev/${x} /cdrom > /dev/null 2>&1
  if [ "$?" = "0" ]
  then
    CDROM="${x}"
    break
  fi
done

# CD not found
if [ "${CDROM}" == "" ]
then
  exec /bin/sh
  exit
fi

# Mount root and create read-write directories
mount -t squashfs -o loop /cdrom/files/source.img /new > /dev/null 2>&1
mount -t tmpfs -o size=24m none /new/var > /dev/null 2>&1
mount -t tmpfs -o size=8m none /new/etc > /dev/null 2>&1
mount -t tmpfs -o size=8m none /new/tmp > /dev/null 2>&1
mount -t tmpfs -o size=8m none /new/root > /dev/null 2>&1
cd /new/var && tar xpf /cdrom/files/var.tar > /dev/null 2>&1
cd /new/etc && tar xpf /cdrom/files/etc.tar > /dev/null 2>&1
cd /new/root && tar xpf /cdrom/files/root.tar > /dev/null 2>&1

# Pivot root and start real init
cd /new
pivot_root . newroot
exec chroot . /bin/sh <<- EOF >dev/console 2>&1
exec /sbin/init ${CMDLINE}
EOF 

Finishing

When you have finished make change to the system issue the exit command to return to /usr/src/livecd. Now run the build script. When the build script is done the livecd.iso will be new created and contain all of your changes. Burn the image to CDROM and begin using it.

Scripts
sroot

#!/bin/bash

mount -o bind /proc source/proc
mount -o bind /sys source/sys
mount -o bind /dev source/dev
mount -o bind /dev/pts source/dev/pts
mount -o bind /usr/portage/distfiles source/usr/portage/distfiles
chroot source/ /bin/bash --login
umount source/proc
umount source/sys
umount source/dev/pts
umount source/dev
umount source/usr/portage/distfiles 
build

 #!/bin/bash
rm -rf target
mkdir target
cp -a source/boot target/
mkdir target/files
rm -rf source/var/tmp/*
rm -rf source/var/lock/*
rm -f source/var/run/*
rm -rf source/tmp/*
rm -f source/etc/mtab
touch source/etc/mtab
cd source/etc/
tar cvpf ../../target/files/etc.tar * .[[:alnum:]]*
cd ../var/
tar cvpf ../../target/files/var.tar * .[[:alnum:]]*
cd ../root/
tar cvpf ../../target/files/root.tar * .[[:alnum:]]*
cd ../../
pwd

mksquashfs source/ target/files/source.img
mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size \
4 -boot-info-table -iso-level 4 -hide boot.catalog -o livecd.iso target/