The OpenBSD installation process is quite straightforward and you can find a good description of the whole procedure in the section 4 of the OpenBSD FAQ. Therefore, I will not go into the details of the configuration, but will focus my attention on things that may confuse first-time users:
Minimum amount of swap space. Use about twice the amount of the RAM memory you have installed in your computer, and you should be OK. If in doubt, use the partition-size values listed in section 4 of the OpenBSD FAQ.
Large disk support. When the hard disk will not boot, even though the system installation went fine, you will need to make it bootable using the hard disk or computer manufacturer's configuration utilities. Sometimes, particularly when dealing with machines with old BIOSs, your system might not correctly recognize the disk's size. That should not affect the OpenBSD installation, and you can simply make the disk bootable after you install OpenBSD on it, using utilities downloaded from the disk or computer manufacturer's Web site. If you are still having problems, read the INSTALL documents, where you will find detailed descriptions of various ways to solve problems with large disks.
Network interface address. When OpenBSD asks you during installation, it is up to you to decide which interface you want to configure; it doesn't matter too much which you choose, since we can change that configuration later on. The only thing to remember is that if you are configuring the interface to the Internet, you must use the IP address that your ISP gave you, while for networks behind a firewall you should use one of the reserved addresses for networks not connected to the Internet, like 192.168.1.x, in which the interface that connects the firewall to the rest of the network would have address of 192.168.1.1 and the interface that connects the firewall to the DMZ would have address of 192.168.2.1 (192.168.2.x is another network). You will not be able to configure the interface connected to the serial port at this time, as it requires additional software (
pppd). You can complete that step later on.
IRQ conflicts. To avoid IRQ conflicts, remove all unnecessary hardware from your system; sound cards should go first, as they are of no use on a firewall; TV/radio, scanner controllers, and similar superfluous cards can go too. All you need are network cards and a SCSI controller card, if your computer is equipped with SCSI disks. Of course, you should leave the graphics card, as you will need to use a monitor, at least during installation.
When you encounter IRQ-related problems with network card devices, the devices will either be invisible to the system, will clash with other devices using the same IRQs, or will not be able to configure themselves properly during the system initialization stage. Common signs that you might be having these problems are lack of connection to other computers (the
ping command followed by the IP address of another computer on the private network or the DMZ reports 100% packet loss), "device timeout" messages, or crashes during system boot or soon afterwards. These problems are easily solved using appropriate network card configuration utilities and the User Kernel Config tool.
When such mishaps happen, boot the computer from the DOS or Windows boot disk, run the card configuration utility, disable automatic configuration, set the network media type to 10BASE-T, and choose IRQ from the list of available interrupts. Repeat the process for every card in your system, exit the configuration utility, and boot the computer into OpenBSD.
If you are still having problems, you will need to configure the kernel via UKC. You can enter the UKC console in two ways: at boot time, when you see the
boot> prompt (type
boot -c), or from the root account (type
config -e /bsd). When you see the
UKC> prompt, you can search for devices, add new devices, disable or enable existing ones, and search for IRQ conflicts between them. If you find that the IRQ you chose for one of the network cards is taken by another device, you might disable that device, as long as it is not an essential part of the system; for example, I always disable the mouse device on a firewall machine, because it is not needed on a machine that does not run X Windows. Similarly, all sound devices can be disabled as well, as they are of no use on a firewall. Once you find a configuration that does work, write it down and use
config -e /bsd (from the root account) to create and save a new kernel that will be used instead of the generic kernel (saving a copy of the generic kernel is a good idea too). You will find additional information in the config manual page (
man config is your friend). IRQ-related problems with SCSI controllers are solved in a similar way. To learn more about UKC, read section 5 of the OpenBSD F.A.Q. The list of supported devices (http://www.openbsd.org/i386.html), and the Ethernet Adapters and SCSI Host Adapters sections in particular, will also come in handy when you are trying to figure out what is going wrong.
To check that the network cards are working, connect the firewall to the private network and the DMZ and use the
ping command followed by the IP number of machines on these networks. Long delays and 100% packet loss are a sure sign of trouble.
Network media selection problems. These are solved either by configuring cards with appropriate configuration utilities or by setting the media selection options in the
hostname.xxx files (they reside in the
/etc directory). You can discover which interfaces you have in your system with
ifconfig -a, which will display the list of all interface devices. Then read the appropriate manual page (e.g. for
ne cards, read
man ne) and find out which options are responsible for forcing media selection. If you are having problems identifying network devices by their names, a look at the Ethernet Adapters section of the OpenBSD Web site will help. When you find out which interface you need to configure, look for the file
/etc/hostname.ne1 for device
ne1) and edit it as necessary. You may need to create this file from scratch. There should be one such file for each Ethernet interface (for more information, read the manual page for
When the installation is finished and the system boots without problems, properly recognizing installed network cards, you can proceed to edit the following files (you must be logged in as root):
/etc/hostname.devicename-- these files store basic information that the system needs to configure network cards. There should be one such file for each card; for more information read section 5 of the the OpenBSD F.A.Q. as well as
man hostname.if. A sample configuration file for an
ne1(an NE1000/NE2000 compatible) device that connects the firewall to the internal private network might look like this:
inet 192.168.1.1 0xffffff00 NONE
/etc/hosts-- the host name database for the firewall machine, this file contains a list of IP numbers and hostnames that the firewall machine "knows;" it should contain the entries for the names and addresses under which it is known on the internal private network and on the DMZ (it is perfectly possible for a single machine to be a member of many networks and be known under many different names and addresses), which in our case are 192.168.1.1 (private internal network) and 192.168.2.1 (DMZ):
127.0.0.1 localhost 192.168.1.1 fireater.foo.com fireater 192.168.2.1 fireball.bar.com fireball
The IP addresses of the firewall interfaces listed in
/etc/hostsare identical to the IP addresses listed in the
/etc/hostname.devicenamefiles. If the firewall is connected to the Internet via an Ethernet card, there will be another entry in
/etc/hostswith the IP address and hostname assigned by the ISP. Remember to change
bar.comto the actual domain names for these networks. These do not necessarily have to be registered domain names. I am using two different domain names for the internal private network and the DMZ, because it helps me differentiate between the two networks, but you may of course use only one domain name (or you could use more than two domain names, it's up to you).
/etc/resolv.conf-- the name resolver configuration file should contain the following entries:
search foo.com nameserver 192.168.1.2 lookup file bind search bar.com nameserver 192.168.2.2 lookup file bind
Notice that I assumed that the nameservers for domains foo.com and bar.com are listening at addresses 192.168.1.2 and 192.168.2.1, but your configuration will quite probably be different and should be changed accordingly.
/etc/rc.conf-- the main system configuration file should have the following options enabled:
After you make all of these modifications, reboot the system with
sync; reboot and check if the network interfaces are functioning properly (
ping requests to hosts on the private internal network or on the DMZ should report no lost packets). Remember that if the network interface connecting the firewall to the Internet is plugged into the serial port, you will need to configure the
pppd daemon (read
man ppp). The device name used by such interfaces is
tun0. (You do not need to create
/etc/hostname.tun0 for it.)
Remember that you must configure other hosts on the private internal network and in the DMZ in a way that will allow smooth communication with the firewall and other hosts on the internal private network, the DMZ, and the Internet. To do so, you should configure the TCP/IP protocol on each machine on the private internal network to use 192.168.1.1 as the gateway, and give each machine an IP address in the same address space (192.168.1.2, 192.168.1.3, 192.168.1.4, and so on). Similarly, the machines in the DMZ should be configured to use the address 192.168.2.1 as their gateway, and give each machine IP addresses from the 192.168.2.2-192.168.2.254 range. Also, every machine should be given a unique host name.
Once that is finished, you should consider running an internal DNS server on the private part of your network, to make internal communication just a bit easier. The DNS entries should list all hosts on the private network and in the DMZ. The DMZ machines will not have access to that data for security reasons (they are banned from sending any packets to the private network altogether), but machines on the private network will need it so users can easily update documents on the WWW server, read and send mail to other hosts on the Internet, and use other services located in the DMZ.
Once you have the OpenBSD system and networking up and running, you will need to configure the firewall. The set of rules I am going to present below is rather restrictive, and many administrators may not agree with it, but I prefer to start with simple, tight rules and later on loosen them up as required.
ipfilter can be divided into two modules: network address translator (NAT) and packet filter. The first performs masquerading (hiding internal IP addresses behind a single external IP address) and packet redirection between hosts and ports. The packet filter picks up packets modified by NAT and checks if they can be allowed to enter the networks behind the firewall. You can find a detailed explanation of the
ipfilter design and rules syntax at Daren Reed's official
man ipf and
man ipnat will provide you with plenty of additional information.
Since NAT gets to look at packets first, we'll configure it first. Network address translation and packet redirection rules are saved in the
/etc/ipnet.rules file. Open this file in a text editor and enter the following rules:
# private internal network NAT rules
map tun0 192.168.1.0/24 -> x.x.x.x/32 portmap tcp/udp 10000:20000
map tun0 192.168.1.0/24 -> x.x.x.x/32
# DMZ NAT rules
map tun0 192.168.2.0/24 -> x.x.x.x/32 portmap tcp/udp 20001:30000
map tun0 192.168.2.0/24 -> x.x.x.x/32
These rules tell the NAT engine to map all connections from the internal private network to address "x.x.x.x" on ports from 10000-20000, and to map all connections from the DMZ to address "x.x.x.x" on ports 20001-30000. The "x.x.x.x" string should be replaced with the actual IP address assigned by your ISP.
tun0 is the name of the Internet interface device. Replace it with a different netowork device name if the external interface is not using the serial port.
We can now make connections to the Internet from the internal private network and from the DMZ, but hosts outside of our network cannot access the services in the DMZ. This is solved by redirection. A sample set of rules for redirecting HTTP traffic is shown below:
# redirect HTTP requests from foreign hosts
rdr tun0 x.x.x.x/32 port 80 -> 192.168.2.254 port 8080 tcp
rdr tun0 x.x.x.x/32 port 80 -> 192.168.2.254 port 8080 udp
# redirect HTTP requests from the private internal net
rdr ne1 x.x.x.x/32 port 80 -> 192.168.2.254 port 8080 tcp
rdr ne1 x.x.x.x/32 port 80 -> 192.168.2.254 port 8080 udp
# redirect HTTP requests from the DMZ
rdr ne2 x.x.x.x/32 port 80 -> 192.168.2.254 port 8080 tcp
rdr ne2 x.x.x.x/32 port 80 -> 192.168.2.254 port 8080 udp
Again, "x.x.x.x" is the IP address of the exernal interface that connects the firewall to the Internet. 18.104.22.168.254 is the IP address of the hosts that runs the HTTP server in the DMZ. For security reasons, the server listens for requests at an unprivileged port 8080. Note that there must be a rule that redirects packets sent to port 80 at "x.x.x.x" for every interface, or some packets will not arrive at the right destination.
To redirect another kind of service, you must copy the rules for HTTP requests changing the port numbers; for example, to redirect mail, add the following rules to
# redirect SMTP requests from foreign hosts
rdr tun0 x.x.x.x/32 port 25 -> 192.168.2.253 port 25 tcp
rdr tun0 x.x.x.x/32 port 25 -> 192.168.2.253 port 25 udp
# redirect SMTP requests from the private internal net
rdr ne1 x.x.x.x/32 port 25 -> 192.168.2.253 port 25 tcp
rdr ne1 x.x.x.x/32 port 25 -> 192.168.2.253 port 25 udp
# redirect SMTP requests from the DMZ
rdr ne2 x.x.x.x/32 port 25 -> 192.168.2.253 port 25 tcp
rdr ne2 x.x.x.x/32 port 25 -> 192.168.2.253 port 25 udp
Note that I used a different IP address on which the SMTP daemon runs, but it could just as well be running on the same machine that the HTTP server runs on.
Once we have our NAT rules in place, we can proceed to add the packet filtering rules. These are stored in the
/etc/ipf.rules file. Open it in a text editor and add the following two lines at the beginning:
pass out quick on lo0 all pass in quick on lo0 all
lo0 is the loopback interface, which we'll leave alone, as trying to block traffic here would be a waste of processor cycles that could be better used elsewhere. The
quick keyword instructs the firewall to immediately stop processing other rules as soon as the packet matching this rule arrives; this saves a considerable amount of CPU cycles and simplifies rule writing. There is not much we can add here, so we can proceed to the
tun0 interface rules, where we need to block all outgoing traffic destined for illegal addresses (this technique is used by some crackers and we certainly do not want to help them):
block out quick on tun0 from any to 192.168.0.0/16 block out quick on tun0 from any to 172.16.0.0/12 block out quick on tun0 from any to 127.0.0.0/8 block out quick on tun0 from any to 10.0.0.0/8 block out quick on tun0 from any to 0.0.0.0/8 block out quick on tun0 from any to 169.254.0.0/16 block out quick on tun0 from any to 192.0.2.0/24 block out quick on tun0 from any to 22.214.171.124/23 block out quick on tun0 from any to 126.96.36.199/3
Having stopped dangerous packets from polluting the Internet, we should add rules that let the legitimate traffic through. The following three rules will allow all traffic from legal addresses on the private internal network to be sent to the Internet:
pass out quick on tun0 proto tcp from 192.168.1.0/24 to any keep state
pass out quick on tun0 proto udp from 192.168.1.0/24 to any keep state
pass out quick on tun0 proto icmp from 192.168.1.0/24 to any keep state
keep state keywords tell
ipfilter to "remember" connection state, so packets sent back to the hosts originating the connection can pass through the firewall. The
proto keyword defines the protocol to which a particular rule will apply.