Building an 'Enterprise Level' Firewall on the Cheap
13th Dec 2009, 16:16:59
For the past five or six years, I've been using a Power Mac G3 running shorewall on Debian Linux to keep our network safe. The G3 quite happily sat there shuffling packets back and forth without a murmur. Just recently, the Mac would kernel panic for no reason or randomly reset every once in a while. The final straw came when it would periodically introduce latency of 2000ms for no reason at all.
This seemed like a good opportunity to experiment with a low-power, solid-state system. So I chose the Soekris Engineering net5501 as the basis for my new firewall.
The net5501-70 is a 500MHz AMD Geode LX based board. Despite its small size, the net5501-70 includes 512MB DDR-SDRAM soldered to the board, a PCI slot, a mini PCI slot, two serial ports, four network interfaces and a USB port. Storage options are provided by means of IDE, SATA and CompactFlash interfaces. This isn't going to outperform your Mac Pro, but it's more than sufficient for firewalling my network traffic.
I was pretty generous with the options pen when I ordered, electing to specify the 5501-70 with a case, a HiFn based crypto card, a power supply and a 4GB CF card. The bill for this little lot was around £300.00 once it had cleared customs. Quite expensive, but less than a tenth of the price of a Cisco ASA. Specifying the less powerful net5501-60 with a 433MHz chip, 128MB RAM and dropping the crypto card would almost half this cost whilst still being adequate for a simple Dynamic NAT setup.
So, UPS oh bringer of joy turned up with my parcel of wonderment from Soekris. Upon unpacking everything, I found that the board was already installed inside the case for me. I merely had to pop to the top off the case to install the crypto board and the CompactFlash card - very easy indeed. The case itself is 1980s beige, it looks as if it has been made with a hammer by a man in a shed and powder coated by someone who usually finishes railings and shower doors. The dome head LEDs poking through holes punched in the front of the casing gives the unit the appearance of something you might have plugged into your BBC Master. Far from being a bad thing, this gives the unit a very pleasing well engineered retro feel.
The Operating System
Just about any UNIX-like operating system will run on the Soekris. The most popular choices seem to be FreeBSD, OpenBSD and Debian Linux. I had already ruled out Debian Linux due to the Linux kernel's lack of proper support for the HiFn crypto accelerator and because I wanted to have access to pf (a BSD alternative to IPTABLES).
Of all the BSD systems I researched, FreeBSD is the more user-friendly BSD; the FreeBSD handbook being probably the best example of online documentation I've ever seen. OpenBSD on the other hand is specifically designed to be used on highly secured firewall and bastion host systems. The OpenBSD project's philosophy seems to be more in line with the conservative philosophy of Debian - "If it isn't broken, don't fix it". Another big plus is that OpenBSD can network boot without the need to make any kernel modifications. This is important for a Soekris system.
The net5501 can only be booted from a CF card, an IDE or SATA drive or it can be netbooted by
means of pxeboot. It can not be booted from a USB device. Netbooting
OpenBSD is very simple, but you do need a DHCP server upon which you can set
the TFTP server and TFTP filename options. Effectively, these directives tell the NIC's PXE boot
ROM from where it must retreive the OpenBSD installation kernel and begins an installation.
Once this is in place, it is necessary to attach a console to the board's serial interface. I used
minicom set at 19200 8-N-1 with hardware flow control. It is possible to configure
the board's BIOS to communicate at a higher bit rate that this, but I use the console so
infrequently that it isn't worth the trouble. You can
read more complete instructions
on my wiki if you wish.
Once installed, OpenBSD takes up only 0.5GB of disk space. Even allowing for growth in
/usr and logs in
/var, I could quite easily have made do with a 2GB CF
card. Despite its economy in terms of storage, the base system already has all of the tools I need
to create my new firewall system.
pf - The Packet Filter
There are several packet filters available for OpenBSD, but the newest and most feature-rich is pf. pf is infact enabled right out of the box on OpenBSD:
# pfctl -s rules pass all flags S/SA keep state block drop in on ! lo0 proto tcp from any to any port 6000:6010
pf has no problem dealing with VPN protocols like IPsec, it can shape your traffic using QoS, it
even has full support for IPv6. These are features that just aren't found on consumer appliances.
I prefer the syntax of
pf.conf rules to IPTABLES; they are so much more readable. For
example, a simple dynamic NAT config might be:
# State which is the internal and which is the external interface. ext_if="vr0" int_if="vr1" # Leave the loopback interface alone set skip on lo0 # NAT inside to outside: # - the brackets tell pf not to care if the outside address changes nat on $ext_if from $int_if:network to any -> ($ext_if) # If it isn't allowed, block it and log it block log all # Allow all outgoing traffic: pass on $int_if all pass out
Put something like that in
/etc/pf.conf, enable ip forwarding in
/etc/sysctl.conf then just:
# pfctl -f /etc/pf.conf
Differences between IPTABLES and pf:
- The rule syntax is approximately 62.5% less likely to make you want to kill someone.
- The last matching rule is applied (unless the quick parameter is used).
pfctl -f /etc/pf.conftransitions between the new and old rules seamlessly, no need to flush tables etc.
- Rules must be listed in order (set, nat, pass/block etc.).
Much more comprehensive pf notes: