If you are thinking of implementing a firewall for your network, you will probably be bombarded by many vendors trying to sell you a variety of off-the-shelf firewall solutions for large amounts of money. However, with a small investment in effort you can have one of the most effective and secure firewalls in a small amount of time, just for the cost of a PC.
Everyone knows that OpenBSD is the most secure operating system around. That is one of the main reasons why it makes the perfect firewall. Its simple, free, open-source, secure, reliable and will help you sleep soundly at night.
OpenBSD will work on a variety of platforms but this document is mainly concerned with Intel architecture. Not for any other reason than it is widely available and cheap. Essentially this small introduction can be applied to any architecture without much difficulty.
This tutorial explains the process of constructing a bridging firewall with OpenBSD.
Install OpenBSD
This is relatively straightforward, to start off with - go to http://www.openbsd.org/, find your closest mirror, and follow the install instructions.
In a nutshell, you download a floppy disk image (currently named floppy29.fs), put it onto a disk using dd or rawrite.exe and boot from it. You'll get asked lots of simple questions, given the opportunity to partition your hard-disk and asked how you want to install. FTP is a good method and if you decide to use it, you'll get offered a list of FTP servers to use. Choose the nearest to you and let it happen. Hey presto - installed.
When you reboot into OpenBSD, type:
man afterboot
which has got lots of suggestions for what to do initially.
Personally I do the following:
Finally - send some hardware or money to the openbsd project by buying something - a cd-rom or t-shirt. Its a wonderful operating system and needs your support.
At the time of writing, IP-Filter (ipf) has been removed from OpenBSD due to licencing issues. However, despite being present in OpenBSD distributions up to 2.9 you might like to install the latest version from the ipf homepage as the package is frequently updated with new features and bugfixes.
Installation is quite simple.
tar zxvf <filename>
make openbsd make install-bsd
OpenBSD/kinstall
Again, this step is not strictly necessary if you are using the version of ipf as supplied with OpenBSD, however it is still advisable to build your own kernel so that you can optimise the kernel for firewalling. DONT PANIC - it really is simple. Here's how to do it in a nutshell.
option IPFILTER option IPFILTER_LOG pseudo-device bridge 2add them if they're not already there.
maxusers 32 # estimated number of users
option "NMBCLUSTERS=8192"NMBCLUSTERS controls the size of the kernel mbuf cluster map. The more network traffic your machine will be dealing with, the more mbufs you need.
boot bsd.oldwhich will boot your old kernel. Then you can fix whatever was wrong with the new kernel.
The first step in making the firewall is to turn the BSD box into a bridge. This means that all traffic on each interface will be forwarded to the other interface. Without any filtering this would allow the joining together of two ethernet networks.
The simplest configuration is to use one of your two ethernet cards as your main interface, which will be given an IP address. The other card will be brought up but will not have any IP addresses associated with it.
Lets assume you have two ethernet adapters, which manifest themselves in the kernel as 'xl0' and 'xl1'. Arbitrarily we'll make 'xl0' the main interface. The commands to configure the cards and the bridge would be:
ifconfig xl0 <ipaddress> netmask <netmask> up ipconfig xl1 up brconfig bridge0 add xl0 add xl1 maxaddr 2000 up
This would configure both interfaces, add them to the bridge0 device, and make the bridge active. The 'maxaddr 2000' term specifies how many MAC addresses are to be remembered by the bridging cache. Set this to the upper limit of how many mac addresses will be available on the network.
OpenBSD provides a simple way to configure the network adapters at boot up. To do this, create a file called '/etc/hostname.xl0' and place the following inside using your favourite text editor:
inet <ipaddress> <netmask> NONEfor example:
inet 10.0.0.1 255.0.0.0 NONE
All we want to do to xl1 is to bring it up. So we create /etc/hostname.xl1 simply containing the word:
upNext, the bridge device. Place the following into /etc/bridgename.bridge0
add xl0 add xl1 blocknonip xl0 blocknonip xl1 maxaddr 2000 up
Notice that we've added 'blocknonip' options to each interface. This option stops the interface forwarding anything but IP (IPv4, IPv6, ARP and RARP).
Finally, we edit /etc/rc.conf.ipfilter=and modify it to say
ipfilter=YESThis is also a good time to also turn off any other junk you won't need. eg
inetd=NO portmap=NO
At boot time, these files will be consulted by /etc/netstart and the interfaces configured accordingly as if you had typed the commands manually. When the OS comes up, the interfaces will be bridging.
The man pages for brconfig(8), bridge(4) and ifconfig(8) are well worth reading. In fact man pages are generally worth reading - especially with BSD systems. This is something that is too often forgotten. People do a lot of work creating them, and I for one appreciate it. Remember: man is your friend.
Whether you use ethernet, Frame Relay, ATM or PPP, IP filtering rules will all apply. This is due to the wonderful BSD networking architecture.
Rather than try to replicate some of the excellent texts available which describe how to use IP-Filter, here is a set of excellent links:
IP Filter has the ability to keep "state" information on pretty much everything. This is an attractive feature but it does have overheads. If your firewalling policy keeps state on many connections and you have a very high-traffic network you may find that your state table fills up. To users, this can manifest itself in many ways. A dead giveaway is that TCP connections appear to time-out consistantly, whilst pings and traffic passed without state information passes freely. To check the activity of the state tables, type:
ipfstat -sThis will produce something like:
IP states added: 24157092 TCP 42 UDP 0 ICMP 901098369 hits 114907215 misses 0 maximum 108240 no memory 2480 bkts in use 6050 active 42 expired 24042802 closed
The highlighted line shows how many states are currently in use.
The maximum number of states is set during compile time. In the ipf distribution is a file called ip_state.h which contains the compile time options. Inside you will see something like:#ifndef IPSTATE_SIZE # define IPSTATE_SIZE 5737 #endif #ifndef IPSTATE_MAX # define IPSTATE_MAX 4013 /* Maximum number of states held */ #endifIPSTATE_MAX is the maximum number of states held. IPSTATE_SIZE is a value which controls the size of the hash table in which the state information is held. In the output of ipfstat -s above, 'buckets' is limited to this size. If either 'active' or 'buckets' are appraching the size of IPSTATE_MAX and IPSTATE_SIZE respectively, you are in trouble and need to increase the values. N.B. you can not choose arbitrary values for these.A post from Darren Reed (the author of ipf) stated :
> Umm, the general rule of thumb is IPSTATE_MAX should be ~70% of _SIZE.
Also, both numbers should be prime!
To increase the values, choose two values that conform to the restrictions above and add the following to ip_state.h, just above the #ifndef IPSTATE_SIZE line.
#define IPSTATE_SIZE <your state size> #define IPSTATE_MAX <your max size>
Then rebuild ipf, rebuild the kernel and reboot.
Over the years various build problems have occured. If you experience a problem, have look through the ipfilter mailing list archives. If you are sure that no-one else has experienced this, then try putting your question to the list.
One problem that you may encounter is that the kernel build fails due to a warning about nat_clearlist() in if.c. You may also experience a similar problem with nat_ifdetach(). The fix for this is to edit: /usr/src/sys/net/if.c
replace the occurence of nat_clearlist(); (or nat_ifdetach) with
frsync();