Understanding Floppy Firewall

A. Howlett
May 2002

Introduction

This document explains how floppyfw works. This document is based on the 1.9.20 release.

Booting the PC: the linux kernel

When you boot the PC, the microprocessor executes diagnostics stored on a non-volatile memory chip, often called CMOS. When the diagnostics are completed the CMOS instructs the microprocessor to load a boot sector from the boot device. In the case of floppy fw, the boot device is the first floppy disk drive. The microprocessor loads the first sector (512 bytes located at track 0 sector 0) of the floppy disk.

The first sector of the floppy disk must contain a boot loader. The boot loader is a very small program which loads, initializes and executes the kernel. The linux kernel has a built in boot loader, but most linux systems use the lilo or grub boot loaders. Floppy firewall uses a special purpose boot loader named SYSLINUX. SYSLINUX is rarely used because it only works with the DOS FAT filesystem. Because SYSLINUX cannot be used with the ext2 filesystem, it is unsuitable for use with hard disks, but can be useful when booting from a floppy.

SYSLINUX is only used with DOS FAT floppy disks. All the linux files are stored on this FAT formatted disk. The boot options are controlled by a file named SYSLINUX.CFG which must be in the root directory of the boot disk. Here is the floppyfw SYSLINUX.CFG file:

#
# 0 is the first port, 1 is the second and so on. 
# the last argument is the speed.
#
#serial 0 9600
default floppyfw
display floppyfw.msg
label floppyfw
 kernel vmlinuz
# Append stuff, usually the only stuff you might need to edit.
 append initrd=initrd.gz root=/dev/fd0 ether=0,0,0,eth0 ether=0,0,0,eth1 ether=0,0,0,eth2
#
# For console over serial port add this to the append line:
# and also remove the comment in the serial line (line one in this file)
#console=ttyS0,9600n 
#
# ttyS0 is com1, ttyS1 is com2
#

The "default" line specifies which boot configuration to use. "label floppyfw" starts the description of the floppyfw boot configuration. "kernel vmlinuz" specifies which kernel to use for the floppyfw configuration and the "append" command specifies the boot options. Here is a description of the most common kernel append commands.

Common Kernel Append Commands

initrd=root.tgz

file that syslinux will load for linux to create RAM disk with
initrd_archive=minix

initrd_archive=fstype

tell kernel to use fstype as the RAM disk filesystem type

ramdisk_size=5120

size in 1024 bytes for RAM disk

load_ramdisk=1

tell kernel to load initrd

root=/dev/fd0

where to run from

reboot={warm|cold},{hard|bios}

alternate ways for kernel to reboot, try if system hangs on reboot

vga=[-1, -2, -3, n]

set VGA console mode


The append command instructs the kernel to create a ramdisk, then decompress the filesystem stored in the initrd.gz file and copy this filesystem into the ramdisk.  

Creating the Root Filesystem

The linux kernel creates a ramdisk and decompresses and copies the initrd.gz file into the ramdisk. Most of the ramdisk is empty: the initrd.gz file contains only the /dev device files, the /linuxrc initialization script and a few files necessary to run the script - namely /bin/busybox and some shared libraries in /lib needed by busybox. Then the kernel runs the /linuxrc script.

busybox :  Most linux systems use the GNU binutils, fileutils, and shellutils utility collections. Busybox provides the same functionality in a much smaller package.

Here is the complete list of busybox commands: adjtimex, ar, basename, busybox, cat, chgrp, chmod, chown, chroot, chvt, clear, cmp, cp, cpio, cut, date, dc, dd, deallocvt, df, dirname, dmesg, dos2unix, dpkg, dpkg-deb, du, dumpkmap, dutmp, echo, expr, false, fbset, fdflush, find, free, freeramdisk, fsck.minix, getopt, grep, gunzip, gzip, halt, head, hostid, hostname, id, ifconfig, init, insmod, kill, killall, klogd, length, ln, loadacm, loadfont, loadkmap, logger, logname, ls, lsmod, makedevs, md5sum, mkdir, mkfifo, mkfs.minix, mknod, mkswap, mktemp, more, mount, mt, mv, nc, nslookup, ping, pivot_root, poweroff, printf, ps, pwd, rdate, readlink, reboot, renice, reset, rm, rmdir, rmmod, route, rpm2cpio, sed, setkeycodes, sh, sleep, sort, stty, swapoff, swapon, sync, syslogd, tail, tar, tee, telnet, test, tftp, touch, tr, true, tty, umount, uname, uniq, unix2dos, update, uptime, usleep, uudecode, uuencode, watchdog, wc, wget, which, whoami, xargs, yes, zcat, [

The /linuxrc script

The first configuration script mounts the /proc filesystem, sets up some symlinks pointing binutils towards the busybox utility, sets environment variables, mounts the boot device at /mnt/tmp, then executes the /mnt/tmp/floppyfw/floppyfw.ini script.

The floppyfw.ini script

The initrd.gz image was mostly empty - initrd.gz contains only the files necessary to run busybox. Most of the system files are stored in two bzipped tar files: modules/base.bz2 and floppyfw/add.bz2. By putting the system files in these two archives instead of the initrd, the floppyfw creators have made it easier to add and remove files. For instance, if you want to add a new module (maybe you want to add support for wireless ethernet cards) then you only need to unzip and extar the base.bz2 file, add the file to it's filestructure, then zip and tar the filestructure. You don't have to fiddle with ramdisks.

The floppyfw.ini script also copies the following configuration files to the ramdisk:

/mnt/tmp/config

->

/etc/config
/mnt/tmp/hosts

->

/etc/hosts
/mnt/tmp/modules.lst

->

/etc/modules.lst
/mnt/tmp/network.ini

->

/etc/network.init
/mnt/tmp/firewall.ini

->

/etc/firewall.init

stripcr :  The floppyfw configuration files are designed to be compatible with DOS text tools. This means that the configuration files are terminated with [LF][CR]. So the floppyfw initialization scripts have a special command, stripcr, which copies the configuration files to the ramdisk and removes the offending [CR] characters.

After copying files from the bootdisk to ramdisk, the floppyfw performs more tasks:

  1. Unzips and extars files from /mnt/tmp/packages/*.bz2 to the the ramdisk.

  2. It looks for a second floppy disk and unzips and extars files from the second floppy to the ramdisk.

  3. Loads the kernel modules

  4. Executes the /etc/network.init script.

  5. Unmounts the boot disk and removes the /mnt/tmp directory

  6. Launches the consoles.

Finally it enters a non-terminating loop. The loop performs one iteration per day which runs the /etc/daily.sh script.

Setting up the network: the network.init script

The network.ini sets up the network interfaces and services. Here's what it does:

  1. First it loads the network configuration from the /etc/config file

  2. Next it activates the loopback interface using the "ifconfig lo 127.0.0.1" command

  3. Then it activates the interface to the internal network.

  4. It adds its own name and IP address to the /etc/hosts file

  5. It sets the firewall's hostname and domain using the hostname command

  6. It configures the external interface and makes it the default gateway.

  7. It creates the /etc/resolv.conf file using values from /etc/config

  8. Creates a file /etc/outside.info containing useful information about the IP info

  9. Runs the /etc/firewall.init script (which sets up the netfilter tables)

  10. Enables TCP_syncookies. syncookies protect a socket from overload when too many connection attempts arrive.

  11. If the kernel has been built with reverse path anti-spoofing, then enable it.

.ini vs .init :  Floppyfw configuration files end with the suffix "ini" or "init". Files ending in "ini" are in MS text file format: i.e. lines are terminated by [LF][CR]. Files ending in "init" are in Unix format - the [CR] characters have been removed.

The config file

With so many initialization scripts and configuration files, it might seem a little bit vague to name a file "/config", but it's an important file. The config file contains excellent in-line documentatin, so I won't repeat it here. The config file specifies things like the device name for the internal and external networks, the IP addresses and netmasks for the internal and external networks, etc.

Setting up the Netfilter tables: the firewall.init script

The firewall.init script sets up the netfilter tables. I've written a separate tutorial explaining network filtering. Here's what the floppyfw network.init script does:

  1. flushes the tables

  2. sets the default policy to DROP for all chains

  3. enables masquerading (NAT)

  4. commands to enable ssh, web, and ftp from the external network to an internal server are commented out. You can uncomment these lines if you want to run these services.

  5. allows packets from previously established connections to enter the private network (required for masquerading)

  6. blocks NetBIOS and SAMBA

  7. accepts icmp in both directions

  8. accepts dhcp in both directions

  9. enables ip forwarding