Free Firewalls Configuration guide

These pages are geared towards building your own firewall box. Since it's rather difficult to make a recipe for the "perfect firewall", I'll concentrate on giving you general principles first. Some small examples will follow at the end. Every site is different, so be sure to take those examples, and customize them to your own situation!

The important thing to keep in mind is that this only gives you basic "secure your network" type information. You should also actively seek out, and stay current in, security issues for your specific platform.

Page sections

Know your networking

An important part of building a firewall is knowing not just how your network is laid out, but how networking works in general.

Information comes across the network in "packets". These packets can be of very different types. You may choose to allow a certain group of types through, or just a select few, or even just one type of packet. So it is imperative to understand networking at a fundamental level first.

You need to understand the basic packet layers before continuing

Conceptual Firewall Types

Most people think of "a firewall" as a single box. Actually, it can be a whole group of systems working to defend your network. But we'll concentrate on the "single box" concept.

There are still multiple types of "single-box" firewalls:

  1. proxy firewall
  2. NAT firewall
  3. transparent firewall
Generally speaking, though, all single-box firewalls have a separate "outside" and "inside" physical network interface. Some may have more than one of each.

Proxy firewall

A proxy firewall runs special software written to allow specific programs to function. For example, an http proxy is written to specifically allow http access, and only http access, through it.
It also requires special action to be taken at the user level. For example, in netscape, you have to specifically Edit the Properties dialog, go into "Advanced", then "Proxies", and make the appropriate entries there.



NAT firewall, AKA "Masquerading"

"NAT" stands for Network Address Translation. The idea is that you have a special range of addresses for your internal machines that is not normally reachable via the internet. The firewall will translate those addresses into a different, globally reachable IP address if the internal machine wants to make an outbound connection. This global address may be the firewall's own IP address, or it may be a "virtual" address that does not have a physical machine behind it at all.
Usually, home firewalls will use their own IP address, since there is only one IP address available for use. Business firewalls, on the other hand, should normally use a virtual address. This way, the address of the actual firewall is not shown to third parties out on the net.

A NAT firewall may have filters to only allow outbound packets on certain ports, or it may simply choose to allow all outbound connections.


The disadvantages of this sort of mechanism are:
  1. There is no additional security beyond "allow this type of traffic". Once an internal client connects via an allowed protocol, anything can happen within the bounds of that protocol
  2. There is no way to allow for special protocols that require a return connection to be made.
  3. If you wish to restrict certain types of protocols, you can only limit access to certain ports. On the one hand, this is too restrictive, because internal folks may not be able to accesss webservers on non-standard ports. And at the same time, this is too permissive, because there may be a disallowed service running on a non-standard port on the outside, and your internal folks will be able to access it in this case.

Transparent firewall

A "transparent" firewall is an amalgam of a proxy firewall and a NAT firewall. An internal machine only has to know where to send packets to reach the outside, similar to a NAT firewall. However, the firewall may "transparently" invoke proxy-like mechanisms on certain traffic, for security purposes, rather than just blindly forwarding it through. The internal machines may or may not have a private IP address range.



Securing the machine

Before you do anything else, especially before connecting it to a network, you should make sure your prospective firewall machine is secured.

One way is to get an operating system that is explicitly designed for this. For example, one of the "firewall on a floppy" distributions, like (Linux 2.2.X based. I like the description of "More than one floppy is bloatware" !)

But in case you like to roll your own, here's some guidelines.

Ideally, you should turn off ALL services. A "netstat -an | grep LISTEN" should show NO listening ports.

Sometimes, it is neccessary to enable particular services, like ssh. If so, you should configure those services to only accept connections from specific hosts whenever possible. Ideally, you would only run those services on the "internal" side of the firewall.

Additionally, you should remove all unneccesary software from the machine. If you are running a package-based OS, like Solaris or Debian Linux, you should look through the list of installed packages. If you dont know what a package does, either learn it, or remove it. If you know a package is not neccessary for firewall operation, remove it.
You should also remove the setuid permissions of any setuid-root programs. If you need root access to do something, use root to do it!

The ultra-paranoid should at this point also make a point of taking checksums of every single file on the machine, and putting them somewhere safe. You should then periodically take another set of checksums to compare, to verify that your machine has not been tampered with. To improve the tamper-proof rating, put the original checksums and program on read-only media like a floppy or CD-R, and only run the program from this read-only media.

Ruleset guidelines

Whatever type of firewall you are building, you have to have a set of rules to determine what type of traffic to allow through. The original adage for configuring firewalls is, "Anything that is not explicitly allowed, is denied". This is still as true as it ever was. Decide which specific services you want to allow, and only allow those services.

If you are wondering whether or not you should allow a new type of service, consider that the more complex a service is, the more likely there are to be security holes somewhere waiting to get you.

The simplest firewall ruleset nowadays will probably look something like the following:

Source IP Dest IP Protocol Action
INTERNAL Any http(tcp) ALLOW
DNS-server Any DNS(udp) ALLOW
[Any] [Any] [Any] [IMPLIED REJECT]

You would additionally want some way of rejecting packets that are supposedly from one interface, but coming in on another. This is protecting yourself from "IP Spoofing"

Note that the "protocol" field is actually misleading. Firewalls arent smart enough to look at a packet and tell "This has HTTP data in it". And even if they were, doing that kind of analysis would slow things down too much.They can only tell "This has TCP data in it with a destination of port 80". So "http" in this case is really just an alias for "TCP, port 80".

Also, the http line implicitly has TWO rules. One rule allows packets to go outbound. The other one says, "If there is an established TCP connection for this protocol, allow packets for that connection to flow inside"

On the other hand, ftp IS sometimes treated specially. Some firewalls have special logic to help ftp connections along, because FTP is a special case. FTP transfers involve TWO connections: a control connection, and a data connection. Originally, the control connection was established as an outbound connection, and the data connection was initiated by the server connecting back to the client. But these days, allowing any kind of inbound connection is a bad idea, so "passive", aka "PASV" FTP, is used. This forces both control and data connections to be outbound.

DNS is also a special case. It is different for a variety of reasons:

1. A lot of client machines dont do full DNS queries. They rely on a common server to handle caching. This turns out to be a good idea anyway, to minimize potential DNS attacks.

2. DNS is based on top of udp. Therefore, there is no "connection" to automatically allow DNS packets inbound. The outbound part is still simple, but the firewall may have to be somewhat smart to figure out when to let DNS packets back inside. Some firewalls do try to be "intelligent" about it, but this is not completely adequate.

3. Some old DNS name servers send queries out on the same port they answer queries on: UDP port 53. So at a high level, it would be difficult to look at a packet and say "This packet is a reply by a normal machine, to a query we sent out".

4. Since there is no "connection", if a packet for a particular UDP port on the inside is let through, the odds are it will get accepted by whatever is listening on your private, internal client machine. There still is the issue of matching port number(s), but it is much much easier for a malicious person to fake UDP packets than it is to fake TCP packets (primarily due to TCP sequence numbers)

Real live rulesets

FInally, here are two examples of the above policy, implemented by two popular firewall filtering drivers: ipchains, and ipfilter. I'll also attempt to give you some usefule OS-specific info that isn't directly part of the filtering.

ipfilter is a well-written STREAMS-based driver that runs on most UNIX variants like Solaris, and BSD... except Linux, because Linux doesnt have proper STREAMS-based networking.

ipchains is the Linux-specific filtering driver that comes with the standard Linux kernel these days.

ipfilter (Solaris, BSD, ....)

We assume that your internal network is a private class A, on the reserved network, on interface dnet0. Additionally, you have a caching DNS server at address

IP Filter ruleset (ipf.conf)
pass in quick on dnet0 proto tcp from to any port = 80 keep state
pass in quick on dnet0 proto tcp from to any port = ftp keep state
pass in quick on dnet0 proto tcp from to any port = ftp-data keep state
pass in quick on dnet0 proto udp from to any port = 53 keep state
#[Yes, DNS *sometimes* uses tcp also]
pass in quick on dnet0 proto tcp from to any port = 53 keep state
#(Manually block IP Spoofing )
block in quick on dnet1 from to any
#(Block attempts to reach PRIVATE net directly)
block in quick on dnet1 from any to
#(block fragmented packets )
block in quick on dnet1 from any to any with short
# Allow tcp-out from FIREWALL
pass out quick on dnet1 proto tcp from any to any keep state
# Allow udp-out from FIREWALL
pass out quick on dnet1 proto udp from any to any keep state

Do not forget the "quick" directive!. If you forget it, it will fall through to the next rule.

To enable NAT, you have to separately configure "ipnat.conf". A trivial one-line ipnat.conf might be

map dnet1 -> portmap tcp/udp auto
# If you want to enable ICMP (and all other non-tcp/udp protocols), add:
# map dnet1 -> 

You now have to turn on "IP Forwarding".

On Solaris, if you have multiple interfaces, ip forwarding should be on by default, due to /etc/init.d/networking. But just in case you want to do it by hand, you can use

ndd -set /dev/ip ip_forwarding 1
Either way, you should also create a script similar to the following in /etc/rc3.d/S01security to protect you from other nastiness:

case $1 in
        ndd -set /dev/ip ip_strict_dst_multihoming 1
        ndd -set /dev/ip ip_forward_src_routed 0
	ndd -set /dev/ip ip_forward_directed_broadcasts 0

Unfortunately, the best I can do for FreeBSD is offer you this third-party patch for rc.firewall. There's other good stuff at But note that BSD comes with its own "natd" which would presumably be used instead of ipfilter's own ipnat driver.


This next one assumes your INTERNAL interface is eth0, and your EXTERNAL interface is eth1

IPChains ruleset
ipchains -A forward -p tcp -i eth0 --dport www -j ACCEPT
ipchains -A forward-p tcp -i eth0 --dport ftp -j ACCEPT
ipchains -A forward -i eth0 -s --dport 53 -j ACCEPT

If you want to automatically do NAT/Masquerading, replace "-j ACCEPT", with "-j MASQ"

The "hard way" to turn on ip forwarding in linux, is to do

echo 1 > /proc/sys/net/ipv4/ip_forward
# (And then to protect from IP Spoofing)
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
echo 1 > $f
But if you're running Debian linux, you can just put
in /etc/network/options

There is a lot more to be said about how IP Chains works. It has a concept of named rulesets, aka "chains".

The default "chains", are "input", "output", and "forward", but you can name your own, and chain them in to one or more of the standard ones. To learn more, please follow the link to the ipchains web pages, at the top of the Real live rulesets" section

Quick-n-dirty ipchains "secure this box" rule

If you're in a bit of a hurry, and need to lock down a linux box (but still keep it net-functioning) RIGHT THIS SECOND because you have zero filtering enabled, try to remember this rule:
ipchains -A input -i eth1 -p tcp -y -j DENY
assuming you had NO rules defined already, because the -A means "Add".

The line is interpreted as follows:
For inbound packets -A input
On interface eth1 -i eth1
Protocol TCP, wanting a new connection -p tcp -y

This won't stop everything. After all, it doesnt even touch UDP at all! But it will stop all attempted TCP connections from "outside", assuming "eth1" is your external interface.

Quick-n-dirty ipfilter rule

Similarly, if you're in a hurry with ipfilter, you can put these two lines in ipf.conf, and block out most all incoming stuff:
[substituting the appropriate external-side device for "dnet1"]

pass out quick on dnet1 proto tcp from any to any keep state
block in quick on dnet1 all
#Note that this doesnt pass DNS, or ANY KIND of UDP!!

Then run " ipf -Fa -f ipf.conf", and the new rules should be in place.

Or if you're running Solaris, just run "sh /etc/init.d/ipfboot reload" to activate your new config.


Last, but certainly not least, comes the paranoia factor. When it comes to firewalls, and security in general, paranoia isn't just a state of mind; It's a way of life!

To sum it up: Trust no one. Trust nothing to work, unless you personally have seen it work.

The most immediately relevant part of this philosophy is that, once you have implemented some variant of filtering from above: VERIFY IT FROM OUTSIDE

(Is that clear enough, or do I need to emphasize it a little more?)

I apologise if there are any errors in the rulesets listed. Please email me if you find any problems with the rulesets here.

Additionally, if you are interested in SunScreen for solaris, sun has a "blueprint" on how to set it up. Or, you can read my much shorter SunScreen command-line guide

Or, if you want to get sneaky, and want a firewall without having a firewall... use ipsec to give you package filtering on a simple workstation that has IPsec on it (solaris 8 or later has it), without having to install a "firewall package".

Try dropping this ipsec.conf file into /etc/inet/ipsecinit.conf, and rebooting, if all you want is to allow ssh in/out, and DNS traffic.

Author: Philip Brown Site: