Automation
(Last updated: Fri. Sep 24, 2004)
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
- Floppy Firewall AX
- FFW w/Dual links
- Initrd Howto
- Blue Box Howto
- Root File system
- UPX - the Ultimate Packer for eXecutables
- Linnix Compact Flash Drive - I'd say these are probably the least expensive compact flash adapters I've found so far.
- Building a uClibc/Busybox Ramdisk for the BE300 - I really don't care about the BE-300 rather I am interested the procedure to build uClibc & BusyBox. Then getting the whole thing bootable.
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 - Get yourself a ROM image to burn to a ROM/Flash chip or a Floppy image to boot from floppy. To begin with I recommend using the Floppy image. It's easy to correct errors with the floppy. Once you have the options the way you want them then use those options with the ROM image.
- Floppy Firewall 2.9.8 dev kit
- Linux kernel 2.4.x
- Busy Box - I built it with cron, telnetd, login & vi (maybe a few more things).
- Initrd
- IPTables
- SNMP
- Drop Bear (SSH)
- Wireless Access Point
- IPTSTATE
- ncurses
- Python
- tcpdump
- ethereal
- DHCP Client
- ez-ipupdate - for dynamic DNS updates
- sensors
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=nFloppy 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:
- Create temp directory and cd to it
- Copy files off MSDOS Floppy (how can we do this with a filesys instead of the floppy)
- gunzip initrd.gz
- 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); }- create temp mnt point, then mount -o loopback initrd <tmp_mnt_pt>
- d2u linuxrc (D2U is a DOS line ending to Unix line ending conversion routine)
- d2u floppy.ini
- d2u etc/config
- bunzip & untar floppyfw/add.bz2 modules/*.bz2 & packages/*bz2
- d2u packages/pre-*.ini & packages/post-*.ini to etc/$file # Put everything in /etc
- d2u hosts -> etc/hosts
- d2u modules.lst -> etc/modules.lst
- d2u network.ini -> etc/network.init
- d2u firewall.ini -> etc/firewall.init
- d2u syslog.conf -> etc/syslog.conf
- d2u packages/timeinfo -> etc/localtime (this doesn't seem to work for me)
- cp licenses to /licenses
- cp modules/* to /lib/modules
- if localtime copy localtime to /etc/localtime (??? are we doing this twice?)
- umount the loopback
- gzip initrd
- mknbi-linux $append --output=$output vmlinuz initrd.gz ; rm -rf $tempdir Here we're making the network bootable image (2.9.x uses mkelf)
- ... aren't there more steps? Like copy the image to tftpboot???
- 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 FreschiMicrosoft, 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
- Floppy Firewall AX
- FFW w/Dual links
- Initrd Howto
- Blue Box Howto
- Root File system
- UPX - the Ultimate Packer for eXecutables
- Linnix Compact Flash Drive - I'd say these are probably the least expensive compact flash adapters I've found so far.
- Building a uClibc/Busybox Ramdisk for the BE300 -
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.
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.