Linux Home
Automation

(Last updated: Fri. Sep 24, 2004)
Google
 

Floppy Firewall Howto


Current Status (briefly):

09/24/2004 - Imagine my surprise when I went searching for something and came across my own page! Why is it a surprise? because I haven't posted any information anywhere about this page. As you can see it's not done. The links to other places may be of some use. Yes I'm still working on it.


Links


Purpose

To build a Linux based firewall that can support my current and future network needs. Currently this include internet connectivity, wireless access, firewall and logging. In the immediate future I'll be adding traffic shaping for VoIP and later IPV6.

Reason

Currently the routers I have are too old and no longer have support. Also the newer routers, which provide the support I need, are expensive.

I've been having a load of problems with my collection of routers. I have a Linksys BEFW11S4 (V4), a Netgear RT311 and a Zyxel P314. While the Zyxel and the Netgear were well behaved the available firmware left something to be desired (no fixes anymore because of age). It tended to crash after a couple of days of use (over flows from probes looking for MS Windows machines). The Linksys on the other hand hasn't worked correctly since the day I go it! It has some of the worst firmware I've every seen. While I have a Cisco 2514 router it won't be long before I can't get new IOS for it and I can't afford a new Smartnet contract or a new Cisco router. Hence the idea to use what I do know very well, can fix the code (if I put my mind to it) and can grow with my needs. That's right I decided on Linux via Floppy Firewall 2.0.9.

I decided that I would start by using Etherboot to test the firewall. I'd burn the ROM, boot from the ethernet card, get the Firewall image from the DHCP server and off we'd go. Fewer moving parts (power supply still has the fan and so does the CPU). After I've tested the Firewall for a time I wanted to move the image off the DHCP server to the compact flash. I think I need things such as snmpd and the routing protocols (Zebra?) and a few other things. These things won't fit on a floppy, not even the extended 1680 sector disk. With the last trouble from my Linksys I've also decided that I'll use the FFW as a wireless access point. But I'm still researching this (equipment is on the way).

Minimum stuff you'll need

  • IBM PC clone motherboard (386 or better), power supply and case (yes I recommend a case :-)
  • At least 16M of RAM
  • 2 network cards (I prefer to work with 2 of the same cards)
  • Floppy drive that support 1.44M floppies.
  • OR
  • appropriate ROM (for Etherboot)
  • OR
  • Compact flash and CF-IDE adapter.

What I've built this on

Basically I built this on top of one of my older systems. Really this is overkill but it's what I had. The Future: stuff is either in transit or stuff I'm waiting on funding to purchase (my wife is the CFO and approves all purchases. :-).

  • K7xxx PCI motherboard (with all sorts of stuff I don't need :-)
  • AMD-K6(tm) 3D processor, 417.617 MHz, 64 KB cache
  • 256M RAM (over kill, uses about 10M of RAM w/ 3.5M ram disk).
  • Netgear FA310TX 10/100 PCI cards (requires tulip and mii modules)
  • Floppy drive (actually used for Etherboot floppy)
  • Future: Belkin 802.11B wireless PCI card
  • Future: Compact Flash card (16M - 256M)
  • Future: Soekris embedded boards - the net4801 may be useful for the Asterisk PBX
  • Future: Wireless Router Access Platform
  • Future: Intel® PRO/Wireless 2100

And my other machine:

  • MZ104 PC/104 Single Board Computer w/ 3 ISA slot adapter.
  • 16M RAM
  • 3Com 3C5089-TP 10M ISA cards
  • Floppy drive (actually used for Etherboot floppy)
  • Future: Compact Flash card (16M - 256M)

Things to get

Etherboot

There are 2 ways to bring up Etherboot . Both start at ROM-o-matic. I used the 3C509:3C509 (3COM ISA board) and the tulip:82c168 (FA310TX) for my 2 machines. I then selected the Floppy Boot ROM Image .zdsk. I also configure different options to meet my needs.

  ASK_BOOT:
  Ask "Boot from (N)etwork ... or (Q)uit? " at startup, timeout after n seconds (0 = no timeout). If unset or negative, don't ask and boot immediately using the default.
  BOOT_FIRST:
  On timeout or Return key from previous question, selects the order to try to boot from various devices.
(alternatives: BOOT_NIC, BOOT_DISK, BOOT_FLOPPY, BOOT_NOTHING).
See etherboot.h for prompt and answer strings.
 BOOT_SECOND:
  On timeout or Return key from previous question, selects the order to try to boot from various devices.
(alternatives: BOOT_NIC, BOOT_DISK, BOOT_FLOPPY, BOOT_NOTHING).
See etherboot.h for prompt and answer strings.
 BOOT_THIRD:
  On timeout or Return key from previous question, selects the order to try to boot from various devices.
(alternatives: BOOT_NIC, BOOT_DISK, BOOT_FLOPPY, BOOT_NOTHING).
See etherboot.h for prompt and answer strings.
 BOOT_INDEX:
  The device to boot from:
0 == any device.
1 == The first nic found.
2 == The second nic found
...
BOOT_INDEX only applies to the BOOT_FIRST. BOOT_SECOND and BOOT_THIRD search through all of the boot devices.
  :
  :
  :
CONSOLE_SERIAL
  set for serial console.
  :
  :
  :
CONFIG_PCI
  Include support for devices using the pci bus.
CONFIG_ISA
  Include support for devices using isa bus.
  :
  :
  :

Floppy Firewall (via a floppy)

This is the easiest method for using Floppy Firewall (FFW). Just follow the directions for installation found at the Floppy Firewall site.

1/_ Change these lines in the Config file: (I use COM1)

# Choose the serial port for the console "n" for none.
SERIAL_CONSOLE=ttyS0
#SERIAL_CONSOLE=n

Floppy Firewall (via Etherboot)

This was taken from the mkffwnbi.pl script in Etherboot's contrib directory. I've attempted to convert it to a loop mounted file system since I have no need to use the floppy then. I have the script but it really needs to be cleaned up. I might try to keep both the floppy version as well as the actual image. Currently this seems to work with FFW 2.0.x. I'm not sure about 2.9.x as I've had a lot of problems booting it with Etherboot.

Right now this probably doesn't make much sense as it's the pseudo code from mkffwnbi.pl

Prerequisites:

  • MSDOS floppy with FFW on it.

OR

  • The a current image or a directory of the image (can be the image loop mounted). For now this set of options require my modified perl script (ask and ye shall receive).

Steps:

  1. Create temp directory and cd to it
  2. Copy files off MSDOS Floppy (how can we do this with a filesys instead of the floppy)
  3. gunzip initrd.gz
  4. if ffw29 extend initrd (FFW 2.9.x) I hope to explain what this means later for now here is the code which may be self evident:
    sub extendinitrd ($$) {
    	my ($initrd, $nblocks) = @_;
    
    	if ($nblocks <= 1440) {
    		print STDERR "nblocks must be >= 1440\n";
    		return (1);
    	}
    	(undef, $type, undef, $fnlen, undef)  = split(' ', `file $initrd`, 5);
    	print "$type $fnlen\n";
    	if ($type ne 'Minix' || $fnlen != 30) {
    		die "Can only handle Minix initrds with 30 char filenames\n";
    		return (1);
    	}
    	status_system("dd if=/dev/zero of=newinitrd bs=1k count=$nblocks", "Cannot create new initrd\n");
    	status_system("mkfs.minix -n 30 newinitrd $nblocks", "Cannot mkfs.minix new initrd\n");
    	mkdir("initrd.from") || print STDERR "Cannot make temp mount point initrd.from\n";
    	mkdir("initrd.to") || print STDERR "Cannot make temp mount point initrd.to\n";
    	status_system("mount -o ro,loop $initrd initrd.from", "Cannot mount $initrd on initrd.from");
    	status_system("mount -o loop newinitrd initrd.to", "Cannot mount newinitrd on initrd.to");
    	status_system("cp -a initrd.from/* initrd.to/", "Cannot copy initrd to newinitrd");
    	status_system("umount initrd.from", "Cannot umount initrd.from");
    	status_system("umount initrd.to", "Cannot umount initrd.to");
    	rmdir("initrd.from") || print STDERR "Cannot remove temp mount point initrd.from\n";
    	rmdir("initrd.to") || print STDERR "Cannot remove temp mount point initrd.to\n";
    	return (0);
    }
  5. create temp mnt point, then mount -o loopback initrd <tmp_mnt_pt>
  6. d2u linuxrc (D2U is a DOS line ending to Unix line ending conversion routine)
  7. d2u floppy.ini
  8. d2u etc/config
  9. bunzip & untar floppyfw/add.bz2 modules/*.bz2 & packages/*bz2
  10. d2u packages/pre-*.ini & packages/post-*.ini to etc/$file # Put everything in /etc
  11. d2u hosts -> etc/hosts
  12. d2u modules.lst -> etc/modules.lst
  13. d2u network.ini -> etc/network.init
  14. d2u firewall.ini -> etc/firewall.init
  15. d2u syslog.conf -> etc/syslog.conf
  16. d2u packages/timeinfo -> etc/localtime (this doesn't seem to work for me)
  17. cp licenses to /licenses
  18. cp modules/* to /lib/modules
  19. if localtime copy localtime to /etc/localtime (??? are we doing this twice?)
  20. umount the loopback
  21. gzip initrd
  22. mknbi-linux $append --output=$output vmlinuz initrd.gz ; rm -rf $tempdir Here we're making the network bootable image (2.9.x uses mkelf)
  23. ... aren't there more steps? Like copy the image to tftpboot???
  24. done

Floppy Firewall (via CF)

Yeah, I'm working on it. First I need to get the hardware.


OK, the stuff after this is directly from the Floppy Firewall HOWTO's list. I haven't tidied it up and I still need to give credit where credit is due (I didn't write these). I simply have these here for now because I hate to lose anything that I might need later.


Building packages for Floppy Firewall

To get executables for FloppyFW on systems that don't have glibc2.0.7
(like RedHat6.2+ and Mandrake 7.2+) one needs one to two things :
A compiler (more or less Mandrake only) and the glibc2.0.7 :

1.) The Compiler
   Basically every compiler should work. However, Mandrake optimizes
   for pentium and floppyfw should not be optimized for pentium.
   Therefore I would try  2 things :
   a) always use the -m388 -march=i386 flags when defining the compiler.
      i.e. change the lines in the Makefile that have
      CC = gcc   to   CC = gcc -m388 -march=i386
   b) Mandrake's default compiler is not the standard one. If you are
      cautions you also might want to try to use egcs instead. Mandrake
      has an egcs package. To call egcs instead of gcc, first find the
      version with "egcs-version" (for me it is egcs-2.91.66), then
      edit the Makefile and substitute
      CC = gcc  with CC = gcc -V egcs-2.91.66
      you can, of course do a) and b)

2.) The correct library
   On Mandrake7.2 system, you can install the package
   compat-glibc-5.3-2.0.7.9mdk. This includes runtime libraries, headers
   and all you need to make 2.0.7 executables. RedHat probably has
   something like that, too. You might want to try to install
   the Mandrake rpms which can be found from a site listed on
   http://www.linux-mandrake.com/en/ftp.php3 as
   Mandrake/7.2/i586/Mandrake/RPMS/compat-glibc-5.3-2.0.7.9mdk.rpm
   
   First thing in the Makefile, make sure you use the 2.0.7 header
   files, best thing is to add it to CFLAGS. e.g. substitute
   CFLAGS = -O   with  CFLAGS = -O -I/usr/i386-glibc20-linux/include
   or wherever your package put the header files.

   Now, it's time to reveal my dirty tricks :-). There may be a better
   way to do it, but I didn't want to try out much more last night.
   I changed the linker flags in the Makefile, i.e. it looks now
   LDFLAGS =   -s -nostdlib -L/usr/i386-glibc20-linux/lib
/usr/i386-glibc20-linux/lib/libc.so /usr/i386-glibc20-linux/lib/crt1.o
   (on ONE line, though !)
   plus the previous linker flags. That compiled micro_httpd and
   micro_inetd
   
   You should also get away with
   LDFLAGS =   -s -nostdlib -L/usr/i386-glibc20-linux/lib -lc
/usr/i386-glibc20-linux/lib/crt1.o
   (on ONE line again). Maybe even with
   LDFLAGS = -s -nodefaultlib -L/usr/i386-glibc20-linux/lib -lc   

   If you want to read the man or info pages to gcc look for
   -nstdlib -nodefaultlib and -nostartfiles
   
   How to test ?
   if you do a ldd executable on your Mandrake or RedHat box, it will
   still show you the system defaults, since it finds those first.
   But it also will add the noversion libraries, since it sees the
   version mismatch.
   I then copy  the plain executable onto the floppyfw floppy in
   a newly created directory (I call it extra) and put that in my
   floppyfw box. Remember you don't have to reboot your floppyfw
   all the time - it's sneaker net time :-) ...
   Then mounting the floppy again on my floppyfw and running the
   newly compiled executable straight from the floppy should tell
   you if it works or not : a seg fault means, it still expects the
   2.1.X libraries :-)


Building Floppy Firewall (from scratch)

Other

3ethernets-multi_ip.txt

---------------------------------------------------------------------------
REVISED.

Introduction:
-------------
I've been playing with this "floppyfw" for a few months.  After I got 
it to work, I haven't spend much time with it.  Just a few days ago,
someone was asking for the configuration of a "three ethernets floppyfw"
(outside, inside and DMZ).  It just happen that I got this type of 
configuration running on my home network, so I posted serveral messages
to help him out.  He also asking about adding another IP address into the
OUTSIDE interface.  Multiple IP addresses, you may say.  It was kind of 
messy to look thru those messages, so Thomas asked me if I can merge them 
together.  As my contribution to the community, I put together this 
"3 ethernets and multiple outside IP" configuration.  I hope it will
help some of you out there.


This is the sample network layout (by Luca Giugno):


                 Internet
      213.82.100.10 and 213.82.100.11
                     |
                     !
           -----------------------
           |        ffw          |----- DMZ 10.10.1.1
           -----------------------
                     |
                     |
                Internal LAN
                192.168.1.1

Requirment:  -- 213.82.100.10:80 ---> 10.10.1.2:80
             -- 213.82.100.11:80 ---> 10.10.1.3:80

10.10.1.2 and 10.10.1.3 are the two web servers on the DMZ subnet.



The Configurations:
-------------------
I'm going to organize these setup based on the floppyfw's configuration 
files.  Most of the configuration are single line.  It's word-wraped.



1/. "syslinux.cfg" file.
	
Check to see "syslinux.cfg" is ready for 3rd NIC.  If it doesn't have
"ether=0,0,0,eth2" in the append line, add it to the end.  The new
lines should look like this:

# 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


2/. "config" file.

You need another section in the "config" file called DMZ.  This will help
you assign and change IP address and such for the DMZ.

#
# DMZ network:
#
DMZ_DEV=eth2
DMZ_IP=10.10.1.1
DMZ_NETMASK=255.255.255.0
DMZ_NETWORK=10.10.1.0
DMZ_BROADCAST=10.10.1.255

Since you going to add another IP to the OUTSIDE interface, add this to
the OUTSIDE section.

OUTSIDE_DEV2=eth0:0    #or eth1:0 if you switch your interface around.
OUTSIDE_IP2=213.82.100.11
OUTSIDE_NETMASK2=255.255.255.0  #(Class C mask, yours maybe diffenrent)
OUTSIDE_NETWORK2=213.82.100.0
OUTSIDE_BROADCAST2=213.82.100.255
	
Also, web traffic need to be forwarded to the DMZ servers.  You define
these servers here by adding these into the "Misc" section.

SERVER1_IP=10.10.1.2
SERVER2_IP=10.10.1.3
    
Note: Lately, Thomas put these in the firewall.ini.  You may want to
have them there instead of here.


3/. "network.ini" file.

Add a section called DMZ as follow to "network.ini" file.  I put it
right after the "Inside" section.  
 
#
# DMZ:
#
/bin/ifconfig ${DMZ_DEV} ${DMZ_IP} netmask ${DMZ_NETMASK} broadcast ${DMZ_BROADCAST}

#
# Brad wanted these next 5 lines.
#
echo "DMZ_DEVICE=${DMZ_DEV}"          > /etc/dmz.info
echo "DMZ_IP=${DMZ_IP}"               >> /etc/dmz.info
echo "DMZ_NETWORK=${DMZ_NETWORK}"     >> /etc/dmz.info
echo "DMZ_NETMASK=${DMZ_NETMASK}"     >> /etc/dmz.info
echo "DMZ_BROADCAST=${DMZ_BROADCAST}" >> /etc/dmz.info

#
# setting up /etc/hosts
#
echo "${DMZ_IP}	${HOSTNAME}.dmz" >> /etc/hosts
# 
# End DMZ
#


For assigning the 2nd IP address into the OUTSIDE interface, add the
below "Multi IP" section right after the "Outside" section.
You will see these lines:

    fi # if EXTERNAL  
fi     # if DHCP      

So add these after them.  Note: work even your 1st IP is DHCP.
#
# Multi IP
#
if [ "$OUTSIDE_IP2" != "" ]
 then
  /bin/ifconfig ${OUTSIDE_DEV2} ${OUTSIDE_IP2} netmask ${OUTSIDE_NETMASK2} broadcast ${OUTSIDE_BROADCAST2}
fi


4/. "firewall.ini" file.

WARNING:  Since I'm not an expert in this area, the setup that I have
here is not the best and secure one.  This is only the basic to get the
requirement above working.  That is routing between INSIDE and DMZ,
NAT outbound traffic and forward inbound web traffic to DMZ servers.
Please consult an expert to get a better filter rules.

Add the dmz.info to firewall.ini as suggested in the newsgroup.
Should look like this:

#
# Overriding the /etc/config and adding additional information.
#
. /etc/outside.info
. /etc/inside.info
. /etc/dmz.info


There are 2 major versions of floppyfw, 1.X and 2.X.  One using ipchains/masq
and the later using iptables.  Add these lines into "firewall.ini" depend
on what version you are using.


_ For ipchains/masq (floppyfw 1.X)
	
# Accepting packets between Inside and DMZ
ipchains -A forward -s ${INSIDE_NETWORK}/${INSIDE_NETMASK} -d ${DMZ_NETWORK}/${DMZ_NETMASK} -j ACCEPT
ipchains -A forward -s ${DMZ_NETWORK}/${DMZ_NETMASK} -d ${INSIDE_NETWORK}/${INSIDE_NETMASK} -j ACCEPT

# Accepting web traffic
ipchains -A input -p TCP -d ${OUTSIDE_IP} 80 -j ACCEPT
ipchains -A input -p TCP -d ${OUTSIDE_IP2} 80 -j ACCEPT

# Forwarding web traffic
ipmasqadm portfw -a -P tcp -L ${OUTSIDE_IP} 80 -R ${SERVER1_IP} 80
ipmasqadm portfw -a -P tcp -L ${OUTSIDE_IP2} 80 -R ${SERVER2_IP} 80

	
_ For iptables (floppyfw 2.X)

# Keep state. (for DMZ)
iptables -A FORWARD -m state --state NEW -i ${DMZ_DEVICE} -j ACCEPT

# We don't like the NetBIOS and Samba leaking. (from DMZ)
iptables -t nat -A PREROUTING -p TCP -i ${DMZ_DEVICE} --dport 135:139 -j DROP
iptables -t nat -A PREROUTING -p UDP -i ${DMZ_DEVICE} --dport 137:139 -j DROP
iptables -t nat -A PREROUTING -p TCP -i ${DMZ_DEVICE} --dport 445 -j DROP
iptables -t nat -A PREROUTING -p UDP -i ${DMZ_DEVICE} --dport 445 -j DROP

# Accepting packets between Inside and DMZ
iptables -A FORWARD -s ${INSIDE_NETWORK}/${INSIDE_NETMASK} -d ${DMZ_NETWORK}/${DMZ_NETMASK} -j ACCEPT
iptables -A FORWARD -s ${DMZ_NETWORK}/${DMZ_NETMASK} -d ${INSIDE_NETWORK}/${INSIDE_NETMASK} -j ACCEPT

# Accepting web traffic
iptables -A FORWARD -p tcp -d ${SERVER_IP1} --dport 80 -o ${DMZ_DEVICE} -j ACCEPT
iptables -A FORWARD -p tcp -d ${SERVER_IP2} --dport 80 -o ${DMZ_DEVICE} -j ACCEPT

# Forwarding web traffic
iptables -A PREROUTING -t nat -p tcp -d ${OUTSIDE_IP} --dport 80 -j DNAT --to ${SERVER_IP}:80 
iptables -A PREROUTING -t nat -p tcp -d ${OUTSIDE_IP2} --dport 80 -j DNAT --to ${SERVER_IP2}:80 
	
# And also, DHCP, but we can basically accept anything from the inside. (for DMZ)
iptables -A INPUT -i ${DMZ_DEVICE} -j ACCEPT
iptables -A OUTPUT -o ${DMZ_DEVICE} -j ACCEPT    

That's it.

IPV6

How to add IPv6 over IPv4 support to your network behind a NAT router.
----------------------------------------------------------------------

Table of Contents


  1. Introduction

     1.1 Copyright
     1.2 Disclaimer
     1.3 Credits
     1.4 Changelog
  
  2. What's IPv6? What can it do for me?

  3. How do I connect to the 6bone?

  4. What should I allow through the firewall?

  5. Configuring the IPv6 machines/routers

  5.1. Linux

  5.2. Windows

    5.2.1 IPv6 stand-alone machine
    5.2.2 IPv6 network
      5.2.2.1 The Router
      5.2.2.2 The clients

  6. Examples
     6.1 Windows PC using IPv6, behind iptables NAT/MASQ, with a tunnel from HE.
     6.2 Multiple Windows PCs using IPv6, behind iptables NAT/MASQ, with a tunnel from BTExact.

----------------------------------------------------------------------

1. Introduction


1.1 Copyright 

This document is Copyright 2002 by Hern\x{00E1}n Freschi. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license can be found at www.gnu.org. 


1.2 Disclaimer 
Use the information in this document at your own risk. I disavow any potential liability for the contents of this document. Use of the concepts, examples, and/or other content of this document is entirely at your own risk. 

All copyrights are owned by their owners, unless specifically noted otherwise. Use of a term in this document should not be regarded as affecting the validity of any trademark or service mark. 

Naming of particular products or brands should not be seen as endorsements. 

You are strongly recommended to take a backup of your system before major installation and backups at regular intervals. 



1.3 Credits 

Hern\x{00E1}n Freschi 

Microsoft, Windows, 2000, XP, SP1, .NET Server 2003 are all trademarks of Microsoft Corp.

Any comments or suggestions can be mailed to my mail address on: hjf(at)hjf.com.ar

This document is still in beta phase, so errors and omissions may be present. 



1.4 Changelog

0.1 Initial Release.



Getting Started



2. What's IPv6? What can it do for me?

Sorry, that is beyond the scope of this document. This aims to make a iptables firewall to allow incoming traffic from an IPv6 tunnel.



3. How do I connect to the 6bone?

Through a tunnel broker!. Get your account (for free) at:

www.tunnelbroker.net (USA)
tb.ipv6.btexact.com (UK)
tb.ngnet.it (Italy?)

You could also use www.freenet6.net, but they use proprietary software, which doesn't run inside a network. But it's easier to implement and even assigns /48 subnets.



4. What should I allow through the firewall?

Everything that comes from the tunnel address, except ICMP (what for? let the linux box answer, so the packets dont get in the network). The rules I use are this:

iptables -A FORWARD -s  -p ! ICMP -i eth0 -j ACCEPT
iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 

And that's it. The outgoing packets don't need special treatment.

Note: This, of course, assumes that your Linux firewall doesn't handle the IPv6 packets. It's designed to run on tiny distros like FloppyFW (www.zelow.no/floppyfw) or LRP (www.lrp.org). With this, the firewall doesn't need support for IPv6. These packets are handled in an internal, more powerful (ie: with a hard disk) computer.



5. Configuring the IPv6 machines/routers

5.1 Linux

I don't have a linux box to experiment, you can either
a) Donate a hard disk, so I can install linux again or
b) Write this section for me :)

5.2 Windows (2000/XP/XP-SP1/.NET Server 2003 ONLY! Win9x is UNSUPPORTED).

First of all, you have to install IPv6 support:

C:\> ipv6 install
Installing...

Success.

5.2.1 IPv6 stand-alone machine:

Use your brokers script! If they didn't provide one, use these:

ipv6.exe rtu ::/0 2/::
ipv6.exe adu 2/

The 2/ is the Interface Index. It's usually 2, but it may vary. If in doubt, type

ipv6 if

and look for a line like this:

Interface 2: Automatic tunnel pseudo-interface

The number, obviously, is the one you are looking for.


5.2.2 IPv6 network

(Note: this applies only to the external network. If you need help setting up the IPv6 lan, read www.microsoft.com/ipv6)

5.2.2.1 The Router

Use your brokers script! If they didn't provide one, use these:

ipv6.exe rtu ::/0 2/::
ipv6.exe adu 2/
ipv6.exe rtu / 4 pub life 86400
ipv6.exe ifc 2 forw
ipv6.exe ifc 3 forw
ipv6.exe ifc 4 forw adv

2, 3, 4 are the interface indices. They may vary. To find out, type

ipv6 if

5.2.2.2 The clients

You don't need to do nothing, they are auto configured.



6. Examples:

6.1 Windows PC using IPv6, behind iptables NAT/MASQ, with a tunnel from HE.

Equipment required:
1 Box capable of running iptables (kernel = 2.4.x)
1 Box running Microsoft\x{00AE} Windows 2000, Windows XP (SP1), Windows .NET Server 2003.

Tunnel:
1 /127 Allocation from Hurricane Electric

  +---+            +---+           \/\/\/\/\/         +------+          /\/\/\/\/\
  |WIN|------------|FFW|-----------/INTERNET\---------|TUNNEL|----------\  6bone /
  +---+            +---+           \/\/\/\/\/         +------+          /\/\/\/\/\
10.42.42.100<->10.42.42.1   <->   209.13.122.2  <->  ipv6.he.net <->   2001:470:1F00:FFFF::xxxx

Configuration:
On the Linux box type:

iptables -A FORWARD -s 64.71.128.82 -p ! ICMP -i eth0 -j ACCEPT
iptables -t nat -A PREROUTING -s 64.71.128.82 -i eth0 -j DNAT --to 10.42.42.100

On the MS box type:

ipv6 rtu ::/0 2/::64.71.128.82 pub
ipv6 adu 2/2001:470:1F00:FFFF::xxxx

Congratulations. You are set.

Now try pinging to 6bone.net, for example. 


6.2 Multiple Windows PCs using IPv6, behind iptables NAT/MASQ, with a tunnel from BTExact.

Equipment required:
1 Box capable of running iptables (kernel = 2.4.x)
n Boxes running Microsoft\x{00AE} Windows 2000, Windows XP (SP1), Windows .NET Server 2003.

Tunnel:
1 /64 Allocation from Hurricane Electric


  +---+ +---+ +---+
  |WIN| |WIN| |WIN|
  +---+ +---+ +---+
    +-----+-----+
  +---+            +---+           \/\/\/\/\/         +------+          /\/\/\/\/\
--|WRT|------------|FFW|-----------/INTERNET\---------|TUNNEL|----------\  6bone /
  +---+            +---+           \/\/\/\/\/         +------+          /\/\/\/\/\

10.42.42.100<->10.42.42.1   <->   209.13.122.2  <->  193.113.58.80 <-> 2001:618:400::xxxx:xxxx

Configuration:
On the Linux box type:

iptables -A FORWARD -s 64.71.128.82 -p ! ICMP -i eth0 -j ACCEPT
iptables -t nat -A PREROUTING -s 64.71.128.82 -i eth0 -j DNAT --to 10.42.42.100

On the MS router type:

ipv6.exe rtu ::/0 2/::193.113.58.80
ipv6.exe adu 2/2001:618:400::xxxx:xxxx
ipv6.exe rtu 2001:618:400:xxxx::/64 4 pub life 86400
ipv6.exe ifc 2 forw
ipv6.exe ifc 3 forw
ipv6.exe ifc 4 forw adv

On the other machines type:

Nothing, they are auto configured. If they dont work, try:

ipv6 reset

If that doesn't work, check for a default route (::/0). 

ipv6 rt

If there isn't one, try adding one:

ipv6 rtu ::/0 n/(your routers ipv6 address)

(where n is the interface index of the ethernet board connected to the network, usually 4).

If it works, but the next time you reboot, it does not auto configure, then maybe you are not publishing the default route in the router.

Congratulations. You are set.

Now try pinging to 6bone.net, for example. 

TC

1) Create a floppy with floppyfw 1.9.20.

2) Place http://www.zelow.no/floppyfw/download/packages/tc/tc.bz2 (doesnt
seem to be kernel specific - its more busybox/libc specific) and
http://www.zelow.no/floppyfw/download/modules/2.4.18/tcmods.bz2 (is kernel
specific, so if you use other kernel than floppyfw (or like upgrade on
your own) you need to update these aswell) in directory a:\packages\ on
the floppy.

3) Edit file a:\modules.lst and place following info in the end of the
file:

#
# tc (trafficshaping) modules:
#
#cls_fw.o
#cls_route.o
#cls_rsvp.o
#cls_tcindex.o
cls_u32.o
sch_cbq.o
#sch_csz.o
#sch_dsmark.o
#sch_gred.o
#sch_ingress.o
sch_prio.o
#sch_red.o
sch_sfq.o
sch_tbf.o
#sch_teql.o

4) Edit file a:\firewall.init and place following info in the end of the
file:

#
# Rules for trafficshaping
#

echo
echo "Configuring trafficshaping."

#root
tc qdisc add dev ${INSIDE_DEVICE} root handle 1:0 cbq bandwidth 100Mbit avpkt 1000 cell 8
tc qdisc add dev ${OUTSIDE_DEVICE} root handle 1:0 cbq bandwidth 100Mbit avpkt 1000 cell 8

#root class
tc class add dev ${INSIDE_DEVICE} parent 1:0 classid 1:1 cbq bandwidth 100Mbit rate 7Mbit weight 700kbit prio 8 allot 1514 cell 8 maxburst 20 avpkt 1000
tc class add dev ${OUTSIDE_DEVICE} parent 1:0 classid 1:1 cbq bandwidth 100Mbit rate 7Mbit weight 700kbit prio 8 allot 1514 cell 8 maxburst 20 avpkt 1000

#2Mbit class: Server 1 (1:2)
tc class add dev ${INSIDE_DEVICE} parent 1:1 classid 1:2 cbq bandwidth 100Mbit rate 2Mbit weight 200kbit prio 5 allot 1514 cell 8 maxburst 20 avpkt 1000 bounded isolated
tc class add dev ${OUTSIDE_DEVICE} parent 1:1 classid 1:2 cbq bandwidth 100Mbit rate 2Mbit weight 200kbit prio 5 allot 1514 cell 8 maxburst 20 avpkt 1000 bounded isolated

tc qdisc add dev ${INSIDE_DEVICE} parent 1:2 tbf rate 2Mbit buffer 10Kb/8 limit 15Kb mtu 1500
tc qdisc add dev ${OUTSIDE_DEVICE} parent 1:2 tbf rate 2Mbit buffer 10Kb/8 limit 15Kb mtu 1500

tc filter add dev ${INSIDE_DEVICE} parent 1:0 protocol ip prio 100 u32 match ip dst 192.168.0.101 flowid 1:2
tc filter add dev ${OUTSIDE_DEVICE} parent 1:0 protocol ip prio 100 u32 match ip src 192.168.0.101 flowid 1:2

#5Mbit class: Server 2 (1:3)
tc class add dev ${INSIDE_DEVICE} parent 1:1 classid 1:3 cbq bandwidth 100Mbit rate 5Mbit weight 500kbit prio 5 allot 1514 cell 8 maxburst 20 avpkt 1000 bounded isolated
tc class add dev ${OUTSIDE_DEVICE} parent 1:1 classid 1:3 cbq bandwidth 100Mbit rate 5Mbit weight 500kbit prio 5 allot 1514 cell 8 maxburst 20 avpkt 1000 bounded isolated

tc qdisc add dev ${INSIDE_DEVICE} parent 1:3 tbf rate 5Mbit buffer 10Kb/8 limit 15Kb mtu 1500 tc qdisc add dev ${OUTSIDE_DEVICE} parent 1:3 tbf rate 5Mbit buffer 10Kb/8 limit 15Kb mtu 1500

tc filter add dev ${INSIDE_DEVICE} parent 1:0 protocol ip prio 100 u32 match ip dst 192.168.0.102 flowid 1:3
tc filter add dev ${OUTSIDE_DEVICE} parent 1:0 protocol ip prio 100 u32 match ip src 192.168.0.102 flowid 1:3

# List the trafficshaping rules
echo ---[${INSIDE_DEVICE}: configured classes ]---------------------------
>> $DEBUG_LOG
echo >> $DEBUG_LOG
tc class show dev ${INSIDE_DEVICE} >> $DEBUG_LOG
echo >> $DEBUG_LOG
echo ---[${INSIDE_DEVICE}: queueing disciplines ]-------------------------
>> $DEBUG_LOG
echo >> $DEBUG_LOG
tc qdisc show dev ${INSIDE_DEVICE} >> $DEBUG_LOG
echo >> $DEBUG_LOG


Done! :o)

Alright so how does all this mumbojumbo work ?

I wont explain the technology I will instead try to explain what each
value do in these lines (so you know what to change if needed).

I think part 1) and 2) is pretty obvious for you, first create the
diskette then place the needed files.

Now, step 3) comes the interresting parts. In here I have placed all
kernelmodules that are available for trafficshaping. There are more than
one way to do trafficshaping where I have choosen to limit the shaping per
ip-address. If you use other methods then mine you will have to
enable/disable the modules you need (disable in order to - why should a
module that isnt used be loaded in memory ? I like fast, slipstreamed
systems :-)

And now for the finally - where all the magic occurs, part 4).

I will split it up for all the comments that are in there.

#root
Here we are assigning the root where all the data will be passed through
(see this as the networkinterface). My method is class based. That means
that first we assign a group of classes and their relations to each other
and second we setup rules on which class to use when a specific network
package arrives to our system. The reason why I setup root on both
interfaces is that the shaping can only occur on the opposite interface.
In other terms, if you want to shape outgoing traffic you need to apply
the shaping rules on the outside interface - and vice versa.

Things that you might want to change: "bandwidth 100Mbit", this is the
speed the interface uses. If you use a 10Mbit nic/speed then write
"bandwidth 10Mbit" instead (this is so the shaping can do proper
calculations).

#root class
This is the first class that we setup and attach it to the device (#root).
Here I have setup a total limit of the shaping (I will shape a server that
will use max 2Mbit and one that will have 5Mbit, thats 7Mbit in total :-)
This is used to tell the shaping rules how much bandwidth we have to play
with because (due to configuration of each class lower down in the line)
we can configure if they should borrow bandwidth from its parent or not
aswell as if they should be able to loan its bandwidth to other children.

Things that you might want to change: "bandwidth 100Mbit" - same as in
#root, this is the speed of the network interface, "rate 7Mbit" this is
the total limit we will setup here, "weight 700kbit" this is always a
devider by 10 of the "rate" value. If you set rate to 5Mbit then weight
should be set to 500kbit.

#2Mbit class: Server 1 (1:2)
I will split this up in three blocks.
In the first block I create the 2Mbit class that will be limited to 2
Mbit. By using "bounded isolated" I have restricted it to not borrow
bandwidth from its parent aswell as not let other classes borrow bandwidth
from itself. For instance - this class have a limit of 2Mbit, nothing more
nothing less. Even if there are unused bandwidth it will not borrow that.
If you want it to borrow available bandidth (but max 2Mbit in total) from
its parent you need to change either "bounded" or "isolated" in both this
class aswell as in the parent class (see a more specific description in
"cbq.init" that can be found around the net).

The second block will set the technical description (qdisc) of this class
such as mtu size and buffer sizes. The only thing you might want to change
here is the mtu size if you are using a dialup connection. But since we
are using ethernet (with ddefautl package size of 1500) we will have the
value of 1500 here instead (dialup mtu is for instance often around 576 in
size).

The third and last block is the block that will tell the shaper what
packages to shape. Here I have setup a rule that says to shape things that
are going to 192.168.0.101 aswell as from the same ip.

Things you might want to change:
Block 1: "parent" if you want to assign another class as parent for this
one. "classid" if you want to change the classid for this class.
"bandwidth", "rate" and "weight" see #root class. "bounded" and "isolated"
(if its not "bounded" or "isolated" both values will be removed from this
line) see the description for "cbq.init" that can be found on various
places on the internet (use www.google.com or something in order to locate
it :-)
Block 2: If you change classid in block 1 you need to change "parent" in
this block aswell - otherwise it will point to wrong parent. "rate" see
description in #root class.
Block 3: "dst" and "src" regarding what client to shape. "flowid" tells
what class the package should flow through when arriving to the shaper.

#5Mbit class: Server 2 (1:3)
This is same as the 2Mbit class but we have changed classid,rate and
weight on the first block, parent and rate on the second block and flowid
and dst/src on the third block.

Things you might want to change: see above :-)

# List the trafficshaping rules
Will list the rules applied in the tty that you have defined as $DEBUG_LOG
in file a:\config. (If you choose tty4 the rules will be visible when you
press alt+f4 on the keyboard, tty3 is alt+f3 and so forth (but I think you
already know this :-)


Well - thats it, shaping in action :-)

If you have further questions or wonder something regarding this you can
either email me or better post the question in the same thread as this...

Links

Initrd Howto

 
those docs i did find in google searches were out of date....
and incomplete in terms of getting a flash disk that you can boot
into  /dev/ram0

-- lets assume that tomsrtbt is too small on the 1.77Mb floppy
   and cdrom is too much hassle to make to boot into /dev/ram ???

we can take it offline to get you a working initrd
( am assumign you have another pc that we can debug it on

c ya
alvin (Alvin Oga)


more expanded micro-initrd Flash howto ( from vague recollection of memory)
=======================================
	am assuming you wanna boot from floppy or better if
	booting from 4Mb flash to be on /dev/hda on the target

A1.  Get a spare PC...
A2.  boot it normally...
A3.  install the kernel you wanna be using and compile it
     and boot until you got the bootable kernel 
A4.  make a boot floppy
A5.  boot the floppy.... if it works...good...now we can start


B0.  Move things around so that you are using ONLY /dev/hdb for
     your own development system
	- use /dev/hda as your flash device on your cev box
	and/or it will be the only disk on your target firewall

B1.  change/update your kernel to support initrd
	- turn on mimixfs
	- turn on /dev/ram
	- turn on /dev/loop  ( better than /dev/ram ?? )
	- you will be tweeking /dev/ram to support 8MB or 16Mb
	  since /lib/libc-2.* is how big ???
	- /lib /boot /root /bin /sbin /etc must all fit in /dev/ram0
	- keep playing with your kernel till you can 

B2.  make ANOTHER boot floppy....
	- something you can play with

B3.  make some ram devices

	dd if=/dev/zero of=/dev/ram0 bs=1k count=8192
	dd if=/dev/zero of=/dev/ram1 bs=1k count=8192
	
	#
	# you're gonna be tweek -i to cram more bytes into the ram device
	#
	mke2fs -m 0 -i 2000 /dev/ram0
	mke2fs -m 0 -i 2000 /dev/ram1
	
        mount /dev/ram0 /mnt/ram0
        mount /dev/ram1 /mnt/ram1

B4.  Start putting what is "required" to boot your server
     into the initrd file
	#
	# make a script that does this
	# ============================
	#
	#
	# i forgot where mkinitrd puts its stuff
	#	- check your fs -- makes it easy
	#
	#	- using mkinitrd helps solve some directory
	#	and copy problem but I forgot where it put stuff
	#
	# mkinitrd
	#

	-- lets do things the hard way

	#
	# the boot FLOPPY  that DOES work...
	#
	mount /dev/fd0 /mnt/floppy
		=
		= you should be able to see the guts of your boot floppy
		=

	#	
	# make some directories for /var/log /tmp 
	mkdir /mnt/ram0/tmp /mnt/ram0/usr/tmp
	chmod 1777 /mnt/ram0/tmp /mnt/ram0/usr/tmp
	...
	mkdir /var/log
	mkdir /var/run
	mkdir /var/spool
	....
	
	#
	# Copy the contents from the working bootable floppy
	# to your new boot media that we gonna create
	#
	# remember the boot floppy assume /dev/hda1 or /dev/sda1
	# for root... we are gonna use /dev/ram0
	#
	cp -par /mnt/floppy/bin /mnt/ram0/bin
	cp -par /mnt/floppy/etc /mnt/ram0/etc
	cp -par /mnt/floppy/dev /mnt/ram0/dev
	cp -par /mnt/floppy/lib /mnt/ram0/lib
	cp -par /mnt/floppy/boot /mnt/ram0/boot
	cp -par /mnt/floppy/sbin /mnt/ram0/sbin
		- fix /mnt/ram0/etc/fstab to point to /dev/hdaxx
	....

	be sure to add/copy your basic/favorite commands into /mnt/ram0:
		bash, ls, ping, route, ifconfig, ps, top, dd,
		mount, cp, mv, etc..etc..
	#
	# copy other non-critical, would be nice ot have commands
	# into/mnt/ram1
	#

	#
	# now lets create your initrd file
	#
	dd if=/dev/ram0 of=/tmp/initrd.test bs=1k
	gzip /tmp/initrd.test.gz
	#
        dd if=/dev/ram1 of=/tmp/initrd.extra bs=1k
        gzip /tmp/initrd.extra.gz
	#
	cp -p /tmp/initrd.test.gz /boot
	cp -p /tmp/initrd.extra.gz /boot
	#
	# the kernel you want should already be in /boot
	#

B5.  Create a temporary lilo.Test.conf file
	#
	# Create a boot media that boots into /dev/ram0
	#
	#
	# on the development machine, the flash is /dev/hda
	#
	boot=/dev/hda
	#
	map=/boot/map
	install=/boot/boot.b
	prompt
	timeout=50
	message=/boot/message
	linear
	#	
	# Create a bootable flash disk
	#
	image=/boot/vmlinuz-2.4.2
        label=linux-2.4.2-FLASH
        read-only
	#
	# the flash disk will be hda on the target firewall
        root=/dev/hda1
	#
	initrd=/boot/initrd.test.gz
	#
	# end of file

	# Run lilo.conf
	#
	lilo -C /etc/lilo.Test.conf
	

	==
	== the target flash disk should only need /boot/...stuff...
	==
		/boot/vmlinuz-2.4.2
		/boot/initrd.test.gz
		/boot/map
		/boot/message

	==
	== take the flash to virgin PC... and boot it there
	---------------------------------------------------

	-- boot the flash ( on hda )  ... if it worked...
	you'd have /dev/ram0 as your root partition

	-- if it didnt boot....you're missing some required binaries

		- go back to the development box and see whats missing
		and add the missing binaries/libraries

have fun
alvin


On Tue, 8 May 2001, will trillich wrote:

> On Tue, May 08, 2001 at 08:32:01PM -0700, Alvin Oga wrote:
> > mkinitrd  ...
> > 
> > or take an existing initrd.gz file...decompress it
> > into /dev/ram  or /dev/loop
> > 	
> > than change the kernel to your version, add your libs/commands
> > and other stuff you want in the initrd to make your system
> > bootable
> > 
> > and compress that /dev/loop image into  your_initrd.gz   and add that
> > as your initrd image in lilo
> > 
> > or so goes the simplified 3-line howto...
> 
> um, point the way or name the doc, if you would.
> 
> > either way...you need to make sure you have minixfs and /dev/ram enabled
> > in your kernel to be able to create initrd files
> 
> eh?
> 
> > i created a full system in about 2.5Mb that expands into 8-16Mb of 
> > linux hierachy that runs in memory ( /dev/ramxx )
> > 	( put that on a 4Mb flash and you've got a nice firewall ?? )
> 
> ding ding ding! you've got my attention... that's almost
> precisely what i'd like to accomplish. can you do that with
> debian?
> 
> > you can try tomsrtbt too but, its bash is too small as is its libraries
> 
> do you have a more fleshed-out documentation trail of making a
> uncompress-onto-ramdisk-during-boot system?
> 
> -- 
> DEBIAN NEWBIE TIP #3 from Will Trillich  
> :
> Wondering how to find WHICH PACKAGE CONTAINS x-y-or-z? Just enter
> "dpkg -S part/of/path" and you'll get a list of all packages that
> affect paths like that. For an example, try "dpkg -S http".
> 
> Also see http://newbieDoc.sourceForge.net/ ...
> 
> 
> -- 

Creating an initrd image on Debian GNU/Linux

By JasonB



When I started booting a box with multiple SCSI adapters, I wanted to keep the device ordering sane. I find it\x{2019}s best when the boot ordering matches the order in which Linux initializes the drivers for each controller. One effective way to handle this under Debian GNU/Linux with one of the stock kernels is to create a custom initrd image.

To create your own initrd under Debian, you will want to install the initrd-tools package. You can then customize to your heart\x{2019}s content using the /etc/mkinitrd configuration directory.

The most important file, /etc/mkinitrd/modules, is the list of modules you want included in the image and loaded, in the order specified, at boot time. The listed modules should be the ones necessary to initialize the actual root device. You must list the modules in dependency order. The kernel will not have the benefit of modprobe at boot time.

Within the mkinitrd.conf file you can change the MODULES option to dep to pack a minimal set of kernel modules in your initrd image. DELAY is also useful when things don\x{2019}t work out. Before the initrd image tries to pivot to the new root filesystem, a brief delay will allow you to see just which modules loaded and in what order, to help debug any problems you many encounter.

# /etc/mkinitrd/modules: Kernel modules to load for initrd.
#
# This file should contain the names of kernel modules and their arguments
# (if any) that are needed to mount the root file system, one per line.
# Comments begin with a `#', and everything on the line after them are ignored.
#
# You must run mkinitrd(8) to effect this change.
#
# Examples:
#
#  ext2
#  wd io=0x300
scsi_mod
sd_mod
aic7xxx
3w-xxxx
jbd
ext3

To build your initrd, you will want to use mkinitrd, specifying the file to write the image to and what your root device is. You can allow mkinitrd to probe for your root device, but that is not always wise. For example, if you just installed a SCSI controller and your new boot device is attached to that controller, but your current root device is an IDE disk, the probe will not include the SCSI drivers you will need at next boot. The DELAY option mentioned above will help track down some of these issues. Finally, the -k option instructs mkinitrd to retain its working directory. You can then check to see if it built the image according to your wishes.

mkinitrd -k -o /boot/initrd.img -r /dev/sda1

The newly created initrd image is actually a cramfs filesystem, which you can mount on the loopback device, provided you are running a Debian stock kernel. Cramfs is not yet officially a part of the v2.4 kernel series, but it is in v2.6.3 and above. If you are compiling your own kernel, you must compile in support for using an initrd, whether your kernel supports cramfs or not.

Mark Alexander, in an email, offered some additional information if you\x{2019}re using a kernel that does not support cramfs, which includes kernels downloaded directly from kernel.org through 2.6.2. Cramfs was officially merged into 2.6 starting with v2.6.3. To create a regular ext2 filesystem and use it as an initrd image, Mark suggests the following procedure. Edit /etc/mkinitrd/mkinitrd.conf and use the following binary for creating the imagine:

MKIMAGE='/usr/local/sbin/mkext2fs %s %s > /dev/null'

Next, create /usr/local/sbin/mkext2fs. (This was originally posted by Fabian Franz to the debian-knoppix mailing list. He explained to me that you may have issues with images greater than 2MB, so you should specify ramdisk_size=100000 or a value larger than your initrd image when you boot your kernel with your bootloader of choice. Thanks!)

#!/bin/bash
# similar to mkcramfs (for use with debian mkinitrd)
# mkext2fs dirname outfile
#
# no options are parsed
#
#       Written by: Fabian Franz 
# GPL v.2 - See: `locate gpl.txt`
if [ $# -lt 2 ]
then
  echo "Usage: $(basename $0) dirname outfile"
  exit 1
fi
TMPDIR=/tmp/$(basename $0).$$
mkdir $TMPDIR
function clean_exit
{
  umount $TMPDIR 2>/dev/null
  rm -rf $TMPDIR
}
trap clean_exit EXIT
COUNT=$[$(du -s $1 | awk '{ print $1 }' )*2+1000]
dd if=/dev/zero of=$TMPDIR/image count=$COUNT
mke2fs -F $TMPDIR/image
mount -o loop $TMPDIR/image $TMPDIR
cp -a $1/* $TMPDIR
umount $TMPDIR
cat $TMPDIR/image | gzip - > $2

If you built a cramfs image, you can mount it on the loopback device and investigate to verify its loading the modules you instructed it to. (You can do the same with the ext2 image, but remember its compressed with gzip.)

sarah:/etc/mkinitrd# mount -t cramfs
  -o loop /boot/initrd.img-2.4.22-xfs-386 /mnt
sarah:/etc/mkinitrd# ls /mnt
bin  dev2   etc  linuxrc       loadmodules  proc  script   sys  usr
dev  devfs  lib  linuxrc.conf  mnt          sbin  scripts  tmp  var
sarah:/etc/mkinitrd# cat /mnt/loadmodules
modprobe -k  scsi_mod
modprobe -k  sd_mod
modprobe -k  aic7xxx
modprobe -k  3w-xxxx
modprobe -k  jbd
modprobe -k  ext3
modprobe -k  vesafb > /dev/null 2>&1
modprobe -k  fbcon 2> /dev/null
modprobe -k  unix 2> /dev/null

As indicated above, after the SCSI subsystem loads, the driver for the SCSI controller with the boot device is loaded, followed by the 3Ware controller\x{2019}s driver, which acts like a SCSI device driver. Now you can easily change the ordering, if need be.

A quick look inside the image should confirm, before you waste a reboot, that the modules you instructed mkinitrd to load are being loaded and in the correct order. The careful reader will also verify the modules actually exist in the imagine itself as well. (And don\x{2019}t forget to include any modules necessary to actually mount and read from your root filesystem; I loaded the ext3 module for ext3 below.)

sarah:/# find /mnt -name '*.o' -print |
  perl -ne 's/.*kernel/(.*)/$1/;print'
drivers/scsi/3w-xxxx.o
drivers/scsi/aic7xxx/aic7xxx.o
drivers/scsi/scsi_mod.o
drivers/scsi/sd_mod.o
drivers/video/fbcon-cfb16.o
drivers/video/fbcon-cfb24.o
drivers/video/fbcon-cfb32.o
drivers/video/fbcon-cfb8.o
drivers/video/vesafb.o
fs/ext3/ext3.o
fs/jbd/jbd.o
net/unix/unix.o

Now, that wasn\x{2019}t so painful, was it?

Linux filesystem

We need to make a filesystem that the Network Boot Program can download from the server, and pass to the kernel. The maximum size of such filesystem is limited to the amount of memory in the machine, but generally it shouldn't be bigger than 4MB.

Since we want to boot the MP3-box from the network, and have no media storage device on the MP3-box, the filesystem cannot be on a harddrive, floppy drive, nor ZIP drive. Linux provides a facility for that called Initial RAM Disk (initrd) - its a file, which actually is a ext2 filesystem embedded in a file.

Creating initrd filesystem.

To understand why we need to create a INITial Ram Disk filesystem, its necessary to understand how Linux boots up.

  • After the kernel is finished loading itself, it starts executing itself.
  • The kernel converts initrd (which the boot loader loads into memory as linux.2) into a "normal" RAM disk.
  • When its done, it mounts the device specified in root_dev (which is changed by the Network Boot Program). This usually points to /dev/ram0 or /dev/ram1.
  • /linuxrc is executed.
  • When linuxrc terminates, the "real" root file system is mounted (which can be the RAM disk)
  • /sbin/init is invoked.

For more info, man initrd.

Creating initrd fs.

The initrd - is a initial ram disk embedded inside a file. Creation of such a file is quite straightforward (you have to be root to use losetup).

dd if=/dev/zero of=/root/initrd count=4096 bs=1024
losetup /dev/loop0 /root/initrd
mke2fs /dev/loop0
losetup -d /dev/loop0
file /root/initrd
This creates a initrd file 4MB big. The last command should say: Linux/i386 ext2 filesystem. This is the file that we eventually use to boot the Linux OS on the MP3-box.

Mounting initrd fs.

To use the initrd for something its necessary to make a mount-point a mount the initrd file:

mkdir /data
mount /root/initrd /data -o loop
Now you freely copy files back and forth onto the 4MB initrd file, which is mounted under /data.

Copying LRP filesystem to initrd fs.

Its time to put something meaningful on the 4MB initrd. We need to copy a small linux distribution onto the initrd, otherwise we can't use it boot the MP3-box.

cd "2nd Step - configuring client/02 - the filesystem"
tar -cf - * | (cd /data; tar -xvf - )

Copying custom modules,

Do you remember the modules that we compiled in the previous section?

cp -Rf /tmp/lib/modules/2.2.16/* ./data/lib/modules/2.2.16
sync
df -h
df -h serves only to show you how much space you have left on the filesystem.

Preparing the initrd fs for NBP.

Using the initrd file generally means we have to unmount the file, gzip it and copy it into the tftpboot directory.

umount /data
sync
gzip -c9 /root/initrd  > /tftpboot/X86PC/UNDI/linux-install/linux.2
This will unmount the initrd, and compress it into linux.2 file (which is what the NBP will look for and download).

Conclusion

That's basicly the method of designing and using an initrd filesystem. One thing to keep in mind - the initrd should always be compressed when deployed.

5.3 Configuring NBP (Network Boot Program).

After you have copied your initrd file and tried to boot up the workstation, you found out that the kernel complains about not being able to mount the root partition. The problem lies in the NBP that is supplied with PXE - it was compiled for RedHat type initrd images, and therefore does some changes to the kernel.

  • When the NBP is finished downloading the kernel, it sets the root_dev environment to whatever was compiled inside the NBP. By default, that is 0101, which is /dev/ram1 (look at its major, minor).
  • NBP passes the environment to kernel (in and in turn overwriting whatever settings the user supplied to the kernel using rdev) and starts it.
  • The kernel happily executes and tries to mount a filesystem from /dev/ram1>, while the initrd image sits in /dev/ram0.
  • The kernel hangs.
The solution is to recompile the NBP with the right root_flags. Look in

1st Step - configuring server/02 - pxe/pxe/pxe-linux/nbp.linux/prepare.c. Line 212 lists the hexadecimal address. Change it to 0x0100 - that way the kernel will mount /dev/ram0 and actually find a initrd filesystem.

5.4 Configuring startup scripts.

When the kernel completes loading the initrd into memory and mounts it as a filesystem, then /sbin/init is executed, which handles the rest of starting the operating system.

  • init reads in /etc/inittab - which lists which scripts must be executed depending on the computer's state.
  • It starts executing the boot-time configuration script /etc/rc.d/rc.boot.
  • rc.boot setups BusyBox and POSIX links, configures all the modules - sound, network, and filesystem. If you are using your own modules, you must edit this file and change the settings.
  • Then init changes the runlevel to its default - 2, which result in running /etc/rc.d/rc.multi.
  • rc.multi setups the network card (configures its IP), mounts the NFS server and starts the audio-subsystem (/etc/rc.d/rc.audio). It gets all the custom configuration (where is the NFS server. its IP, etc) from /etc/rc.conf.
  • rc.audio configures the sound, creates playlists, and starts the ARCamp program (which listens to the remote and runs/kills mpg123).

The scripts were made as simple as possible. The files you ought to look into and alter are:

  • /etc/rc.conf - has the NFS IP, the mountpoint, and the client's IP
  • /etc/rc.d/rc.boot - loads the network module, and the filesystem module.
  • /etc/rc.d/rc.audio - loads the sound card module.


For further info email me at: ncherry@linuxha.com.