Use this information at your own risk. If anything breaks as a result of reading this document I, James Wayne Weller, will not be held responsible. I accept no liability for equipment or data lost or otherwise damaged as a result of these procedures. This implementation worked in my case and might work or help in yours. But if there is any damage done you get to keep both pieces
Hi all,
this is my firewall-on-one-floppy howto. The need
for this document arose when I wanted to connect my home LAN to the
internet over my cable modem. My ultimate
(and current) goal was to use linux as an embedded system for a 486
with two ethernet cards and a boot rom to start from the local
network. Alas, I don't have boot roms (yet). So, floppy disk is the
next best.
The firewall kit is composed of two disks. I know ... I said it fit on one floppy, and it does. The first disk is broken into two parts. The first part is the kernel itself, while the second part is the ramdisk to mount as the root (/) filesystem. The *only* binaries on the ramdisk image are ones *needed* to bootstrap the system, get a console going, and mount further disks. That means that you can boot your system with the first disk, pull the disk, and walk away. It will be firewalling. This boot procedure requires most of the following binaries and scripts.
/bin/sh symbolic link to kiss /bin/kiss a very simple shell to type commands at /bin/ash a smarter shell for scripting /bin/ifconfig ties ethernet cards to IPs... /bin/route set network routes /bin/login enables log on at the terminal
/sbin/init daddy process /sbin/agetty prompt for credentials at the terminal /sbin/ipchains ip packet filter configuration tool /sbin/dhcpcd dhcp client daemon (to pull down IP from server) /sbin/insmod needed to insert ethernet module /sbin/rmmod needed to remove ethernet module /sbin/fw.sh an ash shell script to setup firewalling rules /sbin/mount needed to mount floppies /sbin/umount needed to unmount floppies
You're probably wondering how your going to get anything done on this box. I mean this is a pretty sparse collection of binaries isn't it? The answer is the second floppy disk. If you want this computer to do more than just sit in the closet and filter packets, you'll need to login as root, insert the second floppy disk, and type...
[/root]# mount -t minix /dev/fd0 /usr/bin
Now, /usr/bin is already in your path. So, now you have access to all the binaries on that minix filesystem. My default /usr/bin/ disk has...
/usr/bin/ping send icmp packets /usr/bin/netstat find out what your host is listening for (netstat -an) /usr/bin/traceroute found out the network route your packets take to a host /usr/bin/telnet login to a remote host /usr/bin/ftp file transfer from remote host /usr/bin/pico the end all simple editor /usr/bin/grep look for regular expressions /usr/bin/ssh ssh 1.3 client /usr/bin/gunzip gzip uncompress /usr/bin/gzip gzip compression /usr/bin/tar tape archiver /usr/bin/cat output files /usr/bin/sed stream editor /usr/bin/tail look at the end of a file /usr/bin/yes output a string until terminated (good for I/O testing) /usr/bin/df shows available diskspace /usr/bin/free shows memory usage /usr/bin/head output the top of a file /usr/bin/passwd change your password (temporarily b/c ramdisk)
Notice, because it's physically seperated from your runtime firewall, bad-guy cracker types don't have access to those (unless you mount the disk after you've been rooted). If you want ultra-security bring down your outside internet interface if your are going to mount the tools disk.
styx:[/]# umount /usr/bin
Put a disk in the floppy and type
c:\lfw> rawrite.exe lfw.img a:
Put another floppy in the drive
c:\lfw> rawrite.exe fwtools.img a:
Put a disk in the floppy and type
cat lfw.img > /dev/fd0
Put another floppy in the drive
cat fwtools.img > /dev/fd0
Get a 386 or better motherboard with >= 6mb RAM and hook up two 3com 3c509 ethernet cards ($10~$15) and a 3.5in 1.44mb floppy drive. Yes, that's it :) Make a DOS boot disk and run the 3x509cfg.exe file available from http://www.3com.com. My cards are set to the following values. eth0 irq=10 ioport=0x300 eth1 irq=5 ioport=0x220 Plug your internet connection into eth1 and your local network hub into eth0. Make sure you set all you other machines on your network to use any address from 192.168.0.[2-255]. The other machines should have a gateway address of 192.168.0.1 (styx). The gateway is eth0 on the firewall machine (styx). Slap in the boot disk and turn on that frankenstein monster. You should see a simple kernel description as it straps the hardware. Then you will get a login prompt. The box is now firewalling. You should be able to reach the internet from your computers behind the firewall. You can login as root; the password is Firecracker2000. NOTE: This only works if there is a DHCP server on your internet connection. |
specifically see... The bootdisk howto The ipchains howto The ethernet howto The kernel howto The net 3/4 howto The linux network administrators guide (NAG)
Find out the size of your kernel
[/root]# du -h kernel.img 336K kernel.img
Write that down, because this is the hard part. The kernel has 16 bits at the beginning of it that set important boot values.
bits 0-10: set the offset to the ramdisk in 1024k blocks. unsigned int. bits 11-13: unused bits bit 14: flag indicating whether to load ramdisk. (1) for us bit 15: flag indicating whether to prompt for root fs. (0) for us
Now we need to set up that 16 bits. My kernel image was 336k convert that to a binary value and you get
366d == 101010000b | | 8 0
Notice thats only 9 bits and we get 0-10, 11 bits, to use. So pad it with zeros.
00101010000b | | 10 0
Now we know that the next three bits are unused so we set them to 0
00000101010000b | | 13 0
The next bit is the ramdisk flag. We want to load a ramdisk so we set it to 1.
100000101010000b | | 14 0
Finally, the prompt bit. We know exactly where our ramdisk is and it's not on a second media so their is no need to prompt the operator for it. So, we set this flag to 0.
0100000101010000b | | 15 0
Now, that we have accounted for that sixteen bit number we can convert it back to decimal and setup our kernel image to use the floppy.
0100000101010000b == 16720d
Now issue these commands using the numbers you got from the above arithmetic.
[/root]# rdev kernel.img /dev/fd0 [/root]# rdev -r kernel.img 16720 [/root]# rdev -R kernel.img 0
Note: You'll need ramdisk and minix support in your current kernel.
Fill the ramdisk with zeros.
[/root]# dd bs=1k if=/dev/zero of=/dev/ram0 dd: /dev/ram0: No space left on device 4097+0 records in 4096+0 records out
Note: I always think of dd standing for disk duplicate. It is the worlds most articulate copy command.
bs= means the size of our blocks. count= means the number of blocks to copy if= is the input file of= is the output file skip= skip this many blocks in the input file seek= skip ahead this many blocks in the output file
Make a 2048k minix filesytem on the ramdisk.
[/root]# mkfs.minix /dev/ram0 2048 682 inodes 2048 blocks Firstdatazone=26 (26) Zonesize=1024 Maxsize=268966912
Mount it in a convenient directory
[/root]# mkdir rd [/root]# mount -t minix /dev/ram0 rd
Then put my, loaf's or any other file system in the ramdisk
[/root]# cd rd [/root]# tar -xzf ../filesystem.tar.gz
Now hack, hack, hack in the rd directory until you get a filesystem you want to boot with. Be careful. A booting system is a fragile thing. Move in small undoable steps. Once you have a good filesystem save it.
[/root]# cd rd [/root]# tar -cf ../ramdisk.tar * [/root]# cd ..
Unmount the ramdisk
[/root]# umount rd
fill the ramdisk with zeros to optimize compression
[/root]# dd if=/dev/zero bs=1k of=/dev/ram0 dd: /dev/ram0: No space left on device 4097+0 records in 4096+0 records out
Make yet another minix filesystem
[/root]# mkfs.minix /dev/ram0 2048 682 inodes 2048 blocks Firstdatazone=26 (26) Zonesize=1024 Maxsize=268966912
I like to force a check of it to avoid warnings when mounting
[/root]# fsck.minix -fa /dev/ram0 fsck.minix, 1.2 - 11/11/96 / util-linux 2.6 Forcing filesystem check on /dev/ram0.
Mount the ramdisk again
[/root]# mount -t minix /dev/ram0 rd
Now put your usable filesystem back in. The reason we do this twice is to make the compression work better. Your tinkering in the rd directory caused fragmentation.
[/root]# cd rd [/root]# tar -xspf ../ramdisk.tar * [/root]# cd ..
Good! now we need a copy of the filesystem on the disk called ramdisk
[/root]# dd bs=1k count=2048 if=/dev/ram0 of=ramdisk 2048+0 records in 2048+0 records out
next compress the ramdisk using gzip
[/root]# gzip -9 ramdisk
[/root]# dd bs=1k if=kernel.img of=/dev/fd0 336+0 records in 336+0 records out [/root]# dd bs=1k seek=336 if=ramdisk.gz of=/dev/fd0 614+1 records in 614+1 records out
Note the seek value in the second command is 336. Then, remember that my kernel was 336k. So we put the ramdisk *right* after the kernel.
The shell program kiss cannot parse the ! marks
that ipchains uses. So
I used ash to start up the firewall instead.
If you look at the boot script /etc/rc you'll see it's all very straight forward.
BEGIN /etc/rc ------------------------------------------------------------------------------- #load ethernet (use your own module) /sbin/insmod /3c509.o # Mount the /proc filesystem mount -t proc proc /proc # Set the hostname echo "styx" > /proc/sys/kernel/hostname # Configure the loopback device /bin/ifconfig lo 127.0.0.1 netmask 255.0.0.0 /bin/route add 127.0.0.1 lo #bring up the local network interface echo "Local interface" /bin/ifconfig eth0 192.168.0.1 #bring up the world interface echo "Internet interface" /sbin/dhcpcd eth1 #turn on ip forwarding echo "Turning in IPV4 forwarding" echo 1 > /proc/sys/net/ipv4/ip_forward #load firewalling rules echo "Loading firewall rules" /sbin/fw.sh ------------------------------------------------------------------------------- END /etc/rc
The default password is Firecracker2000,
but you can change it by mounting
the tools floppy disk. Realize that this is only for the duration
of your boot. When you reboot the original ramdisk will be reloaded
and the password will again be Firecracker2000. If you want the password
to be permanent you'll have to rebuild the ramdisk with a different
/etc/passwd file.
styx:[/]# mount -t minix /dev/fd0 /usr/bin styx:[/]# passwd ---CLIPPED--- styx:[/]# ftp my.working.box ---FTP the /etc/passwd file to your rd directory-- styx:[/]# umount /usr/binNow build a new boot disk as described above. You'll find your designated password works.
How do I know this thing is firewalling?
Login and run...
styx:[/]# ipchains -L
How to I modify my firewall rules?
Read the ipchains HOWTO then modify the /sbin/fw.sh or type the new rules at the command line. They won't be permanent until you rebuild the ramdisk.
What are the default rules?
ipchains -A input -j DENY -s ! 192.168.0.0/16 -d 192.168.0.0 ipchains -A forward -j MASQ -b -s 192.168.0.0/16 -d 0/0
Deny all traffic not from the local net bound for the local net. This should never happen, because the 192.168. addresses are unroutable on the internet at large. But it could happen if someone was able to get into your outside interface. But then the only thing they could do would be to ssh to another of your boxes. Which hopefully would have good passwords. Here's the hard part. SSH is on your tools floppy which isn't mounted. HA HA HA. So cracker elite just got caught in a dead end. Anybody have some ideas on this?
Masquerade all traffic between the internet (0.0.0.0/0) and the local network (192.168.0.0/16).
You must use passive FTP unless you modify your firewall rules.
I am open to ALL suggestions.
Jim Weller (NOSPAM_jim@jimweller.net)
Homepage http://www.jimweller.net