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, some of the services are:
    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, and has a 3rd party IPv4 to IPv6 tunnel provider, 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

# For the purpose of this example, 'xl0' is connected to a DSL modem for PPoE.
# '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.
# Otherwise, access via 'xl0' is effectively limited to the DSL modem and its
# web-page config screen, and uses a separate subnet from the remaining network.
#
# In cases where 'xl0' has a public IP, substitute 'xl0' for 'tun0'.  Otherwise,
# 'tun0' is the adaptor that has the public IP address (via PPPoE).

# internal networks
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

# icmp6 (local network, basically allow all icmp6)
ipfw add 1103 allow icmp6 from any to any via xl1 icmp6types \
  1,2,3,4,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,151,152,153,155

# icmp6 for gif0 tunnel (IPv6 4:6 gateway through a service provider)
ipfw add 1110 allow icmp6 from any to any via gif0 icmp6types \
  1,2,3,4,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,151,152,153,155

# protocol 41 ipv6 tunneling (may be bug, use '41' not ipv6 to prevent problems)
# limit it to the actual tunnel endpoints to prevent spoofing
# The 'tun0' interface is used by PPPoE to connect to the IPv4 internet
# To prevent tunnel hijack/spoof, specify the IP address aa.bb.cc.dd [my global IPv4 address]
# and ww.xx.yy.zz [the tunnel provider's IP address].  These IP addresses would have
# been specified in the tunnel create command for ifconfig already.
ipfw add 1200 allow 41 from any to any src-ip ww.xx.yy.zz dst-ip aa.bb.cc.dd via tun0
ipfw add 1201 allow 41 from any to any src-ip aa.bb.cc.dd dst-ip ww.xx.yy.zz via tun0

# allow ICMP to get through on public interface (tun0) for ping, traceroute
ipfw add 1900 allow icmp from any to any via tun0 icmptypes 0,3,8,11

# udp - prevent broadcast going in/out tun0 (ISP should block this, but...)
ipfw add 1999 deny udp from 255.255.255.255 to any out via tun0
ipfw add 1999 deny udp from any to 255.255.255.255 out via tun0

# remaining udp access control (deny specific services to all but those specified earlier)
ipfw add 02000 allow udp from any to any 1024-65535,domain,auth

# allow udp access to any port when the packet is outgoing or 'fragment'
ipfw add 02001 allow udp from any to any out
# ntpd needs this next one
ipfw add 02002 allow udp from any to any 123
ipfw add 02500 allow udp from any to any frag

# this next section denies incoming IPv4/IPv6 to various services since ALL machines
# have PUBLIC ADDRESSES if they use IPv6

# prevent incoming Xorg, vnc, cyrus, nfsd
#vnc denial
ipfw add 02900 deny tcp from any to any dst-port 5900-5909 in via tun0
#POP and IMAP denial (comment out if you want these to be visible)
ipfw add 02901 deny tcp from any to any dst-port 110,143,4190 in via tun0
#X11 server port denial
ipfw add 02902 deny tcp from any to any dst-port 6000 in via tun0

# similar rules for IPv6, with additional ports used by Windows Vista and later
# NOTE:  I may not have ALL of the relevant ports blocked for IPv6 windows clients so
#        please do not hold me liable if your network is compromised because I missed one.
#        You should at LEAST block THESE ports, howerver.
ipfw add 2903 deny tcp from any to any dst-port 5900-5909 in via gif0
ipfw add 2904 deny tcp from any to any dst-port 6000 in via gif0
#POP and IMAP denial (comment out if you want these to be visible)
ipfw add 2905 deny tcp from any to any dst-port 110,143,4190 in via gif0
# specific windows IPv6 vulnerabilities blocked at the firewall
ipfw add 2906 deny tcp from any to any dst-port 2049 in via gif0
ipfw add 2907 deny tcp from any to any dst-port 4190 in via gif0
# port 8001 is apparently used by vista for windows networking and HAS VULNERABILITIES
# so deny any connection INWARDS via the public IPv6 adaptor
ipfw add 2908 deny tcp from any to any dst-port 8001 in via gif0
ipfw add 2909 deny udp from any to any dst-port 8001 in via gif0

# prevent ADDITIONAL incoming udp packets for windows boxen (and nfsd) over gif0
# note that this could potentially mess up UDP communications if the source port
# just happens to be one of the blocked ones, since the recipient would not be
# able to respond to queries.  This can be fixed by limiting UDP automatic port
# numbers to a range above 8001 on all relevant machines
ipfw add 2950 deny udp from any to any dst-port 1025 in via gif0
ipfw add 2951 deny udp from any to any dst-port 1026 in via gif0
ipfw add 2952 deny udp from any to any dst-port 1900 in via gif0
ipfw add 2955 deny udp from any to any dst-port 2049 in via gif0
ipfw add 2953 deny udp from any to any dst-port 4500 in via gif0
ipfw add 2954 deny udp from any to any dst-port 5353 in via gif0


# tcp access control - note that 'ftp-data' must be specified by port number '20'
# your mileage may vary on the allowed services listed.  You may want to add other
# services such as 'auth' for IRC (just make sure you secure it)
ipfw add 03000 allow tcp from any to any http,https,ftp,20
ipfw add 03000 allow tcp from any to any ssh,domain,daytime,time,auth
ipfw add 03000 allow tcp from any to any 1024-65535
# NOTE:  anything already blocked for the various 'in via' rules won't be
#        allowed here, so this next rule really applies to the LAN only
ipfw add 03000 allow tcp from any to any 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 listed here. That is in case it was not allowed previously



# 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-13 by Stewart~Frazier Tools, Inc. - all rights reserved
Last Update: 6/23/2013
Back to 'Windows to UNIX®' page
Back to S.F.T. Inc. main page