Introduction: Build Your Own Gateway Firewall

About: Software developer, Placethings co-founder, and technologist. Currently attending graduate school in the Emerging Media and Communications program at the University of Texas at Dallas.

Learn how to build your own gateway firewall using FreeBSD® and old PC parts. The firewall will consist of the PF firewall, Snort IDS, various IPS applications, Squid proxy, and some intuitive web interfaces for auditing. The cost of this project should be between free and $200 depending on your resourcefulness. I built mine for free using spare parts that were stockpiled in personal storage and parts that the USMC was throwing away, but you can build one from used and/or new parts for dirt cheap.

This is a work in progress, and unfortunately, due to college and work, I don't have the time right now to cover every detail of this project. I'd love to collaborate with others to cover what we can. If you're interested contact me at j0hn7r0n at gmail dot com or catch me online at j0hn7r0n (AIM) or iiwishihadaname (Yahoo).

The FreeBSD Logo is a trademark of The FreeBSD Foundation and is used
by John Syrinek with the permission of The FreeBSD Foundation.

The mark FreeBSD is a registered trademark of The FreeBSD Foundation
and is used by John Syrinek with the permission of The FreeBSD Foundation.

Step 1: Parts

Through the use of open-source software (OSS), outdated PC hardware, and a little know-how, you can build a cheap and highly effective gateway firewall to protect your SOHO LAN.

FreeBSD has its roots in the server environment, and continues to impress me with its performance, ease of use, and security. Combined with it's zero-dollar pricetag, FreeBSD provides the average user with a culmination of the most modern features, powerful network services, and intuitive setup processes. Apple apparently liked it so much, that they combined FreeBSD with the Mach 3 microkernel and a fancy desktop environment known as Aqua to create OS X.

The hardware used for my gateway firewall consists of the following:
  • An old Pentium 3
  • 256MB of PC100 RAM
  • Two 100/10baseT(X) NICs (one on-board)
  • 50GB IDE hard drive
  • Generic IDE CD-ROM drive
  • An old junker desktop ATX case
  • 300W PSU
  • Some Cat5/5e/6 ethernet cable

Most of this stuff can be found at computer scrapyards for between cheap and free. The USMC actually donated the case, motherboard, and processor to me when they cleaned out an old computer warehouse.

Believe it or not, dumpster-diving (eeek!) can turn up a whole slew of useful hardware. Large businesses and educational facilities often throw outdated computers away in large quantities. Though outdated, these would be ideal for our purpose. Be sure to ask the owners if you can help them dispose of their trash before you go digging around though.

I have quickly built a shopping cart on to give you an estimate of what it would cost to build this project with completely new parts. The grand total came to $171.94. Please realize though, I HAD to choose hardware that is considered overkill. People just don't sell the old stuff anymore. It costs them more to keep it in inventory than they can make selling it.

Step 2: Making Sure Things Will Fit

The hardest part about building a computer from scratch is finding the right parts. My suggestion would be to find a compatible motherboard and processor, then find the rest of your parts based on the capabilities of your motherboard.

Every computer must have the following parts:
» Processor (obviously)
» Motherboard
» Physical drives - optical and/or hard)
» Input/output devices - NICs, keyboards, mice, monitors, etc.
» Case (although it's fun to leave this part out and mount the mobo on your wall)
» Cooling unit - Heatsink and/or fan (aka HSF), watercooling/phase-change cooling (not practical here, but fun regardless)

Often times, when building a computer, people put most of their money here. People are ingrained with the impression that a fast processor makes for a fast computer. This is not the case. A fast system relies equally on the speed of all the devices. A motherboard with a fast chipset and high front-side bus (FSB) is just as important as a fast processor. RAM is the other vital component in a fast system. For our system, the speed of all of these is a minor concern, as we are more concerned with the cost-effectiveness.
» AMD Athlon K7/K75/Thunderbird - Found in Slot A and Socket A.
» AMD Duron - Found in Socket A only.
» AMD Athlon XP - Found in Socket A.
» AMD Athlon MP - Found in Socket A.
» AMD Sempron - Found in Socket A and 754. These are just re-labelled Athlon XPs.
» AMD Athlon 64 - Socket 754 and 939. Come in dual-core also. I'm running an Athlon 64 3700 San Diego in my gaming rig, so you can see how these are MAJOR overkill.
» AMD Athlon 64 FX - Socket 939 and 940. Even more overkill than an Athlon 64. Although, I'd be happy to take an Athlon 64 FX-60 off of someone's hands :P
» AMD Opteron - Socket 940. Though geared towards server environments, this processor is about as much overkill as you can find (expensive too).
» Intel Celeron 500A to 2.8GHz Northwood - Found in Slot 1, Socket 370, 423, and 478 varieties.
» Intel Pentium III - Found in Slot 1 and Socket 370 varieties.
» Intel Celeron D - Found in Socket 478 and T.
» Intel Pentium 4 - Socket 423, 478, and T. Overkill
» Intel Xeon - Socket 603, and 604. Major overkill.
» Intel Itanium - Found in PAC611. Major overkill.

This is perhaps the hardest part to pick out, and also the most important. Due to the nearly inifinite variety, I will simply mention the most important features to consider.

» Socket/Slot - This is where your CPU will live. Make sure that your motherboard's socket is compatible with your processor. Often times a socket will be named after it's pincount. In most cases, if the processor and socket have the same pincount, they are compatible. Be careful though, this is not always the case. Be sure to double check.
» Drive interfaces - These are where your drives connect to your motherboard. Paralell ATA (aka ATA, PATA, IDE, EIDE) drives are still the most common, but are being phased out by the faster and more efficient Serial ATA (SATA). ATA comes in ATA66, ATA100, ATA133, and ATA166. SATA150 (aka SATA-I or just SATA) is often compatible with SATA300 (aka SATA-II or SATA with NCQ) motherboards. Another interface typically found in server environments is SCSI. These are being replaced by Serial-ATA due to cost.
» RAM slots - These are where your RAM goes. They are often referred to as DIMM slots. Sometimes you will see the pincount mentioned in the name or description. The slots that I'm familiar with support SDRAM (PC100, PC133), DDR SDRAM and DDR2 SDRAM (In varietes from PC1700 to PC8500), and RAMBUS (rare, pricey RAM that was ahead of it's time; only runs in pairs).
» Input/output interfaces - These are where add-on cards go. The most common are ISA (slowest and only found in industrial motherboards nowdays), PCI (slowest of all in common use, used for pretty much any kind of add-on card), AGP 1x/2x/4x/8x (common; almost always used by videocards; being phased out by PCI Express), PCI Express (fastest of all slots; typically used for videocards), PCI-X (not to be confused with PCI Express; can be (almost) as fast as PCI Express; comes in speeds such as 1x, 4x, 8x, etc.) Make sure that your NIC and video card each have a slot of their own (although it is possible to run this without a videocard).
» Form factor - This determines what kind of case you can use. Form factors include AT (obsolete), Enhanced/Extended ATX (big boards!), ATX (most common), Mini-ATX (small versions of ATX), Micro-ATX (even smaller), Mini-/Micro-/Pico-/Nano- ITX (tiny!). Any of these will work, but be careful of Mini-/Micro-/Nano-/Pico- ATX/ITX boards. Sometimes these have proprietary components that are not supported by FreeBSD drivers. I'd be happy to take an EPIA N Nano-ITX off of someone's hands also.
» Power interfaces - This is where your PSU connects to your motherboard. I'm familiar with 20-pin and 24-pin connectors, as well as Intel/AMD 4-pin headers. Make sure your PSU will plugin to your motherboard. If it doesn't, you can probably find conversion wires to make it fit for a few bucks at your local computer store.
» Backpanel - This is the collection of plugs located at the back of the motherboard. You will almost always find your keyboard, mouse, parallel, and serial connectors here. Many boards also have VGA/S-Video, LAN, USB, Firewire, and/or audio jacks here also.
» Fan headers - These are where your CPU and case fans plugin. Make sure you have enough to accomidate all of your fans. If you don't, you can either remove some fans (BUT NOT THE CPU FAN!), or find/purchase some 4-pin molex to 3-pin fan header conversion wires or 3-pin Y-splitters.

Pretty much any RAM will work as long as it's atleast as new as PC100 and is compatible with your motherboard. A decent capacity is but 128MB. Larger capacities will help speed up your compiling processes.

You can use memtest to test your RAM prior to installing FreeBSD. It may save you some headaches later.

ATA IDE drives are still the most common, but are being phased out by the faster and more efficient Serial ATA. ATA comes in ATA66, ATA100, ATA133, and ATA166. The numbers are associated with theoretical maximum transfer rates. Often times you will see a motherboard that says it supports ATA133. If the motherboard supports ATA133, it usually supports the slower ATA100 and ATA66 specifications. Make sure your motherboard supports an ATA standard greater-than or equal to the one used by your harddrive. Serial ATA has the same considerations. SATA150 (aka SATA-I or just SATA) is often compatible with SATA300 (aka SATA-II or SATA with NCQ) motherboards. Rarely are newer technologies backwards compatible with older ones, but ocasionally you'll find that a firmware update will allow this. If you plan on using SATA, you will most likely need a different power connector; although, Western Digital usually places both the legacy 4-pin molex power connector and the new Serial-ATA connector (DON'T USE BOTH SIMULTANEOUSLY!). If you need a Serial-ATA power connector, don't worry, there's conversion wires for those too.

Hard drive capacities greater than 1GB should be plenty. 100MB is the absolute minimum, but 250MB is recommended. Add 100MB to that if you plan on using a desktop environment.

If you are not using a relatively new (1 year or younger) hard drive, it is wise to perform a diagnostics test before installing your system. Because of their moving parts, hard drives are more prone to failure than the rest of your components.

Optical drives are what you'll use to install the operating system. Almost any drive will work for this as long as it is compatible with your motherboard. FreeBSD can be installed from CD ISOs or a single DVD ISO. It can also be installed from a USB drive (if it's large enough and your motherboard supports booting from USB) or the network. The later will not be covered here.

In our case, your NICs (Network Interface Cards) will be a vital component to the functionality of your PC. You will need two of these, one for the WAN side, and one for the LAN side. Often times you'll find one (or even two) NICs integrated into your motherboard. Just check the backpanel of the motherboard to find out. Your NICs will need to support atleast 10Mbps 10BaseT, but anything faster will work. This tutorial will only cover 10BaseT to 1000BaseTX NICs.

Monitor, keyboard, and mouse
You should be familiar with these already. We will only need a keyboard and monitor for the initial setup process. Afterwards, you can unplug these. Monitors come in VGA and DVI varieties (DVI being digital and newer). A TV can also be used if your motherboard and the TV both have S-Video connections and there is an S-Video driver for FreeBSD. Mice are either PS2 (no, not that one), USB, or the older ADB and RS232. Keyboards are the same. There are adapters to convert most of these to the correct plug.

If the CPU is the brains of your computer, the PSU is the heart. Make sure you have enough of the appropriate connections to power all of your devices. One of the most common problems with building computers is a weak/unstable PSU. You will experience random, unexplained problems if you skimp on the power supply. One of the most common signs of an underpowered computer is random shutdowns. If your computer turns off randomly, it is your hardware protecting itself from the lack of power. Depending on your hardware, you may need something as powerful as 300W. Then again, you may only need 100W. To give you an idea of how much is TOO much for this project, I use a 650W powersupply in my gaming rig; however, a more powerful PSU will not harm your system.

Nothing special here. Make sure it supports your motherboard's form factor. Larger cases are easier to use because you have more room for wires and connectors. Tiny cases might have cooling problems if they are placed in areas with poor circulation. If your PSU doesn't fit in your case, you can modify the case to accomidate it. Be careful though! If you have to modify your PSU, take appropriate precautions. Unplug and discharge it first.

Be sure you have both a heatsink and fan. If you don't have a fan, be sure you have a decent passive-heatsink, acceptable ambient air temperature, and adequate airflow in and around the case. This is another place to be careful. After the initial build, touch your processor from time to time to make sure that it's cooling. It should be warm, but not hot. If your arm jerks in reflex to touching it, it's too hot. Cooler running processors also last longer. Newer processors are more succeptible to thermal damage due to tighter tolerances and electron-migration. Older processors are more stable, and therefore popular in the overclocking community. Watercooling can bring your CPU temperatures close to ambient air temperature, but is overkill here. Phase-change cooling and TECs are MASSIVE overkill. They can drop your temperatures far below freezing where condensation becomes an issue. I wouldn't ming a TEC + Watercooling kit though :P

I think that about covers the hardware, but here are a few things to keep in mind:

» Larger RAM capacities speed up your compilation process. Nowdays 256MB of RAM is marginally more expensive (sometimes cheaper) than smaller capacities due to production, ROI, and storage costs.

» Your NIC should support atleast 10Mbps ethernet (aka 10BaseT). Because most people don't have internet connections higher than 10Mbps, the slower speed is acceptable here. If you can, try to make sure your NIC supports full-duplex to avoid collisions. Full duplex is denoted by an "X" on the end of the media type (eg. 10BaseTX). 100Mbps ethernet (100BaseT) is much more common than 10BaseT(X) and perfectly acceptable, although it is unlikely that you will see any performance gain from using it.

» Your hard drive and optical drive should most likely be ATA IDE drives. You will often see drives labeled ATA100 or ATA133. These work fine. On newer drives and controllers you will see the label Serial-ATA or SATA. These will work if your motherboard has the appropriate (SATA150 or SATAII/300) headers. SATA is major overkill for a simple gateway/firewall because it will VERY rarely be used. In fact, it would be possible to build this project without a harddrive altogether.

» Your PSU (Power Supply Unit) should be able to supply enough STABLE power to all of your devices simultaneously. A 300W PSU is more than enough for the minimal PC that we'll be building.

» If you plan on placing this gateway firewall in a small location, make sure the case is small enough. Because you will not need a monitor, keyboard, or mouse after the initial installation process, it is possible to store the firewall virtually anywhere! I have mine in my closet. Make sure you nave enough ethernet cable also.

Physically building a computer from scratch is much easier than most people think. Due to that large variety of physical connectors, it's pretty hard to damage hardware by placing it in an incorrect slot. If you have to force something into a slot, you're doing something wrong; otherwise, don't worry about frying the component. This hardware is cheap, and it's a good learning experience. Wouldn't you rather make mistakes now than when you build a multi-thousand dollar gaming rig?

Step 3: Putting It All Together

Below are some pictures we took when my brother and I were building our NAS. I'll add comments to each step when I find the time, but, for now, here's the overview (in order):

» Clean everything off. Use compressed air to remove the dust from electrical components. A paintbrush can be used to remove dust from the fans. Do NOT use the paintbrush on electrical components! This may create static and damage your parts.
» Mount the motherboard in the case. It's best to do this now, because you might not be able to later.
» Mount the PSU. Again, do this now, because you may not be able to once you install the CPU, HSF, and drives. Do NOT plug the PSU into the motherboard, and make sure that the PSU is powered off and unplugged.
» Place the CPU in the retention mechanism. Be sure to properly ground yourself first by plugging in your PSU and touching the case as you unplug your PSU. Anti-static wristbands work even better. Do not force the CPU into the socket. Make sure you insert the CPU in the correct orientation. Use the pins and socket as reference. It should either slide in with a little pressure (Slot CPUs) or drop right in (Socket CPUs). After it is in place, be sure to fasten any latches or switches that hold the CPU in place.
» Grease the CPU. Thermal compound is used to fill the microscopic air pockets between your CPU and HSF with a thermally-conductive material. If your CPU has a heatspreader (extra metal around the core to provide strength), apply a dime-sized amount of thermal compound to the center of the heatspreader. If the CPU does NOT have a heatspreader, apply a small dab of thermal compound. Spread the compound around using a piece of stiff paper (a business card works great). If you get a little compound somewhere other than the top of the CPU, a little isopropyl alchol (rubbing alcohol, not booze) and some Q-tips will help to remove it. When you're finished, you should have a very thin layer of thermal compound covering the entire surface of the CPU.
» Install the HSF. This is often the most nerve-racking part. Sometimes it takes some force to secure the HSF retention mechanism. First, examine the retention mechanism to learn how it works. This will give you an idea of how to properly secure it, and ways that you may damage it. Next, take your time and carefully apply the appropriate force to secure the HSF. If you see your motherboard flex, or you're using enough force to move your case, you're probably doing something wrong. After you have the heatsink on, install the fan. Also, BE SURE YOU PLUG THE CPU FAN IN.
» Install the ram. Look at the DIMM slots on your motherboard and make sure that you are inserting the RAM correctly. There should be a ridge in the slot itself, and a notch in your RAM to help you determine the correct orientation of the RAM. You will also need to open the clips on the ends of the DIMM slots to allow insertion of the RAM. Now, carefully apply an even downward force to the RAM until you hear a click. This is the sound of the side fasteners locking the RAM modules into place.
» Install the drives. Because of their size, the drives should be installed next. Place the drives in their appropriate locations, and connect the power and data cables. Your harddrive should be connected to your primary IDE channel (labelled something like IDE_0 or Primary or 1). Your optical drive can share the same ribbon as your hard drive; however, if you plan on removing it, it's better to connect it to the secondary IDE channel for easy removal. You may notice an extra plug on the back of your optical drive. This is for digital audio. It's safe to ignore this.
» Install the I/O devices. Use a steady downward force to secure the PCI, AGP, and/or ISA cards in their appropriate slots. Be careful not to flex the cards while you're installing them. Sometimes the VGA slot has a little pin to better secure the video card. Should you ever remove the video card, you will need to release this pin first.
» Install any case fans. Consider the environment where the firewall will be placed, and provide enough fans to maintain adequate cooling. Larger fans are more quiet and move less air. If you're placing your firewall in an air-conditioned environment, and you have a decent sized case, one fan or no fans should provide enough cooling.
» Connect the power, reset, HD activity LED, Motherboard status LED, and system speaker. On most motherboards, the connections for all of these can be found in two rows of pins somewhere on the motherboard. Please refer to any documentation you can find to attach your power switch and indicators to the correct location. One trick to help locate the power-on or reset pins if you are POSITIVE that you have found the correct set of headers is to use a screwdriver to temporarily short jumpers until the computer turns on. You will have to do this after you connect the PSU to the motherboard (obviously).
» Connect the PSU to the motherboard. Connect the 20- or 24-pin connector to the motherboard. You may find an extra 4-pin connector on the motherboard also. This is to provide additional power to the motherboard. Often times it is unnecessary to connect this, because we will not be drawing enough power to connect it. Try powering on the motherboard without it, and if that fails, plug it in and try again.
» Power on and pray. This is the moment of truth. Did you install your RAM correctly? Is your CPU fan plugged in? If you hear more than a single short beep from your system speaker (you plugged that in right?), then something is probably wrong. Power off immediately and check your documentation to confirm that you've done everything. The beeps that you heard (error codes) can be used to help diagnose the problem.

Step 4: Installing FreeBSD and the Ports Collection

Due to time constraints, I only have time to cover the required software and a brief overview of the installation process.

Obtaining the OS
Grab the CD ISOs or purchase the actual CDs or DVD from You can use either FreeBSD 5.4 or 6.0, either one works. Be sure you download the correct image for your architecture (only x86 is covered here). When in doubt, just grab the x86 and try it. I've never tried the AMD64 version of FreeBSD. The libraries were a pain to maintain with the AMD64 version of FC2 though. If you've used this architecture build, let me know how it works. If you have a 64-bit AMD processor, it is backwards compatible with the x86 architecture, so you have something to fallback to if you want to have an adventure in 64-bit computing.

Preparing the installation media
If you've downloaded the ISOs, burn them to CDs. Make sure your BIOS is set to use the CD/DVD drive as your primare boot device

The OS Installation Process
Follow FreeBSD's installation procedures. The default partition settings work fine for our purpose, but if you don't plan on rotating your logs regularly, you might want to increase the size of the /var partition.

As far as the ports collection is concerned, there are two methods to consider. If you don't want to bother with manually installing only what you need, install the entire ports collection; otherwise, perform a minimal install
» Update your ports collection. THIS IS IMPORTANT. If you do this PRIOR to building and installing any software, you'll save time later by not having to upgrade.
» Make sure all of your hardware is recognized. You may want to install the nVidia or ATI drivers if you're going to be using a desktop environment like KDE or Gnome
» Configure your ethernet interfaces
» Reboot and make sure that everything works and that you have internet access (by using lynx to view a website, or a simple ping connectivity test)

Again, any collaboration would be appreciated. See the intro for contact details.

Step 5: Configuring Your Software

Here is a VERY brief overview of the configuration process.

» Install and configure OpenSSH for network terminal emulation. Pre-shared keys are definately recommended, but not a requirement.
» Confirm SSH connectivity from another machine on the LAN using OpenSSH (*nix) or PuTTY (Windows)
» Install and configure the ported version of OpenBSD's PF packet-filtering, stateful firewall. You can take a look at pf.conf for an example of what your PF configuration file might look like. Also, two great sources for information pertaining to PF are the PF User Guide and Peter Hansteen's Firewalling with OpenBSD's PF packet filter. Thanks for the resource Peter!
» Install and configure any other software that you would like. I recommend the Squid caching-proxy (installing as a reverse-proxy is nice too), Snort IDS (Intrusion Detection System), ClamAV (antivirus) with vectoring through your firewall, Bruteforceblocker (SSH bruteforce blocker), and Snarf (web interface for Snort logs).

Craig McLean was kind enough to let me integrate a how-to article on the same topic into this one. We've agreed to post some of his article here. Please realize, he, like I, wrote this article from memory. If you find any errors in it, please let us know. What follows is taken directly from his howto.

Things to decide
You will need to decide what you want your internal network to look like when this is over, and which machines should have access to what. This is not as complex as it sounds but it benefits us to work it out in advance. In this guide I will use the following: ( to Will be the internal network. Will be the firewall's internal IP address. ( to will be assigned to a DHCP range.

Things to know
» You will need to know what your internal- and external-facing interfaces and IP addresses are.
» You will also need to know the IP address(es) of the DNS servers provided by your ISP.
» The FreeBSD device name for your internal/external interfaces. These are named like so: The name of the driver used for the device followed by a number. This number is typically 0 (zero), but if you have multiple devices using the same drivers, each device will have a unique number starting at zero and counting up. For example, two Realtek based NICs will apear as rl0 and rl1. lo0 is your loopback device (IP If you've configured pflog to monitor your firewall, you'll see pflog0 here also. (John)

In this guide, I'll use the following:
» "xl0" will be my internal interface.
» will be my internal IP address. Internal hosts will have to route packets through this.
» "dc0" will be my external interface.
» will be my internet-facing IP address, used for machines in the outside world to connect to me.

You may not know your external IP yet, but once the install is complete you should use:
# ifconfig -a
to find it out.

If the IP assigned by your ISP is dynamic, you may need to setup DHCP on your external interface. Use dhclient for this. Also, while using DHCP on your internal network is more user-friendly, static IP addressing works just fine too. It can also make security audits more straightforward. (John)

Setting up the System
There is a really important file on your new FreeBSD machine. It's called /etc/rc.conf. In here you will put information on a variety of things. The hostname of the system, IP addresses, the services you want to be started when the system boots, and much more. You should take the time to have a look at it before we move on, and while you are there - make a backup copy!
Add a User
If you didn't do this during install, you should add a non-root user which you can use on a day-to-day basis. This can be done with the command:
# adduser
Make sure the user is in the group "wheel". This is a special group which contains all users who can become "root". If you find 'su' rejecting you, it's probably because you are not a member of the "wheel" group.

The pw command can also be used to add/modify/delete users and groups. (John)

Set up OpenSSH
OpenSSH (Open Secure SHell) should be your weapon of choice when connecting to your new FreeBSD host. It's secure, included by default with the OS, and there are any number of clients you can use to connect to it. Linux machines will have ssh by default, windows users can get hold of PuTTY (

OpenSSH can be enabled on FreeBSD by editing /etc/rc.conf and making sure you have the following:
in there.
Your machine will be on the internet, and people will try and get in. One of the ways they will do this is to try to guess usernames and passwords, which ssh uses by default. If you don't absolutely need ssh from the internet, make sure you only listen for connections on the internal interface. Do this by editing the ssh daemon configuration file which lives at /etc/ssh/sshd_config and make sure you have
in there, replacing with the internal IP address we decided on earlier.

Now you can run
# /etc/rc.d/sshd start
to start the service.

If you decide that you need ssh access from the outside world, you should disable password-based access and instead use publik-key authentication. Google will tell you how!

Setting up Firewall and NAT
Primarily, we want this system to be protected from bad guys on the internet by using firewalling, and share out our internet connection to other equipment on our network using NAT (Network Address Translation).

The Firewall
While Craig covers using IP Filter here, I will append a tutorial for using PF when I get the chance. For now, you can refer to the PF Guide ( and the sample configuration file that i've attached (pf.conf). (John)

First, let me point you at another great URL, it's the renowned "ipf HOWTO": Keep it to hand as we go through these steps.
In a minute, "in" and "out" are going to have very specific meaning, but let's not worry about that yet. Logically, we want to do the following:
» Allow internal IP traffic to the firewall machine.
» Redirect (where necessary) internal IP traffic to the internet.
» Redirect replies to internal traffic back to individual systems.
» Allow machines on the internet access to certain ports/services on the firewall.
» (maybe) Redirect access from machines on the internet to other machines on the local network.
» Block everything else.
First we need to enable ipfilter. That needs the following in /etc/rc.conf

This should be pretty self-explanatory, and the first thing to note is the location of the rules file, /etc/ipf.conf. This is where all our rules will live.
From here onwards, "in" and "out" need to be used very carefully, as they refer to "in" and "out" of a specific interface. Keep this in mind as we go on.
We decided earlier what logic we wanted, and can now translate that into rules:
# First, deny everything unless specified.block in on xl0 # Our internal interfaceblock out on xl0block in on dc0 # Our external interfaceblock out on dc0# Allow our internal network to come into the internal interfacepass in on xl0 from to any# Allow our internal interface to talk to the internal networkpass out on xl0 from to any# Allow tcp or udp from our external interface outwards to anywhere, keeping# a "state table" of connections and assembling fragmented packetspass out on dc0 proto tcp/udp from any to any keep state keep frags# Allow "ping" and its friends out from the external interfacepass out on dc0 proto icmp from any to any## Services## We're going to be running a web server, so we need port 80pass in on dc0 proto tcp from any to any port = 80 flags S keep frags keep statepass in on dc0 proto tcp from any to any port = 443 flags S keep frags keep state# Likewise sendmail, eventually. Leave it commented for now, though.# pass in on dc0 proto tcp from any to any port = smtp flags S keep frags keep state# pass in on dc0 proto tcp from any to any port = smtps flags S keep frags keep state

Those are the basics. You can start the firewall, using these rules, by issuing:
# /etc/rc.d/ipf start
If you change the rules, and want to reload the firewall tables, you can use:
# ipf -Fa -f /etc/ipf.conf
which translates as "Flush all, read new rules from file /etc/ipf.conf". If you want to clear out your firewall rules just use:
# ipf -Fa
To view all rules for inbound packets:
# ipfstat -i
and outbound:
# ipfstat -o

The 'ipf' functionality in FreeBSD is huge. This has only just scratched the surface of what is possible, or desirable. There's more info in the manpages, and at the link at the beginning of this section. I strongly suggest you take a look at both.

Warning: Think very hard before changing firewall rules if you are connected over TCP/IP. You may find if hard to recover if you get it wrong, and suddenly find yourself disconnected :-)

Next we want to set up Network Address Translation for other devices on our internal network. NAT allows many internal clients to share one internet address.
To do this, we need to add some more lines to /etc/rc.conf:
Pretty much like the firewall stuff, but this time the rules are in /etc/ipnat.rules.
NAT is really easy to set up. We want to allow anything on to use the internet, so our rule is:
map dc0 -> dc0/32 portmap tcp/udp automap dc0 -> dc0/32 proxy port ftp ftp/tcp
The first line maps internet access outbound on dc0 to appear from "dc0/32", which is shorthand for "the IP address currently associated with the interface dc0".
The second line will proxy outbout ftp access. This is necessary if you don't want to have to use passive ftp all the time because the ftp protocol sucks.

To get ipnat up and running, do:
# /etc/rc.d/routing start# /etc/rc.d/ipnat start

At this point, any client on the network which has a netmask of or stricter and as its router should be able to access the internet, with its packets being "mapped" by the NAT setup on the firewall machine.

DHCP Server Setup
The final step in the initial setup of your system will be to provide your clients with DHCP information. This allows centralised management should things change, and automatically assigns IP addresses (and more importantly, gateway information) to clients. We're going to allocate from to for clients...
To do this, we will use ISC's DHCPD from the ports collection.

# cd /usr/ports/net/isc-dhcp3-server# make

From the menu, select whichever options you want (I'd recommend at least PARANOIA and JAIL)
# make install# cd /usr/local/etc# mv dhcpd.conf.sample dhcpd.conf

Then edit the dhcpd.conf file, so it looks like this:
ddns-update-style none;log-facility local7;shared-network Dynamic-4-subnet {option routers;option domain-name-servers nnn.nnn.nnn.nnn;subnet netmask {range;}

You will need to substitute nnn.nnn.nnn.nnn with your ISP's domain name servers.
Then ensure /etc/rc.conf contains:
and start the dhcp server using
# /usr/local/etc/rc.d/ start

Thanks Craig, I appreciate the help. While my home network is a little different than Craigs, the same still applies. Here is how mine is setup:
» Cisco uBR900 cable modem provides connectivity to the internet.
» The modem is connected to my firewall. The WAN IP on the firewall is assigned by DHCP from the modem.
» The LAN network is and static (no DHCP)
» My firewall connects to a 24port switch. This is connected to a 108Mbps 802.11g D-link WAP and an 8port gigabit switch. The WAP has a static IP, but provides wireless access through DHCP.
» My firewall provides no internal protection. All internal traffic moves unprohibitted by the firewall. This includes outbound traffic also. While this may not be the most secure, it is definitely easier to manage. I don't have to add firewall rules everytime I want to access a new service.

Your setup may be different also. It's all personal preference.


Step 6: Packet Prioritization

Packet Prioritization with ALTQ
If your WAN connection stays fairly saturated (with things like bittorrent), then I'm sure you've experienced your fair share of timeouts, lag, or slow page loads. Packet prioritzation offers a solution to this problem. Instead of spending $100+ on a router that has this feature, you can instead use ALTQ with PF to accomplish the same thing.

ALTQ is very easy to setup. The most complicated thing you have to do is recompile your kernel. Don't worry, it's much easier than you think. Just follow my instructions, and you should be fine. A new kernel is required, because ALTQ support is disabled by default in FreeBSD.

Adding ALTQ support to your kernel
To begin, read Building and Installing a Custom Kernel thorougly. After you read that, read Enabling ALTQ.

I'll be using the "new" method. After duplicating the GENERIC kernel configuration file, edit it with your favorite editor (pico is great for beginners). Now, add the folowing lines to the end of the file:
#ALTQ OPTIONSoptions         ALTQoptions         ALTQ_CBQ        # CLASS BASES QUEINGoptions         ALTQ_RED        # RANDOM EARLY DETECTIONoptions         ALTQ_RIO        # RED IN/OUToptions         ALTQ_HFSC       # HIERARCHIAL PACKET SCHEDULERoptions         ALTQ_PRIQ       # PRIORITY QUEUINGoptions         ALTQ_NOPCC      # REQUIRED FOR SMP BUILD
Now save the file (I called mine FIREWALLKERNEL), then follow these steps (from the handbook) to compile it:

1. Change to the /usr/src directory.
# cd /usr/src
2. Compile the kernel.
3. Install the new kernel.
# make installkernel KERNCONF=FIREWALLKERNEL
If everything works, your new kernel is ready to use. FreeBSD is even kind enough to place the new kernel in your boot path. All you have to do is reboot your system (`shutdown -r now`). Now, you should have ALTQ support compiled into your kernel. Our next step is actually configuring ALTQ

Configuring ALTQ
ALTQ supports two kinds of packet prioritization: class-based (CBQ) and priority-based (PRIQ).

Class-based queueing divides trafic into "classes". A specific portion of your overall bandwidth is then allocated to each one of these classes.

Priority-based queueing, like it's name suggests, assigns priorities to packets. The packets with the highest priority are processed first.

There are also a few additional features that you have at your disposal: random early detection and explicit congestion notification (ECN).

Random early detection, or RED, calculates the average queue size, then drops or forwards packets depending on the level of congestion. If the average queue size is above a maximum threshold, all packets will be dropped. If the queue size is below a minimum threshold, no packets will be dropped. Anywhere between these thresholds, and packets will be dropped depending on how close the queue size is to the upper and lower thresholds.

Explicit congestion notification, or ECN, sets a flag in packets to notifiy hosts of network congestion. When a host that supports ECN receives a packet marked with this flag, it responds by throttling back it's activity.

I chose priority-queueing, because my network sees a large variety of different types of traffic. Priority-queuing uses numbers 1 through 15 to prioritize traffic, number 1 being highest priority. In my PF configuration file (pf.conf), I assigned a default priority to number 10. This means that any traffic that matches my firewall rules and is NOT given a priority will default to priority level 10. I then gave bittorrent a priority level of 15. By doing this, I am able to have bittorrent running non-stop on my network, without any noticeable increase in latency or throughput. I also gave SSH a high priority of 1, because of its time-critical nature. Here is what my PRIQ configurations look like ($int_if is my internal interface, device rl0; and $ext_if is my external interface, device dc0):
altq on $int_if priq bandwidth 100% queue {std, ssh, bt, http, p2p}altq on $ext_if priq bandwidth 5Mb queue {std, ssh, bt, http, p2p}queue ssh       priority 1      priqqueue http      priority 2      priqqueue std       priority 10     priq (default)queue p2p       priority 13     priq (red, ecn)queue bt        priority 15     priq (red, ecn)
Notice my "bandwidth" options on the first and second lines. I set the ALTQ queue size on my external interface to 5Mb. Although my external interface may be connected at 10Mbps, I am only allotted 5Mbps by my ISP. This is important, because packet prioritization relies on the level of saturation on an interface to determine when to start queuing packets. You'll notice I also assigned 100% of the bandwidth on my internal interface to ALTQ. This means that all traffic flowing through my internal interface will have 100% of its 100Mbps bandwidth.

Now that I've determined my priority levels, it's time to actually assign them to my firewall rules. This is very easy. Simply add "queue <queue_name>" to the end of any rules that you would like to assign to the priority level identified by <queue_name>.

And that's it. Packet prioritization is that simple. Leave me a comment to let me know if this helps anyone. It has definately helped me.

I've attached a revised version of my pf.conf that includes ALTQ configurations.


Step 7: Conclusion and Where to Find Help

You are not limitted to these utilities. FreeBSD has a vast collection of battle-proven security packages. Have a look at for the list.

If you experience frequent power surges, power outages, or even if you don't a UPS (Uninteruptable Power Supply) can save you many headaches. FreeBSD doesn't like being shutdown instantaneously. Often times, this leads to corrupted data. While most of the time (in my experience atleast) this can be fixed by running `fsck` in single-user mode with your disks unmounted, a UPS will eliminate this problem alltogether. Unless your power goes out for a prolonged amount of time, a UPS will provide reliable power to your firewall to keep it running smoothly. There are two different types of UPS's: offline (or standby) and online. Offline UPS's provide power from the outlet until they sense a power outtage, in which case they switch over to battery power. Online powersupplies have a zero switchover time (the amount of time it takes between loss of mains power and when stable power is supplied by the UPS) because they use inverters. Online UPS's are a little more expensive than offline UPS's, but more reliable. Offline UPS's will work fine though, so long as they have a low switchover time.

Bastion hosts and bastard systems
Keep in mind that the less software that you install, the more inherent security your firewall will enjoy. More software means more places for hackers to find vulnerabilities. By installing JUST a firewall, we would have a bastion host. Because it is more cost-effective to combine the firewall with the IDS, IPS, and auditing software, we are not creating a true bastion host -- more like a bastardized version of one.

Who's knocking down the door?
Don't be suprised to see attacks within minutes of placing the firewall on the internet. This does not mean that someone is intentionally trying to hack into your network. There are literally THOUSANDS of zombie computers out there that mindlessly probe the internet looking for a system to call their own, or worse, destroy. Aren't you glad you have a firewall?

My record for intrusion attempts after placing a firewall online is 3 minutes. In my experience, the most disturbing attempts are SSH bruteforces. A zombie computer portscanned you and found that you're running the SSH service (should you decide to allow WAN access). If someone were to gain access through SSH, the effects could be devastating. This is why your most important security measures should be placed here. If you're not using RSA/DSA pre-shared keys (why aren't you?), then at the very least, make sure your login password is extra-long, and contains an overzealouz combination of letters, numbers, AND symbols. Perhaps the dumbest thing you can do is allow root access to SSH. This would be like spamming the planet with your social security number. If need be, you can login as a normal user, then `su` your way to root.

Do I have a false sense of security?
If you don't trust your firewall, you can perform a quick and easy portscan on yourself by pointing a browser protected by your firewall to There you should find ShieldsUp!, a popular (and basic) security assessment tool. If you listen to the Security Now podcast with Leo Laport, you may have heard ShieldsUp! mentioned.

The best form of security auditing is by using a tool like Nessus. Nessus can be used to perform a MASSIVE assortment of security probes. You'll find Nessus in your ports collection, and at

The FreeBSD Handbook is the single-most important resource when working with FreeBSD. Just point your browser to and click on "Handbook". Google is also another valuable resource. The best (and most enjoyable IMO) way to learn how to use FreeBSD, or any flavor of Linux or Unix, is by doing the research yourself and diving right in. You'll screw your system up, curse everyone and their mother, and possibly become an alcoholic because of it, but you'll be that much more elite once you figure it out. As a last resort, try some the IRC channels on Dalnet or Freenode. When resorting to chatrooms, be expecting insulting comments and a few "RTFM"s.

Other uses
I also build a NAS (Network Accessible/attached Storage) device using a more modern AMD K8, 512MB of PC3200 DDR-RAM, and a few gigabit ethernet NICs. This system is more than enough to provide reliable streaming media, file serving capabilities, and SVN repositories to anyone with wired, wireless, or VPN access to our LAN. We've even setup dynamic DNS services to provide internet access to our media through a custom web interface. Eventually, we will release the MyNAS project to provide a user-friendly interface to the NAS and an out-of-the-box file-sharing community.