Retinix
News
About Retinix
Articles
Projects
Links

StingLin SpeedTouch USB Firewall for Linux

News

12.1.2002 v0.4
I've finally updated it. The 0.3 version was based on the 2.4.7 kernal. I've now used a 2.4.17 kernel. The ppp over atm patch is now incorporated into the kernel. Other changes are iptables 1.2.4 compiled as a single executable. ReiserFS has been ditched in favour of ext3 for any extra filesystems (the root fs is also ext3, but still mounted read only).

Introduction

This is my attempt at a pre-packaged firewall/gateway based on Linux and the Alcatel Speedtouch USB modem (the weird bluey green thing). This will allow you to connect a home LAN through to an ADSL internet connection.

Requirements

  • A system with USB ports. This generally means anything from a Pentium 1 generation machine up. I'm using a Pentium 75 with 16mb of RAM. It has no builtin USB, so I have a PCI USB card plugged in.
  • An IDE hard disk with at least 12MB of free disk space.
  • An Alcatel SpeedTouch USB modem.
  • At least one LAN card
  • Probably 16mb of RAM mimimum, though I haven't tried it with 8mb.
  • A floppy drive to install from. You could potentially borrow one from another PC, as you won't need it after the install.

Features

  • Allows multiple PCs to connect to the internet.
  • Works like an appliance. Turn the PC on, it boots up and automatically connects to your provider. Turn it off when you're finished with it. No need for fancy shutdown procedures.
  • Utilises an old junky PC
  • Can utilise a few different cheap LAN cards, so the box acts like a 'sort of hub'. This is what I do. I'm too cheap to buy a hub, so all the machines on the home LAN have cross-over cables directly plugged into the gateway machine.
  • Can login via a serial console.
  • Can login via SSH.
  • Contains a minimal set of firewall rules.
  • ext3 support is included if you want to have a web server or general dump area mounted that you need to survive power off/on events.

Software Included

Network card driver modules included

  • 3c59x/3c90x Vortex/Boomerang
  • 3c509 EtherLink III
  • SMC-Ultra
  • SMC WD80*3
  • NE2000 PCI
  • NE2000 ISA
  • AMD PCNet32 PCI
  • CS89x0
  • Davicom DM910x/DM980x
  • EtherExpressPro/100
  • Realtek RTL 8139 10/100

Installation

You need 3 floppy disks for the install. You should probably format them first. They are just normal 1.44MB format floppies. If you have a linux box with 'superformat' you can do this:
   superformat /dev/fd0 hd sect=18
Download and extract the following tar.gz file: There are 3 raw disk images. If you have a unix/linux system you can create the floppies with:
   dd if=disk1.bin of=/dev/fd0 bs=1k
   dd if=disk2.bin of=/dev/fd0 bs=1k
   dd if=disk3.bin of=/dev/fd0 bs=1k
If you're doing this from Windows then you should get Rawrite for Windows available here.

Label disks as 1 ,2 and 3.

Insert disk 1 into your soon-to-be-firewall and boot it up. Disk one is a linux boot/root disk, so you should see an initial LILO prompt, a long pause while it loads the kernel ... then loads the compressed ramdisk contents. Eventually you should get a prompt asking you to press ENTER to login.

At the '#' prompt type 'setup'. This now goes through all the setup steps and prompts you as appropriate. Here are the main steps:

  • Run fdisk. you need to set up one partition on /dev/hda that is at least 12mb in size and is of type 'Linux native' (fdisk will create any new partitions as this type). If you want, you can also set up a Linux Swap partition too. Swap is purely optional. You should only really have a swap partition if you intend to add some memory hungry software to the firewall later on. Make sure you 'w'rite the partition table before you exit. You may have to make the linux partition the 'a'ctive boot partition.
  • Copy the kernel, libc and mke2fs off disk 1 (ie. don't eject disk 1 yet).
  • Put in disk 2 when prompted.
  • Put in disk 3 when prompted.
  • Fixes /etc/fstab so your root partition is named correctly.
  • Set up LILO. If you want a serial console you should say so here. You can specify what baud rate to use for your serial console. The default is 38400. Other posibilities are 9600, 19200, 57600, 115200
  • Generate ssh host keys. You can skip this step as it can take a minute or so on slower machines, but you won't be able to login via SSH.
  • Set the root password.
  • Set up networking. First you have to work out the modules for your LAN cards. Most are reasonably obvious. Some aren't. In some cases you need to enter two modules in order to get a LAN card to work. SMC Ultra is like this. You must put in the 8390.o (don't forget the .o) and then the smc-ultra.o module. If you need to enter additional parameters for the module then specify them after the module name.
       eg. smc-ultra.o io=0x280 irq=3
    
  • Set up PPP login information. You'll need to enter your ADSL login and password for your provider as well as your VCI.VPI pair.
  • Eject any floppies and reboot.

Operation

Boot up the PC. If you're using a serial console, make sure you have an appropriate serial terminal (or PC running a terminal program) plugged in. The usual settings are hardware handshaking/8 bits/no parity and whatever baud rate you set.

The screen output can be messy, but hopefully you should get something like:

Waiting for ADSL negotiation
Starting Stingray Modem.
Waiting to sense USB attachment
                               .usb_control/bulk_msg: timeout
usbdevfs: USBDEVFS_BULK failed dev 2 ep 0x85 len 512 ret -110
.
(none) login: ..............
The USB errors appear to be OK. I just always get them. The string of dots is printed as the PC waits for the Modem initialisation message. This can take minutes so be patient. The next thing you should see is:
Terminated
Starting pppd
PPP is up
Don't worry about the 'Terminated'. Its supposed to happen. Now you should be able to press ENTER and get a login prompt. Login and try pinging some known address (eg. ping yahoo.com). It should work. DNS server information is automatically retrieved from the ppp connection.

In order to use a PC on your internal LAN, you'll need to specify a default gateway (on the PC) that corresponds to the LAN card on the firewall PC. You also need to specify the DNS servers. To find these out from the firewall PC, just login to it (using ssh) and cat /etc/resolv.conf.

There is a default firewall config script that is run during boot. It is not reconfigured based on the IP address info you entered (maybe in the next version). So unless you set up your internal network like mine, you probably won't get far. Basically, my setup is to have 3 network cards on addresses 10.0.0.5, 10.0.1.5 and 10.0.2.5 (all with netmask 255.255.255.0). Each card just has a crossover cable going to a PC. The firewall script will allow most traffic from these 3 subnets to go out via the ADSL connection. The important variable assignments in the /etc/rcFirewall script are all at the top of the script.

Firewall Boot Sequence

This is the first time I've used Busybox's init to start up a system. Its syntax is different and the way it works is slightly odd too ... but it gets there in the end. Here's the typical inittab:
::sysinit:/etc/rcS
::once:/opt/ssh/sbin/sshd
::once:/etc/rcStartStingray
::once:/etc/rcADSL

::respawn:/sbin/agetty 38400 tty1 linux
There are no run levels. The first thing that gets run is the 'sysinit' part. This performs the bulk of the startup. next would be the 'wait' items but I don't have any and then the 'once' items. The 'once' items are launched asynchronously (ie. Busybox's init doesn't wait for them to complete). And lastly to get a console login, there's a respawn item that launches an agetty.

/etc/rcS

This performs the following:
  • Firstly, the device filesystem helper process is started so that the old style device names are present under /dev.
  • Mounts the 512K ramdisk on /var and then sets up the directory structure within it. These are things like /var/tmp, /var/adm etc. it also creates a /var/ppp which /etc/ppp symlinks to. /etc/ppp-master (on the hard disk) is then copied into /var/ppp so that the pppd config files are present when pppd eventually starts.
  • Start klogd and syslogd (the Busybox ones) which log just about everything to /var/adm/messages
  • Mount /proc and /dev/pts
  • Load the main device modules
  • Configure the network interfaces
/opt/ssh/sbin/sshd
Originally, sshd was launched from rcS. The problem with this is that as soon as the rcS script finishes, it kills any child processes (ie. sshd). The way to get around this is to launch sshd directly from init using a 'once' line.
/etc/rcStartStingray
If you've read the other Howto's you'll know that the typical command sequence to kick the SpeedTouch into life is to :
  insmod speedtch
  speedmgmt &
I've put the insmod into the main kernel module load routine, so that just leaves running speedmgmt. This turned out to not be a trivial task. Because you are meant to launch speedmgmt in the background (ie. it cannot fork by itself), it means its attached to the controlling terminal. I tried putting it in the main rcS routine, but as soon as rcS finished, speedmgmt would die because the script would exit. By putting this script as a 'once' item in init, it means that its launched asynchronously and can potentially run forever. So basically we just:
   exec speedmgmt
, so it replaces and gets rid of the ash shell that launched it and leaves it running forever. We do have to do one other thing before launching it though. Make sure the 'USB plugin' event for the modem has been registered. Even though the USB modules are all loaded in rcS, there seems to be a delay before the SpeedTouch device is actually sensed that its plugged in. If speedmgmt is started before the 'USB plugin' event then it gracefully dies. Most people use the 'hotplug' system to get around this. I just look at /proc/usb/bus/devices and grep for 'speedtouch'. If its not there I go to sleep for a second and try again.

/etc/rcADSL

This is also a 'once' script as it needs to be launched around the same time as the rcStartStingray script. When speedmgmt starts (in rcStartStingray) it will talk to the modem and the LEDs will flash for some time while the ADSL link is negotiated. Eventually it will finish and say something like:
   Modem initialised at 2208 kbit/s downstream and 800 kbit/s uptream
This gets written into /var/adm/messages. There is no point starting pppd until we get this message, rcADSL, just looks at the messages going into /var/adm/messages and waits for the Modem intitialised string. Once its got it it starts pppd. This should now quickly connect and we have a connection
The getty
The last line in inittab is to start up a getty either on the normal virtual console or on a serial line.
But there's more
The last major thing init does is to start up pppd. pppd should connect within seconds and will automatically run the ip-up script in /etc/ppp. ip-up then calls /etc/rcFirewall script. This script sets up some simple firewall rules involving doing MASQUERADING from the internal LAN cards onto the ADSL connection.

Setting up a Web Server

You may have noted that mini_httpd is included with StingLin. The idea is that you can utilise some of your spare disk space (you didn't use up the whole disk for StingLin's partition did you?) for web server content. Unlike, the root fs that is permanently read-only, the web server content file system will need to be read/write (technically it doesn't have to be but its a lot more flexible). Now, because the system was designed so you could just turn it off without shutdown procedures, the web server filesystem needs to be recoverable through and unclean shutdown. Prevously, I used reiserfs, but now that ext3 is getting more mainstream I'm using it. Its seems a lot more simpler, recovers quickly (unlike reiserfs) and doesn't require that enormous mkreiserfs binary.

Here's what you might do:

   mke2fs -j /dev/hda4
   mount -t ext3 /dev/hda4 /mnt
   cd /mnt
   mini_httpd -r
Now to mount it at boot time, you could just put the following in /etc/rcS:
   mount -t ext3 /dev/hda4 /mnt
If you want to do this mount in the background (just in case it does take a long time), then create an /etc/rcHttp startup script and launch it asynchronously.
Change /etc/inittab so that it looks like:
   ::sysinit:/etc/rcS
   ::once:/etc/rcHttp
   ::once:/opt/ssh/sbin/sshd
   ::once:/etc/rcStartStingray
   ::once:/etc/rcADSL
Now create the /etc/rcHttp file as:
   #!/bin/ash
   mount -t ext3 /dev/hda4 /mnt
   cd /mnt
   exec /sbin/mini_httpd
And make sure its executable (ie. chmod 700 /etc/rcHttp).
So now when the box starts up it will begin the motions of connecting to your ISP, but at the same time it will trying to mount your ext3 partition. If you're lucky the mount will have completed and mini_httpd will have started by the time the ISP connection is made.

Notes

  • The root partition is mounted read-only. If you need to make changes to any files you will need to log in as root and remount the root fs read/write , make the changes, then remount it read-only:
       eg.   mount -o remount,rw /
             vi /etc/hosts
             mount -o remount,ro /
    
  • When you first try to login using ssh it will hang for a long time. It's trying to do a reverse lookup on the machine that you're connecting from. If you don't want the delay then add the name and ip of your ssh client system into /etc/hosts:
       10.0.0.99    mypc
    
    For that matter, you should probably add in names and IPs for each LAN card you have on the system.
  • The firewall rules in /etc/rcFirewall are only meant as a starting point. I suggest you search the web for more information and amend the rules as appropriate. In fact you may have problems connecting anywhere until you change them.
  • I find that my ADSL provider's ppp name authentication doesn't work correctly all the time. I'll often get:
       LCP terminated by peer
    
    in /var/adm/messages and consequently pppd dies. I then have to log in, and just type 'pppd' and check /var/adm/messages repeatedly.

Jan 18,2002

1