Much has been written about
building Unix firewalls. Some of what has been written may even be
useful.
I chose OpenBSD with IPFilter for the
following reasons:
To prepare to build a firewall like this, the first thing to do is to go to the OpenBSD order page and buy OpenBSD. The 2 CD set is only $40 Canadian, and includes OpenBSD builds and tools for many different processors including: most varieties of Mac 68K's; Sparc 4C and 4M types; Sun3; iMac; Powerpc G3, G4, or cube; amiga; hp300/400; and i386 and higher PC's. The OpenBSD project depends on sales for funding. They build a good operating system for building firewalls and deserve the support. Note that those using i386 and higher PC's can also download a version of OpenBSD stripped down for firewalling, emBSD. However, for this as well, I recommend that you keep a maintenance system with a full OpenBSD installation from the CD's.
Once you have the 2 CD's, I recommend that you have at least two systems, one of which should have at least 800 MB of disk space and a single network interface while the other need only have 200 MB, but must have two network interfaces. On the one with 800 MB of disk space you should load the entire operating system, compiler and compiler tools, and man pages along with the entire source code tree. This will be your maintenance system. At this point, you should go to the OpenBSD errata starting page, locate the correct errata page for the version of OpenBSD you have, and download the appropriate source code patch files to your maintenance system. Patch installation instructions are at the start of each patch file. Follow the instructions intelligently, i.e., if several patches apply to the same code section, do not compile that code until all of those patches have been applied. The patches and compilations may take a while, but they improve the security and the response of the machine. You may want to compile a custom kernel for your systems to exclude kernel code portions you won't need. See kernel configuration, and OpenBSD kernel compilation and optimization, for information on how to do this.
The firewall system should only
have a minimal OpenBSD configuration loaded. This means only a
generic bsd kernel, the base binary distribution, and the etc
distribution file. This gives everything necessary for firewalling.
Once this is all installed, boot OpenBSD on the firewall system and
transfer from the maintenance system the installed versions of those
files that are also present on the firewall system. Note that some of
the files installed in the process of patching are not present on the
firewall system. However, they were used to produce files that are
present on the firewall system. If you have compiled a custom kernel or
have recompiled the generic kernel, now is the time to transfer the new
kernel to the firewall system as well.
After all of that preparation,
firewall construction can finally begin (See also IPF How To). I've found that
native address translation simplifies firewall rule development, and
that is what I will describe here. I have gotten an "invisible"
bridging firewall to work, but I did not like its behavior and won't
describe that method. In the following instructions, I use $INTERNAL$
to mean the first three sets of numbers of the internal network IP,
$EXTERNAL$ to mean the first three sets of numbers of the external
network IP, $EXTERNAL-MYADDR to mean all four sets of numbers for an
external (internet) IP address, and $INTERNAL-MYADDR to mean all four
sets of numbers for an internal (local) IP address The steps for
developing a firewall on the firewall system are as follows:
# $OpenBSD: ipnat.rules,v 1.2 1999/05/08 16:33:10 jason Exp $ # # See /usr/share/ipf/nat.1 for examples. # edit the ipnat= line in /etc/rc.conf to enable Network Address Translation # #map ppp0 10.0.0.0/8 -> ppp0/32 portmap tcp/udp 10000:20000 # #need this to make FTP work fully # map if1 $INTERNAL-MYADDR/32 -> $EXTERNAL-MYADDR/32 proxy port ftp ftp/tcp # Repeat above line for each paired set of $INTERNAL-MYADDR and $EXTERNAL-MYADDR # #this lets everything else work # bimap if1 $INTERNAL-MYADDR -> $EXTERNAL-MYADDR/32 # Repeat above line for each paired set of $INTERNAL-MYADDR and $EXTERNAL-MYADDR #
# $OpenBSD: ipf.rules,v 1.6 1997/11/04 08:39:32 deraadt Exp $ # # Template for filtering rules development for /etc/ipf.rules # # To use this template to develop a rules system: # # 1. Replace $CAMPUS with the name of the interface to which the campus network will # be connected, e.g. ae1 # # 2. Replace $PROTECT with the name of the interface to which your protected local area # network will be connected, e.g. ae0 # # 3. Replace $INTERNAL-NET with the internal net address, e.g. 192.168.123.0/24 # # 4. Replace $EXTERNAL$ with the prefix to the external net address, e.g. 123.45.123 # Note that this is not the full address. # # 5. Duplicate the line that reads, # "block in log quick on $CAMPUS from $EXTERNAL-MYADDR/32 to any group 10 # No, you're not me" # as many times as needed so that there is one for each value of $EXTERNAL-MYADDR with # one of those values to be substituted for $EXTERNAL-MYADDR on each of those lines. # # 5. Replace each $EXTERNAL-MYADDR with an actual address to filter against, e.g. 123.45.123.45 # # 6. Add incoming from campus network policy rules just above the line that # reads, "block in quick on $CAMPUS all group 10 # Kill it all now!" # to reflect the site needs. # # 7. Edit the outgoing to campus network policy rules between the line that # reads, # "# 4. Allow ping out." and the line that # reads, # "block in log quick on $PROTECT all group 20 # block everything else forever and log it!" # # 8. Edit other names beginning in $ to reflect your network. # # 9. Add the file /etc/ipnat.rules with the following type of content in this precise order: # Note that the $EXTERNAL-MYADDR* and $INTERNAL-MYADDR* can be repeated as often # as needed in order to reflect the entire network. However, all map/proxy rules # must precede all bimap rules. Substitute for $CAMPUS as above. # # # #need this to make FTP work fully for some reason # # # map $CAMPUS $INTERNAL-MYADDR1/32 -> $EXTERNAL-MYADDR1/32 proxy port ftp ftp/tcp # map $CAMPUS $INTERNAL-MYADDR2/32 -> $EXTERNAL-MYADDR2/32 proxy port ftp ftp/tcp # map $CAMPUS $INTERNAL-MYADDR3/32 -> $EXTERNAL-MYADDR3/32 proxy port ftp ftp/tcp # # # #this lets everything else work # # # bimap $CAMPUS $INTERNAL-MYADDR1/32 -> $EXTERNAL-MYADDR1/32 # bimap $CAMPUS $INTERNAL-MYADDR2/32 -> $EXTERNAL-MYADDR2/32 # bimap $CAMPUS $INTERNAL-MYADDR3/32 -> $EXTERNAL-MYADDR3/32 # # 10. The file /etc/hostname.$PROTECT where $PROTECT is replaced with the name of the interface # to which your protected local area network will be connected must contain the lines # inet $INTERNAL$.100 255.255.255.0 # up # with $INTERNAL$ replaced with the prefix of the protected local area network, e.g. 192.168.123 # Note that this is not the full address. # # 11. The file /etc/hostname.$CAMPUS where $CAMPUS is replaced with the name of the interface # to which the campus network will be connected must contain the lines # inet alias $EXTERNAL-MYADDR1 255.255.255.0 # inet alias $EXTERNAL-MYADDR2 255.255.255.0 # inet alias $EXTERNAL-MYADDR3 255.255.255.0 # up # with as many alias lines as you have $EXTERNAL-MYADDR* and with each value substituted # appropriately. # # 12. The file /etc/myname should contain a system name such as bsd-4a # # 13. The file /etc/hosts should have a line that defines the host address as $INTERNAL$.100 as # $INTERNAL$.100 bsd-4a bsd-4a.not.here.now # The exact name does not matter. # # 14. Edit the ipfilter= line in /etc/rc.conf to enable IP filtering # # 15. Edit the ipnat= line in /etc/rc.conf to enable NAT # # 16. Delete any file named /etc/bridgename* The bridge is not needed and causes a leak. # # 17. The file /etc/mygate should contain the gateway router IP address such as: # $EXTERNAL$.100 # # 18. Check all the above files in /etc to be sure of their contents, connect the cables, reboot, # and enjoy life behind your new firewall. # # # Examples of rules to print to printers external to the firewall, and for telnet, web, # ftp, domain, and ping out both active and passive, are given. # # IP filtering rules. See the ipf(5) man page for more # information on the format of this file, and /usr/share/ipf # for example configuration files. # block in all #kill everything, both ways. Default deny block out all # # allow loopback to work. # pass in quick on lo0 all pass out quick on lo0 all # # block problem packet types # block in quick all with opt lsrr block in quick all with opt ssrr block in quick proto tcp all with short block in log quick proto tcp from any to any flags FUP # Block & log this OS fingerprinting # # block persistent campus network usages # block in quick proto tcp/udp from any to any port = 67 #bootps block in quick proto tcp/udp from any to any port = 68 #bootpc block in quick proto tcp/udp from any to any port = 69 #tftp # # block problematic services on both sides # block in quick proto tcp/udp from any to any port = sunrpc #portmap block in quick proto tcp/udp from any to any port = msp #msp? block in quick proto tcp/udp from any to any port = 1109 #kpop block in quick proto tcp/udp from any to any port = 1127 #SUP debug block in quick proto tcp/udp from any to any port = 1495 #cvc block in quick proto tcp/udp from any to any port = 1524 #ingres lock block in quick proto tcp/udp from any to any port = 1525 #prospero block in quick proto tcp/udp from any to any port = 1645 #radius block in quick proto tcp/udp from any to any port = 1646 #radius acct. block in quick proto tcp/udp from any to any port = 1760 #www-ldap-gw block in quick proto tcp/udp from any to any port = 2049 #nfs block in quick proto tcp/udp from any to any port = 2105 #kerberos rlogin block in quick proto tcp/udp from any to any port = 2108 #k-init block in quick proto tcp/udp from any to any port = 2111 #k X block in quick proto tcp/udp from any to any port = 2112 #k ip block in quick proto tcp/udp from any to any port = 2120 #K auth block in quick proto tcp/udp from any to any port = 4045 #lockd block in quick proto tcp/udp from any to any port = 2627 #webster dict. block in quick proto tcp/udp from any to any port = 5002 #radio free ethernet block in quick proto tcp/udp from any to any port = 5680 #Kana-Kanji server block in quick proto tcp/udp from any to any port = 6112 #dtspc block in quick proto tcp/udp from any to any port = 7100 #font server block in quick proto tcp/udp from any to any port = 7326 #internet CB block in quick proto tcp/udp from any to any port = 26740 #hunt (6) # # The following line can be removed if site policy permits X terminals # block in quick proto tcp from any to any port 5999 >< 6010 # No X # # # block in quick on $CAMPUS all head 10 # # # Antispoofing incoming rules # block in quick on $CAMPUS from 0.0.0.0/8 to any group 10 block in quick on $CAMPUS from 2.0.0.0/8 to any group 10 block in quick on $CAMPUS from 5.0.0.0/8 to any group 10 block in quick on $CAMPUS from 10.0.0.0/8 to any group 10 block in quick on $CAMPUS from 20.20.20.0/24 to any group 10 block in quick on $CAMPUS from 23.0.0.0/8 to any group 10 block in quick on $CAMPUS from 27.0.0.0/8 to any group 10 block in quick on $CAMPUS from 31.0.0.0/8 to any group 10 block in quick on $CAMPUS from 67.0.0.0/8 to any group 10 block in quick on $CAMPUS from 68.0.0.0/6 to any group 10 block in quick on $CAMPUS from 72.0.0.0/5 to any group 10 block in quick on $CAMPUS from 80.0.0.0/4 to any group 10 block in quick on $CAMPUS from 96.0.0.0/3 to any group 10 block in quick on $CAMPUS from 127.0.0.0/8 to any group 10 block in quick on $CAMPUS from 128.0.0.0/16 to any group 10 block in quick on $CAMPUS from 128.66.0.0/16 to any group 10 block in quick on $CAMPUS from 169.254.0.0/16 to any group 10 block in log quick on $CAMPUS from 172.16.0.0/12 to any group 10 block in quick on $CAMPUS from 191.255.0.0/16 to any group 10 block in quick on $CAMPUS from 192.0.0.0/16 to any group 10 block in log quick on $CAMPUS from 192.168.0.0/16 to any group 10 block in quick on $CAMPUS from 197.0.0.0/8 to any group 10 block in quick on $CAMPUS from 201.0.0.0/8 to any group 10 block in quick on $CAMPUS from 204.152.64.0/23 to any group 10 block in quick on $CAMPUS from 224.0.0.0/3 to any group 10 # # Anti-incoming broadcasts rules: # block in quick on $CAMPUS from 255.255.255.255/32 to any group 10 # No broadcast. block in quick on $CAMPUS from $EXTERNAL$.255/32 to any group 10 # No broadcast. block in quick on $CAMPUS from $EXTERNAL$.0/32 to any group 10 # Not this broadcast either. # # Anti-self masquerade rule: # block in log quick on $CAMPUS from $EXTERNAL-MYADDR/32 to any group 10 # No, you're not me # #************************************************************************ # # Insert lines to stop incoming traffic from ISP's from which past strange contacts have come. # Add to these as needed to block hostile activities. Note this does not block outgoing to # these ISP's. In other words, treat them as "Don't call us. We'll call you." because of # their repeated problems. # block in quick on $CAMPUS from $PROBLEM$.0/$MASK$ to any group 10 # Block a problem # #************************************************************************* # # Internet incoming rules: # # 1. Place specific rules for the site here. # # 2. Allows in destination unreachables naturally. # # 3. Block everything else without exceptions and without further notice. # block in quick on $CAMPUS all group 10 # Kill it all now! # # #************************************************************************* # block in quick on $PROTECT all head 20 # # Antispoofing from LAN rules # block in quick on $PROTECT from !$INTERNAL-NET to any group 20 # Must be from legal address range block in quick on $PROTECT from any to 0.0.0.0/8 group 20 block in quick on $PROTECT from any to 2.0.0.0/8 group 20 block in quick on $PROTECT from any to 5.0.0.0/8 group 20 block in quick on $PROTECT from any to 10.0.0.0/8 group 20 block in quick on $PROTECT from any to 20.20.20.0/24 group 20 block in quick on $PROTECT from any to 23.0.0.0/8 group 20 block in quick on $PROTECT from any to 27.0.0.0/8 group 20 block in quick on $PROTECT from any to 31.0.0.0/8 group 20 block in quick on $PROTECT from any to 67.0.0.0/8 group 20 block in quick on $PROTECT from any to 68.0.0.0/6 group 20 block in quick on $PROTECT from any to 72.0.0.0/5 group 20 block in quick on $PROTECT from any to 80.0.0.0/4 group 20 block in quick on $PROTECT from any to 96.0.0.0/3 group 20 block in quick on $PROTECT from any to 127.0.0.0/8 group 20 block in quick on $PROTECT from any to 128.0.0.0/16 group 20 block in quick on $PROTECT from any to 128.66.0.0/16 group 20 block in quick on $PROTECT from any to 169.254.0.0/16 group 20 block in quick on $PROTECT from any to 172.16.0.0/12 group 20 block in quick on $PROTECT from any to 191.255.0.0/16 group 20 block in quick on $PROTECT from any to 192.0.0.0/16 group 20 block in quick on $PROTECT from any to 192.168.0.0/16 group 20 block in quick on $PROTECT from any to 197.0.0.0/8 group 20 block in quick on $PROTECT from any to 201.0.0.0/8 group 20 block in quick on $PROTECT from any to 204.152.64.0/23 group 20 block in quick on $PROTECT from any to 224.0.0.0/3 group 20 # # Anti-broadcasting rules. # block in quick on $PROTECT from any to 255.255.255.255/32 group 20 block in quick on $PROTECT from any to $EXTERNAL$.255/32 group 20 block in quick on $PROTECT from any to $EXTERNAL$.0/32 group 20 # # Anti-self send rules # block in quick on $PROTECT from any to $EXTERNAL-MYADDR/32 group 20 # Don't send to self.group 20 # # Do not need to block going to ISP's from which strange contacts have come. # Only needed to block their contacting here. Here contacting them may be # an acceptable actitivy depending on why done. # #************************************************************************* # # LAN in going rules {outgoing to campus network. Edit below here down to the line # that reads, # "block in log quick on $PROTECT all group 20 # block everything else forever and log it!" # to reflect policy}. The line above that reads # "block in quick on $PROTECT from !$INTERNAL-NET to any group 20 # Must be from legal address range" # means that now do not have to check address legality any more in this rule group since # only legal from addresses are allowed in at all. # # Example shown is designed to: # # 1. Allow ftp, web, and telenet from internal through firewall. Allows both # passive ftp for web servers and active ftp sessions. Of course, the NAT # rules must do the ftp proxy as well for this to work completely. # # 2. Allow printing to approved printers ONLY. # # 3. Allow udp out to domain # # 4. Allow ping out. # pass in quick on $PROTECT proto tcp from any to $EXT-PRNT$.0/24 port = 515 flags S keep state group 20 # lp block in log quick on $PROTECT proto tcp/udp from any to any port = 515 group 20 # lp only to ours pass in quick on $PROTECT proto tcp from any to $DNS/32 port = 53 flags S keep state group 20 # domain names pass in quick on $PROTECT proto udp from any to $DNS/32 port = 53 keep state group 20 # domain names pass in log first quick on $PROTECT proto tcp from any to any port = 23 flags S keep state group 20 # telnet pass in log first quick on $PROTECT proto tcp from any to any port = 80 flags S keep state group 20 # web pass in log first quick on $PROTECT proto tcp from any to any port 19 >< 22 flags S keep state group 20 # ftp pass in log first quick on $PROTECT proto tcp from any to any port = 443 flags S keep state group 20 # secure web # # This next allows active ftp out # pass in log first quick on $PROTECT proto tcp from any port 19 >< 22 to any port > 1024 flags S keep state group 20 # # This next allows passive ftp such as is done with web servers. X already blocked and not a threat. # pass in log first quick on $PROTECT proto tcp from any port 32800 >< 46000 to any flags S keep state group 20 # pass in quick on $PROTECT proto icmp from any to any icmp-type 8 keep state group 20 block in log quick on $PROTECT all group 20 # block everything else forever and log it! # # #************************************************************************* # # Internet outgoing rules for addresses # allow tcp and udp out from here. Its been filtered. # allow pings out from here. They've been filtered. # block all else # block out quick on $CAMPUS all head 60 pass out quick on $CAMPUS proto tcp from any to any flags S keep state group 60 pass out quick on $CAMPUS proto udp from any to any keep state group 60 pass out quick on $CAMPUS proto icmp from any to any icmp-type 8 keep state group 60 block out quick on $CAMPUS all group 60 # # #************************************************************************* # # LAN out going rules for addresses # # Allow tcp and udp to go back to internal from here. Its been filtered. # Allow destination unreachables to go back naturally. Be sure that only # packets bound for the internal network pass this group. # block out quick on $PROTECT all head 80 pass out quick on $PROTECT proto tcp from any to $INTERNAL-NET flags S keep state group 80 # insist on right address! pass out quick on $PROTECT proto udp from any to $INTERNAL-NET keep state group 80 block out quick on $PROTECT all group 80 # # block in all block out all # # last rule wins in the event we get here! #
Text templates for each of the files to be created can be loaded from these links: