Scudamore Consulting Banner


OpenBSD pf Firewall Build Procedure - howto (How to build the perfect firewall)

Why OpenBSD? Why pf?

I have been building firewalls for many years. A firewall should should be a lean, efficient combination of the operating system which is easily hardened. While there are many options available today, I believe that pf on OpenBSD is the clear leader in terms of functionality, flexibility and security.


First Steps

Partition The Disk

The first step is to partition the disk. You will need to create two partions on a one disk system. Three partitions if the system has a data disk. On the primary disk you need to create a root partition and a swap partition. The root partition must be created first on the disk. A useful technique is to create the swap partition first to get it the correct size and then select the remaining disk space for the root partition. You must then write down the size of the root partition. Zero-out the partition table and recreate the two partitions (root first this time) using the information you have logged from the previous step. If there is a second disk utilize the entire disk to create a /opt partition.


Complete the Base Install

Select the default installation sources.  Note: On Openbsd 4.2 and above, you will also need to install xbase, as expat (a library required for the below package installs) is now provided by xbase. When the files are done installing, select no to X Server and yes to sshd and ntpd.  reboot


Download Source, Ports and Packages

Create a directory for installs using: mkdir –p /opt/installs

Download and Install Required Pacakges

Download the following packages from your favorite OpenBSD ftp server to the /opt/installs directory.
Install the packages using the pkg_add command.


Install vim from the Ports Collection

Browse to the /usr/ports/editors/vim directory. To compile vim without X11 support, edit the Makefile and change the FLAVOR?= option from  gtk2 to no_x11. Compile by executing make then make install. Also, be sure to copy /usr/local/share/vim/vim71/vimrc_example.vim to /usr/local/share/vim/vimrc.


Adding Color Support

By installing the gnu.org coreutils package, and the color support scripts I adapted from Linux, you can experience OpenBSD with full-color support.

The colorscripts install.sh places the required files for color into /etc/skel so additional users will be created with the appropriate color files.


Create Additional Non-Privileged Users

Create additional non-privileged users with the adduser command. Add the users to the wheel group if you wish for them to be able to su to root.


Redirect root's Email

Redirect root's email to your "normal" email account so that it doesn't get backed up the firewall. Use vi to open the /etc/mail/aliases file for editing. Modify line that says "# root " by removing the "#" comment at the beginning of the line, and then modifying the portion after the colon so that it points to your "normal" email address instead. You can either point it to your new user account (so that the email stays on the machine & can be accessed without su'ing to root), or redirect it to your 'normal' email account in the office (so that you don't even have to SSH out to the firewall to see how it's doing each day).

After saving & exiting, then run the command "newaliases" from the command prompt to update the email alias database.


Create and Install a Warning Banner

Use vi to replace your /etc/motd file with the following text (or some other equivalent legal disclaimer).


* * * * * * * * * * * W A R N I N G * * * * * * * * * * * * *
THIS SYSTEM IS RESTRICTED TO AUTHORIZED USERS FOR AUTHORIZED USE
ONLY. UNAUTHORIZED ACCESS IS STRICTLY PROHIBITED AND MAY BE
PUNISHABLE UNDER THE COMPUTER FRAUD AND ABUSE ACT OF 1986 OR
OTHER APPLICABLE LAWS. IF NOT AUTHORIZED TO ACCESS THIS SYSTEM,
DISCONNECT NOW. BY CONTINUING, YOU CONSENT TO YOUR KEYSTROKES
AND DATA CONTENT BEING MONITORED. ALL PERSONS ARE HEREBY
NOTIFIED THAT THE USE OF THIS SYSTEM CONSTITUTES CONSENT TO
MONITORING AND AUDITING.
* * * * * * * * * * * * W A R N I N G * * * * * * * * * * * * *

Edit /etc/rc and comment out the motd section or your file will be overwritten everytime you reboot.


Build a Custom Kernel

For this example, we will assume you are using the i386 platform:

# cd /usr/src/sys/arch/i386/conf
# cp GENERIC CUSTOM (replace the word custom with any name of your choice. This simple step will prevent intruders from easily determining which kernel you are running )
#
vi CUSTOM ( modify the kernel options as desired )
# cd ../compile/CUSTOM
# make clean && make depend && make
    [...lots of output...]
# make install

At this point, reboot your machine to activate this new kernel.


Make Static Routes Persistent Across Reboots


# Add static routes as required.
# file format is:
#  gw network/mask
if [ -f /etc/myroutes ]; then
        {
                set -- `sed -e 's/#.*$//' /etc/myroutes |grep -v '^$'`
                while [ $# -ge 2 ]; do
                route -n add -net $2 $1
                shift 2
                done
        }
fi

216.52.46.254   172.16.1/30
216.52.46.254   192.168.10/24
216.52.46.212   69.25.212.192/27
216.52.46.212   69.25.212.224/28
216.52.46.252   69.25.212.240/28
216.52.46.254   192.168.12/24


Enable Packet Forwarding and Performance Tweaks

Make the following changes to /etc/sysctl.conf

net.inet.ip.forwarding=1 
       # 1=Permit forwarding (routing) of packets
vm.swapencrypt.enable=1         # 1=Encrypt pages that go to swap

To enable high performance data transfers on hosts according to http://www.psc.edu/networking/perf_tune.html Enabling High Performance Data Transfers on Hosts, add the following to /etc/sysctl.conf:
net.inet.ip.mtudisc=1     #Path MTU discovery
net.inet.tcp.rfc1323=1    #TCP Extensions

#  Increase TCP and UDP Window size for increase in network performance
net.inet.tcp.recvspace=65535
net.inet.tcp.sendspace=65535
net.inet.udp.recvspace=65535

# SACK (RFC2018): enabled by default


Create Hostname Files for the External and Internal Interfaces

You will need to create a hostname file for each interface. The filename syntax is hostname.xxx where xxx is the name of the network adaptor. You can easily find the network adaptor names for your system by executing:

# ifconfig (sample output below)

lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 33192
        groups: lo
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x6
        inet 127.0.0.1 netmask 0xff000000
hme0: flags=8863<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 08:00:20:fd:87:bb
        media: Ethernet autoselect (100baseTX full-duplex)
        status: active
        inet6 fe80::a00:20ff:fefd:87bb%hme0 prefixlen 64 scopeid 0x1
        inet 192.168.0.254 netmask 0xffffff00 broadcast 192.168.0.255
xl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 00:10:5a:e3:2f:a2
        groups: egress
        media: Ethernet autoselect (100baseTX full-duplex)
        status: active
        inet6 fe80::210:5aff:fee3:2fa2%xl0 prefixlen 64 scopeid 0x2
        inet 207.138.124.249 netmask 0xfffffff8 broadcast 207.138.124.255


In the above example, a hostname.xl0 and a hostname.hme0 need to be created for the external and internal interfaces.

The /etc/hostname.xl0 (external interface) file contains the following for the above example:

inet 207.138.124.249 255.255.255.248 NONE

The /etc/hostname.hme0 (internal interface) file contains the following for the above example:

inet 192.168.0.254 255.255.255.0 NONE



System-name, Gateway and DNS Resolution

# cat /etc/resolv.conf

search mydomain.com
nameserver 1.2.3.4
nameserver 1.2.3.5



Final Steps