IPFW Firewall Explained

General Information

This guide helps you setup a simple firewall for any FreeBSD version (recent) that can load the firewall module.

Introduction

Why have protection? Computers on the Internet run the risk of being damaged or hijacked. Firewall software is a very powerful tool in fighting this. Having firewall software doesn’t mean that your safe. You will still have to update your system in order to fix security bugs and check for viruses. Although the latter isn’t much of a problem for Unix-like computers at the time of writing.

The goal of this guide is to setup a simple firewall for FreeBSD and explain certain details of the firewall, from the user point of view, while doing so. At the end of this guide you will have a firewall with a simple ruleset. The questions this guide will give anwsers to are:

  1. How packets are checked agains the rules.
  2. guide natd effects the rules and guide deal with those effects.
  3. guide setup statefull rules and why the can not be used with natd.

Related guide’s:

  1. Firewall Setup – A more complex firewall setup, that also includes a traffic shaper and network address translation (NAT). This particular guide lays the basis for the next guide.
  2. Traffic Reports – guide create traffic graphs with MRTG, IPA and IPFW.

Notes

The newer versions of FreeBSD can load the firewall software when this is required. Older versions of FreeBSD don’t have this ability and need to have a kernel compiles. You also need to do this with the newer version when you like to create more advanced rules, like logging of traffic shaping.

Summary

The firewall and the natd daemon are loaded by adding the following lines to /etc/rc.conf:

firewall_enable="YES"
firewall_quiet="NO"
firewall_type="/etc/firewall.conf"

The configuration file exists out of these rules:

# check ip packed agains state
add 100 check-state

# allow local traffic
add 160 allow ip from any to any via lo0 out
add 1010 allow ip from 192.168.1.0/24 to 192.168.1.0/24 via xl0
add 4980 allow ip from any to any in via xl0

# pass packets comming from internal NIC and us
add 2000 skipto 2100 ip from any to any via xl0
add 2000 skipto 2100 ip from 192.168.1.0/24 to any via xl1 out
add 2000 skipto 2100 ip from any to 192.168.1.0/24 via xl1 in
add 2000 skipto 2100 ip from 10.0.0.0/24 to any via xl1 in
add 2000 skipto 2100 ip from any to 10.0.0.0/24 via xl1 out

# deny spoofing
add 2010 deny ip from 10.0.0.0/8 to any in
add 2010 deny ip from 127.0.0.0/8 to any in
add 2010 deny ip from 172.0.0.0/12 to any in
add 2010 deny ip from 192.0.2.0/24 to any in
add 2010 deny ip from 192.168.0.0/16 to any in
add 2020 reject ip from any to 10.0.0.0/8 out
add 2020 reject ip from any to 127.0.0.0/8 out
add 2020 reject ip from any to 172.0.0.0/12 out
add 2020 reject ip from any to 192.0.2.0/24 out
add 2020 reject ip from any to 192.168.0.0/16 out

# stateful firewall
add 4990 allow tcp from any to any out via xl1 setup keep-state
add 4990 allow udp from any to any out via xl1 keep-state
add 4990 allow icmp from any to any out via xl1 keep-state

# reject (unreach host) outgoing so we know and don't have to wait
add 4997 reject ip from any to any in via xl0
add 4998 reject ip from any to any out via xl1

# deny incoming for stealth
add 4999 deny ip from any to any

Loading the Firewall Rules

The first step is about loading the rules. FreeBSD loads the rules during the boot process. It needs some information in order to load the rules. It looks for that information in /etc/rc.conf. Open it and the following lines.

firewall_enable="YES"
firewall_quiet="NO"
firewall_type="/etc/firewall.conf"

The firewall setup is done during the next boot, if firewall_enabled is true, by loading the rules as indicated by file_type. If firewall_quiet isn’t set or is set to NO, then the rules will be printed to the screen duing boot.

Configuring the Firewall Rules

The rules need to be written down in /etc/firewall.conf, since the previous section set ipfw up to load this file. This section explains first how the IP packets are passed though and matched against the rules, before we go into the rules.

IP packets are checked against the ruleset when they pass though the firewall. The man pages tell us that the number of times it passes varies between 0 and 4 times depending on the packet’s source and system configuration. In our case, that is without adjusting the default settings, it will pass though just ones. The packet is run from top to bottom and rules can have it skip a range of rules.

A rule tells what under which conditions the packet matches and what to do if a rule matches. You can specify the kind of packet, the source & destinaion IP adress range, the direction a packet is heading, though what NIC it needs to travel, and more. The first rules that it matches and allows, rejects (unknown host), or denies it determins whether it is crushed by the big hammer or if it’s allowed to pass through the firewall.

Stateful Firewall

The first thing on the agenda is to setup a security barrier between the Internet and this computer. The task is to allow desired packets by this computer. The stateful firewall is just the tool to use.

# stateful firewall
add 4990 allow tcp from any to any out via xl1 setup keep-state
add 4990 allow udp from any to any out via xl1 keep-state
add 4990 allow icmp from any to any out via xl1 keep-state

Stateful firewall is the art of having packets denied or rejected by the firewall, unless the IP packets belong to you. The firewall records certain information with these rules that allow it to see if a returning packet contains requested information or if it belongs to the other side.

# check ip packed agains state
add 100 check-state

This rule checks if the table contains information that tell it whether packets should be allowed to pass. It’s advised to have this rule early on in the firewall rules set as it can efficiently check and could lower the load on the firewall by quite a lot. The search, for a match between the packet and a rule, ends when this rule lets the packet pass and continues otherwise.

Network Adress Translation

Please skip this section if you didn’t compile your own kernel or have no idea what that is. This section is intented to be informational only and was added because that is the primary goal of this guide.

If this computer is a gateway for your LAN then you may need something like network address translation (NAT). NAT is a technique where packets with private IP address, that are non-routable, get the public IP address of the gateway before going on the Internet. This process is reversed on the way back.

# select traffic for natd
add 3000 skipto 3400 ip from any to any via xl0
add 3000 skipto 3400 ip from me to any via xl1
add 3210 divert 8668 ip from any to any
add 3220 skipto 3400 ip from any to me
add 3390 allow ip from any to any

Having these packets being registered by the stateful firewall wouldn’t work. Here’s what happened. On the way out the packets first go though natd and receive a public IP address and then they would be registerd by the stateful firewall. On their way back two things can happen:

  1. The packets first are checked by the stateful firewall. This then accepts the packet preventing them from going to natd and getting their private IP address. Thus they would have received their destination in the eyes of the packet. The gateway, of course, wouldn’t know what to do with it.
  2. The packets pass though natd again and recieve their private IP address. Then they are passed by the stateful firewall. This has no record of a private IP address and doesn’t let the packet pass.

The solution is a simple one: simply let Natd keeps record in much the same way as the stateful firewall does. If it has a record of the packet then it belongs to the network and should be allowed to pass, never to be recorded by the stateful firewall.

Deny Spoofing

# deny spoofing
add 2010 deny ip from 10.0.0.0/8 to any in
add 2010 deny ip from 127.0.0.0/8 to any in
add 2010 deny ip from 172.0.0.0/12 to any in
add 2010 deny ip from 192.0.2.0/24 to any in
add 2010 deny ip from 192.168.0.0/16 to any in
add 2020 reject ip from any to 10.0.0.0/8 out
add 2020 reject ip from any to 127.0.0.0/8 out
add 2020 reject ip from any to 172.0.0.0/12 out
add 2020 reject ip from any to 192.0.2.0/24 out
add 2020 reject ip from any to 192.168.0.0/16 out

Spoofing is a technique where crackers change certain information that can identify them. This can happen with the addresses in IP packets. The IP address ranges you see above are private IP addresses. This means that they are non-routable (Unless you use them). Therefore, the ruleset above blocks packets that have one of them set.

# pass packets comming from internal NIC and us
add 2000 skipto 2100 ip from any to any via xl0
add 2000 skipto 2100 ip from 192.168.1.0/24 to any via xl1 out
add 2000 skipto 2100 ip from any to 192.168.1.0/24 via xl1 in
add 2000 skipto 2100 ip from 10.0.0.0/24 to any via xl1 in
add 2000 skipto 2100 ip from any to 10.0.0.0/24 via xl1 out

You will most likely be using some private IP addresses. These packets can jump right over the spoofing block by setting up rules with the skipto command, as you see above.

Allow Local Traffic

Next are rules for that allow all traffic from and to the local LAN. There is no need to use natd or the stateful firewall here and doing so would put a strain on their resources. I have seen cases where heavy use of the LAN resulted in natd taking up 100% of the CPU. This will prevent that from occurring.

# allow local traffic
add 160 allow ip from any to any via lo0 out
add 1010 allow ip from 192.168.1.0/24 to 192.168.1.0/24 via xl0

Deny Everything Else

All other packets that goes on to the Internet are denied or rejected.

# allow traffic on the internal NIC
add 4980 allow ip from any to any in via xl0

# reject (unreach host) outgoing so we know and don't have to wait
add 4997 reject ip from any to any in via xl0
add 4998 reject ip from any to any out via xl1

# deny incomming for stealth
add 4999 deny ip from any to any

Final Notes

Using firewall protection is important because it provides a powerfull security that gives protection from attacks. Everyone should have one on each computer. Only the most basic stuff was discussed in this guide. The firewall may not be to your liking the way it is; however, I hope I’ve given enough guidance and support to make some changes for yourself. In addition, I’d like to encourage you to contact me, if you have questions or feedback about this guide.

This guide first appeared on my site http://www.kruijff.org/alex/FreeBSD/.

Speak Your Mind

*