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.
May 13th, 2007 at 12:37 am
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
August 10th, 2007 at 4:07 pm
Any plans to update documentation for Debian Etch?
Also can you share your kernel.config.