Building a mini Debian based router/firewall

Until recently, as an internet gateway/router/firewall/access point, I was using LEAF Bering (Linux Embedded Appliance Firewall) on a small fan-less appliance that uses a compact flash as a hard disk. It worked quite correctly but I was not happy with the fact that LEAF cannot evolve easily. It requires very specific knowledge and I felt like I was not really controlling it.

During last week-end, I felt somewhat courageous and started building a mini system based upon Debian which is a much more standard distribution and which I know much better. A requirement was that it had to be pack on a 128MB flashcard. I took some notes so I’ll describe below the steps I followed. Hope that it will help someone.

Installing the basic system

First, thanks to the great tool “debootstrap”, on my laptop, I installed a basic Debian system in a directory, chrooted into it and installed additional Debian packages.

root@laptop:/# mkdir /minidebian/

root@laptop:/# debootstrap --arch i386 sarge /minidebian/ http://ftp.fr.debian.org/debian
I: Retrieving Release
I: Retrieving Packages
I: Validating Packages
I: Checking component main on http://ftp.fr.debian.org/debian...
I: Extracting base-files...
I: Extracting base-passwd...
I: Extracting bash...
[...]
I: Installing core packages...
I: Unpacking required packages...
I: Configuring required packages...
I: Installing base packages...
I: Base system installed successfully.

root@laptop:/# chroot /minidebian/ /bin/bash
(from now on I am on the minidebian system)

root@chroot:/# apt-setup
(I selected a source for apt)

root@chroot:/# apt-get update
root@chroot:/# apt-get upgrade

root@chroot:/# base-config
root@chroot:/# dpkg-reconfigure console-data
(I chose my keyboard configuration)

root@chroot:/# apt-cache search kernel-image
(I chose a kernel-image)
root@chroot:/# apt-get install kernel-image-2.6.x

root@chroot:/# apt-get install libatm1
root@chroot:/# apt-get install shorewall
root@chroot:/# apt-get install dhcp
root@chroot:/# apt-get install ssh

Configuring the network

I use an Alcatel Speedtouch ADSL modem. The drivers are already in the Linux 2.6 kernel, no need for “modem_run” as mentioned in many tutorials. I configured Ethernet only for the moment.

root@chroot:/# cat /etc/network/interfaces
auto lo
iface lo inet loopback

# This is a list of hotpluggable network interfaces.
# They will be activated automatically by the hotplug subsystem.
mapping hotplug
        script grep
        map eth0

auto eth0
iface eth0 inet static
        address 192.168.100.1
        masklen 24
        subnet 192.168.100.0
        netmask 255.255.255.0
        broadcast 192.168.100.255

root@chroot:/# cat /etc/dhcpd.conf

dynamic-bootp-lease-length 604800;
max-lease-time 1209600;

subnet 192.168.100.0 netmask 255.255.255.0 {
	option routers 192.168.100.1;
	option domain-name-servers 212.94.174.85;
	range 192.168.100.10 192.168.100.99;

#        host bob {
#               hardware ethernet XX:XX:XX:XX:XX:XX;
#        	fixed-address 192.168.100.100;
#        }

}

#subnet 192.168.101.0 netmask 255.255.255.0 {
#	option routers 192.168.101.1;
#	option subnet-mask 255.255.255.0;
#	option domain-name-servers 212.94.174.85;
#	range 192.168.101.10 192.168.101.99;
#
#}

root@chroot:/# cat /etc/ppp/chap-secrets
# Secrets for authentication using CHAP
# client        server  secret                  IP addresses

'login' * 'pass' *

root@chroot:/# cat /etc/ppp/pap-secrets
(same than above)

root@chroot:/# cat /etc/ppp/peers/speedtch
noipdefault
defaultroute
noauth
updetach
usepeerdns
plugin pppoatm.so
8.35
user "login"

root@chroot:/# cat /etc/init.d/speedtch
#!/bin/bash
modprobe ppp_generic
modprobe pppoatm
count=0
while [[ $((count++)) -lt 40 ]]
do
  sync=$(dmesg | grep 'ADSL line is up')
  if [ ! -z "$sync" ]
  then
    pppd call speedtch
    exit 0
  fi
  sleep 1
done
echo "The Speedtouch firmware didn't load"

root@chroot:/# ls -l /etc/rc2.d/
[...]
lrwxrwxrwx  1 root root  18 Mar 25 02:25 S15speedtch -> ../init.d/speedtch

root@chroot:/# ls /usr/lib/hotplug/firmware/
speedtch-1.bin  speedtch-2.bin

Testing the new system

I then tested the new system by booting into it. It is not necessary to create a new partition, it possible to boot into a directory, as described below. Worked like a charm.

root@chroot:/# cat /chrootinit
#!/bin/bash
mount -t proc /proc /proc
mount -o bind /proc /minidebian/proc
mount -o bind /dev /minidebian/dev
exec /usr/sbin/chroot /minidebian/ /sbin/init

root@chroot:/# exit
exit
(from now on I am on my real Linux installation)

mathieu@laptop:/$ cat /boot/grub/menu.lst
[...]
title           Debian
root            (hd0,0)
kernel          /minidebian/boot/vmlinuz-2.6.x-486 root=/dev/hda1 rw init=/minidebian/chrootinit quiet splash
initrd          /minidebian/boot/initrd.img-2.6.x-486
boot
[...]

root@laptop:/# reboot

Compiling the kernel

It is time to save space. First, I recompiled the kernel and saved about 30MB. I was not very selective, I only removed options that would obviously not be necessary for my purpose such as support for sound, some filesystems, some USB devices, some networks protocols, some video cards etc.

root@chroot:/# apt-get install kernel-package bin86 libncurses5-dev module-init-tools initrd-tools procps
root@chroot:/# apt-get install linux-source-2.6.x
root@chroot:/usr/src# tar xfj linux-source-2.6.x.tar.bz2
root@chroot:/usr/src/linux-source-2.6.x# make menuconfig
root@chroot:/usr/src/linux-source-2.6.x# make-kpkg --revision=minidebian.0.1 kernel_image
root@chroot:/# dpkg -i /usr/src/linux-image-2.6.x_minidebian.0.1_i386.deb
root@chroot:/# mkinitramfs -o /boot/initrd.img-2.6.x 2.6.x

Trimming the system

It is still possible to gain a lot of space by deleting unnecessary files such as cache, manual pages, documentation and so on…

root@laptop:/# cp -R /minidebian/ /minidebian_good_copy/
(let's backup everything first)

root@chroot:/# dpkg-query -W --showformat='${Installed-Size} ${Package}\n' | sort -rn

root@chroot:/# apt-get remove pppoe pppoeconf telnet slang1a-utf8 gettext-base aptitude \\
 libssl0.9.7 dselect perl perl-modules libc6-dev linux-kernel-headers cpp-4.0 kernel-package

root@chroot:/# rm -rf /usr/src/* /var/cache/apt/archives/*.deb /var/cache/apt/*.bin  \\
/usr/share/locale/ /usr/share/doc /usr/share/info/  \\
/usr/share/man /usr/share/zoneinfo/ /var/lib/apt/lists/*.* /var/cache/debconf/*

I finally end up with a 90MB system. It is also possible to use Cloop, a module that adds support for transparently decompressed block devices. It is used in most of the Live CDs and has been initially written for Knoppix. From tests I made, I would say it is possible to save up to about 66% of space.

Making the partition

A flashcard can be written a limited number of times only, so I used RAM disks for logs. See my fstab file below.

root@chroot:/# cat /etc/fstab
#     
       

proc            /proc           proc    defaults        0       0
/dev/hda1       /               ext2    defaults,errors=remount-ro 0       1
tmpfs           /tmp            tmpfs   defaults,noatime  0   0
tmpfs           /var/run        tmpfs   defaults,noatime  0   0
tmpfs           /var/log        tmpfs   defaults,noatime  0   0
tmpfs           /var/lock       tmpfs   defaults,noatime  0   0
tmpfs           /var/tmp        tmpfs   defaults,noatime  0   0
tmpfs           /var/cache      tmpfs   defaults,noatime  0   0

Finally, it is time to set the system on the flashcard.

root@laptop:/# fdisk /dev/sda
(creating a primary bootable linux partition)

root@laptop:/# mkfs.ext2 /dev/sda1
root@laptop:/# mount -t ext2 /dev/sda1 /mnt/flash
root@laptop:/# cp -R /minidebian/* /mnt/flash

root@laptop:/# grub-install --root-directory=/mnt/flash /dev/sda

root@laptop:/# cat /mnt/flash/boot/grub/device.map
(hd0)   /dev/sda

root@laptop:/# cat /mnt/flash/boot/grub/menu.lst :
default 0
timeout 1

title           Debian
root            (hd0,0)
kernel          /boot/vmlinuz-2.6.x root=/dev/hda1
initrd          /boot/initrd.img-2.6.x

Still to do

I still need to set up the wireless aspects of the network. I also think I will toy with the VPN thingy. Should be instructive and funny.

2 Responses to “Building a mini Debian based router/firewall”

  1. danny Says:

    dpkg-query -W –showformat=’${Installed-Size} ${Package}n’ | sort -rn

    has a type and should be

    dpkg-query -W –showformat=’${Installed-Size} ${Package}\n’ | sort -rn

    “\” added

  2. Sam Says:

    Any plans to update documentation for Debian Etch?
    Also can you share your kernel.config.

Leave a Reply

CAPTCHA Image