I added some tips on adding firewall rules with ipfilter.

IP Filter – an alternative firewall and NAT to ipfw/natd

This article is now outdated.  For FreeBSD 3.* and ipf 3.3.3, see Installing IP Filter 3.3.3

See also IP Filter – second time around and Adding
ipnat to FreeBSD 3.*

You may have seen the problems I was having with natd and ipfw.
  It was suggested by by Darren Reed that I drop ipfw/natd and try IP
.  I decided to do so.  For a trial at least.  It should also be
mentioned that Darren is the author of IP Filter.

IP Filter

The main webpage is http://coombs.anu.edu.au/~avalon/.
  See their list of mirrors for the latest source.  It basically does the same
thing as the natd and ipfw combination, but it seems to do it better.
  This is based solely upon my first impressions.  However, like most ports, the
documentation on how to install it is minimal and open to some interpretation.  I
have listed the steps I took.  Hopefully, they’ll work for you too.

Installation | NAT |
Removing natd/ipfw | Adding Rules | Conclusions

One of the best how-to guides for ipfilter is at:



I followed the instructions supplied in INST.FreeBSD-2.2 and used the LKM
(Loadable Kernel Module) option as the other option (kernel install) is unsupported.

will be installing a new kernel.  I named my new kernel IPFILTER.
  You may wish to name your kernel something else.  Keep that in mind when you

obtain the source

As mentioned above, use the http://coombs.anu.edu.au/~avalon/
site to obtain your source code.  I downloaded my file and place it in the /usr/ports/net
directory.  Then I did the following to uncompress and extract the files:

  1. cd /usr/ports/net
  2. gunzip ip-fil3.2.9.tgz
  3. tar -xvf ip-fil3.2.9.tar
  4. cd ip_fil3.2.9

prepare a kernel

Prepare, but don’t yet compile a new kernel.  Follow these steps to do this:

  1. cd /usr/src/sys/i386/conf/
  3. /usr/sbin/config IPFILTER

We will compile this kernel later on.  The above steps merely create the kernel
file which will be modified by the  IP Filter make.

make IP Filter

  1. cd /usr/ports/net/ip_fil3.2.9
  2. make freebsd22 IPFILKERN=IPFILTER
  3. make install-bsd
  4. FreeBSD-2.2/minstall

Step 3 may have to be done as root.  Step 4 must be done as root.

build a new kernel

You should now build the kernel you prepared above.

  1. cd /usr/src/sys/i386/conf/
  2. /usr/sbin/config IPFILTER
  3. cd ../../compile/IPFILTER
  4. make depend
  5. make
  6. make install

reboot to install the kernel

In order for the kernel to be installed, you need to reboot.  This command will
do it for you:

shutdown -r now

load the module

After the new kernel boots, issue the following command to load the module:

su-2.02# modload /lkm/if_ipl.o
Module loaded as ID 0

su-2.02# modstat
Type     Id Off Loadaddr Size Info     Rev Module Name
DEV       0  79 f3c86000 0031 f3c90248   1 IP Filter v3.2.9


For a definition of NAT, see Network Address Translation.
  I’ve summarized what I did based on the instructions supplied in the file  NAT.FreeBSD.
  The following numbered sections are extracted from that file.  Please refer to
the next section for a list of other steps I performed which were not included in the

NOTE: The instructions supplied with IP Filter make reference to /etc/sysconfig
which has been replaced by /etc/rc.conf.

1. Load the kernel module

We did this manually above.  In order for it to run at boot-time, you should add
the following line to /etc/rc.local (NOTE:  /etc/rc.local is
deprecated; use /usr/local/etc/rc.d/ instead; see Starting
stuff at boot time
and Installing IP
for an example):

modload /lkm/if_ipl.o

2. Setting up the NAT Rules

Rules for IP Filter are stored in the file /etc/ipnat.conf
I took what I found in /usr/ports/net/ip_fil3.2.9/rules/nat-setup as the basis
for my NAT rules.  Here they are (these may or my not be my real numbers):

map ed0 -> portmap tcp/udp 10000:40000
map ed0 ->

Please note that the above example differs from that supplied in the
file.  The second line does not contain the portmap keyword.  I could
not get the rules to load otherwise.

3. Loading the NAT Rules

The above rules need to be loaded everytime the computer reboots.  This can be
done by putting the following line in /etc/rc.local (NOTE:  /etc/rc.local
is deprecated; use /usr/local/etc/rc.d/ instead; see Starting
stuff at boot time
and Installing IP
for an example):

ipnat -f /etc/ipnat.conf

You can view the loaded rules by issuing the following command:

ipnat -ls

I have also supplied my NAT rules for those that may need
an example.

As for your firewall rules, I suggest you start with the contents of the Rules
directory and use either BASIC_1.FW or BASIC_1.FW as the basis for
your rule set.  Also note that BNF contains the rule syntax.

4. Enable Routing between interfaces

The instructions say you should do this:

sysctl -w net.inet.ip.forwarding=1

But you can achieve the same thing by using /etc/rc.conf.  Look for the
following section and ensure that the values are as shown.

### Network routing options: ###

5. Static Routes to Subnet Ranges

The instructions want you to set up the following routes.  I didn’t do this and
it still worked.  I’m not sure what I’m missing.

route_foo=" -netmask 0xf0000000 -interface"

6. Make sure that you have your interfaces configured

In /etc/rc.conf, you should have someething which looks like this:

network_interfaces="fxp0 fxp1"
ifconfig_fxp0="inet netmask"
ifconfig_fxp1="inet netmask"

Removing natd/ipfw

Prior to installing IP Filter, I was running ipfw and natd.
  My first attempt failed.  I think it was because I was still running those
programs.  So I made the following changes in order to get IP Filter

  1. removed the "options IPFIREWALL" and "options IPDIVERT"
    from my kernel.
  2. changed firewall_enable=YES to  firewall_enable=NO in /etc/rc.conf.

Adding Rules

The IP Filter examples
are highly recommended reading.  Of note are the sections on NAT and Rule Groups.  In
short, if you do this, you will Flush existing rules and add the rules contained in the /etc/ipfrules:

ipf -Fa -f /etc/ipfrules

TIP: Another good thing to try is to add the rules, wait a bit, then restore the
original rules.  This ensure that you haven’t locked yourself out of your box.  
This is very useful when working remotely. 

ipf -I -Fa -f /etc/ipfrules 

ipfilter has two rule lists, the active list and the inactive list.  ipfilter
always works against the active list.  The options in the line above, as taken from
the man ipf page are:

-I     Set the list to make changes to the inactive list.

-F     This option specifies which filter list  to  flush.
       The  parameter  should  either  be "i" (input), "o"
       (output) or "a" (remove all filter rules).   Either
       a single letter or an entire word starting with the
       appropriate letter maybe used.  This  option  maybe
       before,  or  after, any other with the order on the
       command line being that used to execute options.
-f <filename>    This option specifies which files ipf should use to
       get input from for modifying the packet filter rule

So the above command tells ipfilter to load your rules into the inactive list but first
flushes any rules which were already there.

ipf -s; sleep 10; ipf -s

The following man page extract explains the above command.

    -s     Swap the active  filter  list  in  use  to  be  the
           "other" one.

The above command line tells ipfilter to swap the active and inactive list.  This
invokes the rules you added with the first command.  It then tells the system to
sleep for 10 seconds.  You should type a few characters and see if they are echoed.
  If they are, you haven’t locked yourself out of the system.  But just in case
you have, the next command tells ipfilter to swap the active/inactive lists again.  
This puts you right back where you were before.

Rule Groups

The concept of a rule group is at the heart of understanding how IP Filter
works.  Rules can be grouped together according to logical function.  The
documentation also states that groups make for more efficient rule processing.

group is identified by a unique group number.  A new group is created by including a
head statement such as the following:

block in log on ed0 all head 100

The above rule declares that all incoming packets on ed0 will be processed
using group 100.  The default action for this group is to block all.  Note: that
only packets which match the above rule will be processed by rules in group 100.

If we wish to allow people to access our webserver, we would add a rule which looks
like this.

pass in quick proto tcp from any to any port = WWW keep state 
                                                          group 100

Default rules

IP Filter comes with a script which will create some default blocking rules
for you.  Read rules/firewall for details. Here’s what I did to invoke
those rules:

  1. cd /usr/ports/net/ip_fil3.2.9
  2. ./mkfilters > rules/mkfilter_rules
  3. ipf -f rules/mkfilter_rules

To view the rules, try the following:

ipfstat -hio

Firewall rules

But for real protection, you want the firewall rules.  I started with the ones
provided in rules/BASIC_1.FW.  Then I moved to rules/BASIC_1.FW
because I couldn’t get some of my services to run.  I struggled for 2 days trying to
get traceroute to work.  I gave up.

(see below for additional information).


These conclusions are based on 3 days of working with IP Filter.  I have
no doubt they are biased and based upon my lack of experience with both the product and
Unix.  I like IP Filter.  It loads rules much faster than ipfw.
  And the concept and use of rule groups is quite good.  For a commercial
environment, I think IP Filter would be better than ipfw.  I also
feel that better protection can be obtained by using IP Filter.

I found it very
difficult to find out how to load rules, display the rules, and view the accounting
statistics.  Once you know the commands, they are easy to do.   That said, I
found it difficult to obtain this information from the documentation.  Hopefully, the
information I’ve provided above will help. 

See the notes below for more information

traceroute solved (added on 9 November 1998)

I’ve been using the latest beta of IP Filter and doing some testing with the
help of the author.  Darren has fixed the trace problem I initially encountered.
  The utility I was using to do a trace used short packets which were being removed
by the block in log quick all with short rule.  This fix will be available
with IP Filter 3.2.10.

some block packets (added on 15 November 1998)

I am now using IP Filter for my firewall.  The only outstanding problem is
related to packets which are being blocked.  I’ll have to investigate this further
now that I know how to interpret the information in the log..

Tip for updating your rule set remotely (added on 16 November 2000)

When you are changing your rule set, there is always the chance that you
will lock yourself out of your box.  That’s OK if you’re at the console, or if you
can just walk over and reset things.  But that’s not very nice if the box is several
hours away by car or plane.  So here’s a tip on how to change the rule set, do a
short test, and make sure you’re not locked out.  This tip came to me from David S.
Madole of Optimized Micro Devices back in April 1999 via the ipfilter mailing list, but
that message is still in my mailbox.

modify /etc/ipfrules
ipf -I -Fa -f /etc/ipfrules
ipf -s; sleep 10; ipf -s

In this example, you modify the rules.  Then you load those rules into the
inactive rule set.  Then you swap the rule sets, wait 10 seconds, then swap them
back.  During that ten seconds, you can type a few characters to make sure you get
echoes, then type ^C.

Hope this helps.

Leave a Comment

Scroll to Top