IPFW Configuration Help


IPFW, which stands for IP FireWall, is an important (and sometimes hard to 'get right') part of a secure installation. In short, it can help to protect you from certain kinds of attacks by filtering out packets destined for certain locations. Even in *nix systems, some applications will listen for TCP or UDP packets on specific ports and bind to ALL IP addresses, without giving you the ability to shut this 'feature' off. Even 'inetd' is no exception to this. Further, you may want to enable actual filtering, such as only allowing incoming SMTP traffic from "known" IP addresses, and denying 'even the existence' of an SMTP server to everyone else. This kind of filtering can discourage those who might otherwise try to scan you for vulnerabilities, because they will often do an 'initial scan' to see who is listening on a particular port, and then do further probing if you appear 'interesting' to them.

On a Linux system, IPFW configuration is a bit different, but the principles remain the the same. On this page I provide examples written for FreeBSD, configured so that you can specify which services you want to expose to the outside world. The example here is also for a multi-homed system that uses ppp to dial into the internet via DSL. A cable modem connection would be slightly different, but only slightly. IPFW is not likely to be of any use if you are already going through some kind of router that has a built-in firewall, so if you have a NAT-capable DSL router with a built-in firewall, this probably does not apply to you. If you want your computer to BE the NAT-capable DSL router with a built-in firewall, you should definitely read on (and save yourself a little money while you're at it).

The following is a 'short list' of the things that need to be accomplished to get ipfw running on your computer. Although the documentation for FreeBSD states that you need to re-compile the kernel, this is not entirely so. You CAN re-compile the kernel to provide native ipfw support if you want, but there are at least 2 ways to accomplish the same thing without a kernel re-compile. The easiest method is to invoke ipfw as a kernel loadable module, by modifying the 'rc.conf' file. This is the method that will be discussed here.

  1. Use 'ifconfig' to determine which network adaptors are involved. One of these will be connected to the internet. For sake of argument, this will be 'xl0'. If 'xl0' is plugged into a DSL modem and you use 'ppp' to dial it, the internet connection will actually be 'tun0' (or similar). In this example, 'xl1' will represent the 'LAN' connection, which will have a fixed IP address 192.168.2.1/24 . It is assumed that both network cards are properly configured and working properly.
  2. Determine which services you want to allow unrestricted access to, and what their port numbers are. The file /etc/services contains a list of them. In this example, the services will be:
    Also, all inbound/outbound connections to ports greater than or equal to 1024 must be allowed so that FTP (and similar) protocols, non-privileged applications that open a 'listening' port, and normal TCP connectivity (which opens automatically assigned ports that are 1024 or greater) can function as expected. Ports 0 through 1023 are considered 'reserved' by the operating system and on a *nix system will typically require superuser access to bind to.
  3. Determine whether or not you want to filter outgoing connections. You may want to restrict all outgoing SMTP (port 25) connections so that they only connect to your ISP's mail server, in case someone ends up with an e-mail virus, or if you want to route all outgoing mail through a company SMTP server.
  4. Determine whether or not you want additional filtering on incoming connections. In some cases you might want to restrict access to a single IP or range of IP addresses, particularly if you are having trouble with a particular netblock. A good example would be to deny all access to SMTP that does not come from a forwarding mail server, or to block all access to and from specific ISP's or geographical regions to limit 'cracking' attempts or eliminate problems from port-scanning or 'denial of service' attacks.

You should also keep in mind, that the more rules you add, the slower your system response will be over TCP/IP. So the best way to handle things is to 'keep it simple' as much as you can, put the most permissive rules at the top of the list, and limit the total number of rules to something that is easily managed.

The Files

The contents of the various files are shown here. You can 'clip' the text out of the html text and paste it into the appropriately named file, modifying the text as needed for your operating system, and network settings.

Entries Added to '/etc/rc.conf'

FreeBSD uses a file /etc/rc.conf to determine which scripts in /etc/rc.d will load daemons, and what the settings will be. It is actually included by these scripts and so it merely sets up the necessary variables to tell the 'rc.d' scripts how to load the daemon (or whether to load it at all). For FreeBSD, the following entries will be needed:

firewall_enable="YES"
firewall_script="/etc/ipfw.conf.sh"

Firewall Script, '/etc/ipfw.conf.sh'

Using this method, you bypass the default 'rc.firewall' script and run your own script, which (in this example) is stored in '/etc/ipfw.conf.sh' (NOTE: make sure you set the executable bit!). If you prefer, you can choose one of the configurations from 'rc.firewall' and assign that value to 'firewall_type' and be done with it. However, in this example, we want more control over what is happening, and instead of modifying the rc.firewall script, we'll simply create one of our own.

For a system that has a DSL modem and uses 'ppp' to dial into the internet, the contents of '/etc/ipfw.conf.sh' might be:

#!/bin/sh
# the file /etc/ipfw.conf.sh - configuration script for ipfw

# already established connections continue going through
ipfw add 01000 allow tcp from any to any established

# local adaptors (not tun0 that is).  'xl0' is connected to the DSL modem
# for PPPoE.  'xl1' is the adaptor connected to the internal LAN.  You should
# change these to match your own system.  If you are not using 'PPPoE' then
# you should exclude the entry for the adaptor that is connected to the internet.
ipfw add 01100 allow all from any to any via xl0
ipfw add 01101 allow all from any to any via xl1
# don't forget the loopback interface or some things might break
ipfw add 01102 allow all from any to any via lo0


# udp access control (all adaptors)
ipfw add 02000 allow udp from any to any 1024-65535,domain,daytime,time,echo,discard,chargen

# allow udp access to any port when the packet is outgoing or 'fragment'
ipfw add 02001 allow udp from any to any out
ipfw add 02500 allow udp from any to any frag


# tcp access control - note that 'ftp-data' must be specified by port number '20'
ipfw add 03000 allow tcp from any to any http,https,ftp,20
ipfw add 03000 allow tcp from any to any 1024-65535,ssh,domain,telnet
ipfw add 03000 allow tcp from any to any daytime,time,echo,discard

# if you want services such as 'auth' 'pop3' or 'smtp' to be accessed by the outside
# world, consider uncommenting the following line
# ipfw add 03000 allow tcp from any to any auth,pop3,smtp

# outgoing TCP packets - no filtering at all
ipfw add 03001 allow tcp from any to any out


# icmp packets (ping).  'icmptypes' are listed based on recommendations from
# the FreeBSD handbook on ipfw.
ipfw add 04000 allow icmp from any to any icmptypes 0,3,8,11,12,13,14


# These next 4 entries are needed for VPN.  They can be removed if you won't be using it
ipfw add 04500 allow esp from any to any
ipfw add 04501 allow gre from any to any
ipfw add 04502 allow udp from any to any 500
ipfw add 04503 allow tcp from any to any 1023,1723
# note that '1723' was still mentioned here. That is in case you filter it elsewhere


# logging and denying
ipfw add 05999 deny log ip from any to any frag

# this next one is by default the last one.  You can choose a LARGE number if you
# like.  I chose '6000', you can pick anything up to 65535.  In FreeBSD the rule
# for '65535' is initially defined as 'deny all from any to any' when you load ipfw.

ipfw add 06000 deny all from any to any

Don't forget to mark your firewall script 'executable'; otherwise, you may be in for an unpleasant surprise. Also, it might be best ONLY to attempt ipfw configuration from the console. If you misconfigure ipfw remotely, you'll probably have to gain direct console access in order to fix it.

Hopefully this will be enough to get you started. It is basically how I have my system set up, and when I did a scan using the 'DSLReports.com' port scanner, it came up with no detectable problems. And with everything else working properly (mail, web, ftp) I'd say it's done right, and done well.


©2004 by Stewart~Frazier Tools, Inc. - all rights reserved
Last Update: 10/14/2004
Back to 'Windows to Unix' page
Back to S.F.T. Inc. main page