How-To: OpenBSD Firewall

I love network security, firewalls in particular. I have done some pretty extensive fire-walling with OpenBSD and I learned a ton along the way. I tried to write down what I learned, and have gone back to reference the resulting document multiple times when doing installs or upgrades. So I wanted to post up on my blog some of that in a how-to format. This guide will take you through the installation and initial configuration of an OpenBSD firewall, which, depending on the hardware, could be suitable for home or office use.



Before Beginning!
This is intended to be a fairly step by step tutorial on getting a BSD firewall going on some old hardware. This is intended (eventually) for production environments, so don’t expect any compromising security options to be installed. Also, this is for dedicated stations, ergo, dual boot options and configurations are not covered in this document.

Also, there are going to be some things that you need to have ready. CD burner & blank cds (you only -need- one, if you have confidence that you won’t burn any coasters), the machine you intend to install on, obviously. A calculator (this is for figuring out partition sizes), and a fairly good knowledge of the machine you are going to be installing on (general hardware, we don’t usually need to painstakingly document each components manufacturer, chip set, etc as those who remember some painful early installs of Linux may expect). This will also require that you have at least 2 NICs in your computer. A working Internet connection will be needed if you plan on installing over the intertubes. Also a cursory knowledge of vi, or the ability to cheat sheet it.

Step 1: Installation

Getting the Install Media: This used to be a bit more involved, but they have started releasing full install discs. Just download the install iso and burn it to a disc.

  1. Now that you have your cd, throw it in the tray and boot to the install process!
  2. Now its gonna throw a lot of options at you. Defaults will be fine for most of these.

List of Options

  1. (I)nstall, (U)pgrade or (S)hell? Option I for install (note shell is -extremely- limited!)
  2. Terminal Type Enter
  3. kdb mapping Enter
  4. proceed with install? y
  5. selecting available disks: Enter
  6. Do you want to use it all? y
  7. now you go to the disk label process. This is tricky! I will fill this out with some detailed instructions. DON’T BE INTIMIDATED! USE BEST PRACTICES!
  8. Disk Label
    1. enter ‘p m‘ at the prompt to view existing partitions
    2. partition c represents the whole disk. If you wiped your drive before this, you should see just c, which is your whole drive. For those who didn’t wipe the drive before this, shame shame, but we can still set up the disk with the partitions that we need
    3. enter ‘d letter of partition‘ to delete other partitions, don’t delete c:, but get rid of all others
    4. now we will create some partitions -
      1. To setup a partition, the command is ‘a letter of partition
        1. It will ask for the offset (this is fine for default)
        2. size? (number no spaces, g for gigabyte, m for megabyte)
        3. filesystem? (BSD will be fine, except for swap, that defaults to swap)
        4. mountpoint?
          1. a should be root (input / for root)
          2. b should be /swap
          3. DO NOT USE c IT REPRESENTS YOUR WHOLE DRIVE! (don’t think it will let you anymore)
          4. d is for /tmp
          5. e is /var
          6. f is /var/logs
          7. g is /usr
          8. h is /home
      2. Partitioning: I put relative sizes for the partitions based on if you plan on using the entire hard disk, it hardly needs this much space. (for a 40g hard drive is paran)
          1. 1/3 for root (1g)
          2. 2 g for swap (2g) (double your current RAM is a good bet, that way you won’t run out of space)
          3. 1/15 for tmp – more space if you plan on compiling ports from source (2g)
          4. 1/15 for var -  (2g)
          5. for /var/log – this is where we will store our logs so pretty hefty (8g)
          6. 1/3 for usr – more if you plan on compiling port from source (6g)
          7. 1/4 or whatever for home (4g)
      3. Things to remember while partitioning
        1. Having extra space is not going to hurt anything, disk space is cheap these days, so be generous, but don’t worry if you don’t use all the available space. Some admins even like to leave some extra unpartitioned space so that they can add some later as needed (the flexibility is there, but is beyond the scope of this document)
        2. You can get an install going on an insanely small amount of space, the provided example is certainly sufficient space for all aspects, even if you use the x win system (although we won’t here)
        3. You can use any drive letters for the partitions except c. a should always be for root, other than that, you are free to go crazy (don’t though, you will forget)
    5. After you have set all your partitions enter q to quit the disk label creator
    6. Want to write new labels (d)
    7. It will run through the labels that you have created for double checking. Confirm that those are in fact the points you defined earlier by hitting enter at each mount. After you have reviewed all of them, you must type ‘done
    8. Stuff will scroll by as it saves those options
  9. Now it will kick you into network configuration. This is designed at this point for the old system where you had to install over a network or over the internet. All of these options are going to be able to be reconfigured when you have your system installed, so you don’t have to worry about it to much.
    1. So you can initilize an interface right now, if you would like, I won’t tell you how
    2. Hostname? your hostname
    3. Configure the network? n
  10. Password for root account? password – enter a password here, not just ‘password’
  11. Location of sets? Enter (for cd)
  12. Which cd rom? Enter – Select your main one, default is fine if you only have one
  13. Pathname to sets? Enter
  14. Set name?
    1. You need the following sets to run OpenBSD, and for production firewalls, it is recommended that you install -only- these sets, as there is a theoretical security advantage to doing so, ie if a hacker was to gain remote access, it would be difficult to install anything if compile tools were not there. If you go with the defaults, don’t worry about it to much, however.
      1. bsd
      2. base[version#]
      3. etc[v#]
      4. man[v#]
    2. To delete other packages simply prepend a ‘ - ‘ to the name of the set, it will be deleted
  15. Ready to install sets? Enter
  16. Location of sets? Enter
  17. Start sshd by default? n – transparent bridge, no. But for later administration, you will want this running
  18. NTP server? Enter
  19. X windows? Enter – no way! we have command line fu at our disposal!
  20. Change default console? Enter
  21. Time
    1. To set your clock accurately, you will want to do this. It is important for log files to be accurately timestamped for admission in a court of law.
    2. ? – gives you a list of options, mine is US/Central.
    3. You can enter this in at two separate prompts or all at once if you know your options.
    4. Capital letters do matter here!
  22. It will run through some scripts, and then give you instructions to reboot the machine. Do it.

Congrats! You have now completed your basic installation, with minimum hassle, hopefully. Now on to some more interesting options in you new world of the BSD operating system.


Step 2: Post – Installation Configuration
Great, so now you are in your new system. You have a few immediate orders of business to take care of:

Getting out of that scary root account

And into a more comfortable local account.

  1. type ‘adduser‘ at the command line. This brings up an interactive dialog (the first time sets the defaults for the following times)
    1. Pay attention to the terminal type, you don’t want to get stuck with a command line option you hate!
  2. Follow the dialog through in creating you new user
  3. Still as root, type ‘vi /etc/group‘ to edit your groups configuration so that you can have su privileges
    1. To do that edit (usually the first line) to read ‘wheel:*:0:root,your user name‘ no space between the comma and your name
  4. Now type exit to get back to the login screen
  5. Login as you newly created user
  6. type ‘su‘ at the command line to confirm that you setup your account correctly, if you can login after typing the root password, then you are fine.
  7. If you are going to have a few junior admins working on the firewall, you should limit their privileges even further by setting up sudo rights for the accounts in question

Building Bridges:

Creating the bridge that you will be using for your firewall.

  1. ifconfig - type this to discover what your interfaces have been named by OpenBSD (maybe you jotted it down from the install process, maybe you didn’t). Remember to ignore both the loopback interface (lo0) and the enc0, these are for other purposes. An example would be  fxp0, fxp1. These are what I am going to use to configure my bridge
  2. ifconfig bridge0 create – type this to get the bridge running (must su to root)
  3. vi /etc/sysctl.conf – this is a location that we need to change so that ip forwarding is enabled we do this by changing a line
    1. #net.inet.ipforwarding=1
    2. net.inet.ipforwarding=1 – to this (we removed the comment declaration)
  4. These three commands get your bridge up now:
    1. ifconfig fxp0 up
    2. ifconfig fxp1 up – these commands ensure that the interfaces that I want to add to my bridge are up and operational
    3. brconfig bridge0 add fxp0 add fxp1 up – this adds your interfaces to the bridge and then brings the bridge online, temporarily
  5. Setting up your bridge to run at startup. This is important, if you ever need to reboot the previous commands won’t have been remembered, so it is nessacary to setup host files, these will automatically be parsed at boot time.
    1. vi /etc/hostname.fxp0 - should consist of one line up
    2. vi /etc/hostname.fxp1 – also one line - up – this tells BSD to turn on these interfaces at startup
    3. vi /etc/bridgename.bridge0 – this will create a file that will create your bridge automatically when you bootup (or reboot). A simple file will have three lines:
      1. add fxp0
      2. add fxp1
      3. up
  6. Your bridge has been built!

Enabling the firewall, the pf.conf

  1. vi /etc/rc.conf – this will allow us to tell the system that we want to use pf (we really want to!) find and change:
    1. pf=NO to pf=YES


Step 3: Configuring your Firewall

Fantastic we are moving right along. We have our machine up and running, and we have built a bridge. You probably have (and should) hooked up your firewall to an already safe network segment to try it out. Now we are ready to make this the really excellent firewall that it was born to be (err, metaphorically of course). The syntax for a pf ruleset is very readable, in my opinion. One thing to remember is that the last rule always wins! There are also a few other things that you need to be aware of, they will be listed at the end.

  1. So here we go, here is a sample firewall ruleset that does these things, read the comments, as a good ruleset is self-documenting.
  2. To change the firewall rules without a reboot (grr.. reboots)
    1. pfctl -F all this will flush all the pf rules
    2. pfctl -f /etc/pf.conf this will load the most current rules- need to say where the actual file is explicitly somewhere
  3. Get to know pfctl, read its man page. This thing can do all kinds of great things!
    1. You can use pfctl to change rules on the fly, or to load a totally different ruleset without interfering with the one that actually works
  4. For other examples of different configurations, and a list of syntax rules, see /usr/share/pf its very good 
################################################
# Sample pf ruleset for OpenBSD 4.3 bridges
# author Trevallion : 13 May 2008
################################################

### Quick rules, good ideas ###
# skip your loopback interface, if you don't this could cause problems
# scrub all of your traffic in
# scrubbing out will stop hosts posing as trusted users using packet fragmentation for fingerprinting (not common... by the way)
set skip on lo
scrub in all
scrub out all


### Macros for extensiblity ###
# outside and inside
# trusted hosts (behind the firewall, presumably)
# trusted ports
outside="fxp0"
inside="fxp1"
trusted_hosts="ip addresses of trusted hosts, seperated by commas, ranges -are- permissible, eg 192.178.0.1/24"
trusted_ports="{port #'s here}, eg { 22, 113 }"


#### Windows Updates ####
# Allow Windows Servers to get Windows Updates
# The ports that it opens up are just http and ssl
windows_range="{84.53.136.0/24,207.46.0.0/16,65.55.192.0/24,
64.4.21.0/24}"
windows_range_ports="{80, 443}"


#### Anchor for Command Line Changes Later ####
# this will allow you to change some of these basic rules from the command line eg,
# pfctl -a main -f pass in on $inside all keep state 
# this will be only useful for rules that use quick
anchor main_quick


### pass all traffic on your outside ###
pass in quick on $outside
pass out quick on $outside


### block default on your inside interface ###
block in log on $inside
block out log on $inside

### allow some sanitary traffic on through your inside interface ###
pass in on $inside from $trusted_hosts to any keep state
pass out on $inside from $trusted_hosts to any keep state
This is a skeleton ruleset only, and just gives you the basics. Understanding of what traffic you want to block and what you want to keep to completely up to you.


Logging Options

Ideally you will want to log unusual traffic to your hosts, as well as some of the traffic that you block

  • You can log most rules by adding the log keyword
  • Some rules will have uninteresting logs, however, so map out your traffic flow, and decide what you do, in fact want to log
  • It is best to determine what interfaces and what rules you want to view, this will be dictated by the degree of granularity you want to peruse
  1. tcpdump – a few items to get you started
    • tcpdump -i your interface
      • this will show you all the packets passing through the specified interface, in near realtime
    • tcpdump -e -n -ttt -i pflog0
      • Is going to allow you to view packets headed to your log (assuming that you are logging traffic) ,
      • the “e” option prints link level headers,
      • the “ttt” option gives you a timestamp, and
      • the “n” option gives you a more barebones look by not attempting to provide address translation (opposite is the -a parameter in case you are interested)
      • pflog0 is the realtime view, to get the actual logs use tcpdump -n -e -ttt -r /var/log/pflog
  2. pftop is a great utility
How to edit logging parameters on OpenBSD.
You may think that you have needs over and above the 4 hour defaults that are found in OpenBSD. If you think that you are going to need more logs, or keep them for a longer period of time, then you had better consider a few things:
  • How much traffic is going to go through the firewall?
  • What would the effects of logging more than the usual time window do to your resources (this is a question that everyone will have to answer differently)
  • The default settings for logs will log at -minimum- 4 hours of the traffic that you specify using log rules, if there is practically nothing being logged, then you will be fine. Do you want to go to the trouble of changing some decent settings?
  1. If you answered ‘Yes, I really need to be logging way more than 4 hours’ here are some ways to do it (please use best practices and make backups before you edit these very critical files!!):
    • vi /etc/newsyslog.conf – this will pull up the settings for all of you system logs you are looking for a line that looks like this
      • /var/log/pflog … 600    3    250  *  ZB  /var/run/pflogd.pid
    • there are a number of things that you can change here
      • changing the 600 is -not- good, that will change the permissions on the file (and you want to be able to read it)
      • changing the 3 to another number will allow you to keep more logs archived (default is four, 0-3), you can keep more, ie if you change this value to 7 then you will keep at minimum 8 hours of logs
      • changing the 250 to another value will change the size (in kilobytes) of your log file. Making this larger will increase the size maximum of your log file, this is a great place to add some space to your logs without worrying about running out of space, etc. A word of caution here, very large sizes may cause system slowdown when archiving does get around to taking place
      • changing the star to any integer value will force logs to change at the hour, regardless of the size parameter (i.e., if you change this to 1, the it will create a new log and archive the old one every hour, deleting the oldest).

If you want to check on them more than every hour, you can edit that in cron like this (I am not recommending this method, be sure you read all the documentation concerning this method before you decide to use it, it may have unintended consequences!):

  • crontabs -e -u root this will kick you into a vi like interface where you can make some changes to your logging time parameters (among other things)
  • look for the line that looks like this
    • #rotate log files every hour, if necessary
    • 0    *    *    *    *    *   /usr/bin/newsyslog
  • edit it to read
    • 0-23/2    *   *   *   *   * /usr/bin/newsyslog
  • this will check the logs every 2 hours, effectively creating 2 hour logs

Conclusion

Well, that is pretty much it. I included some useful sites and snippets in these ‘Appendixes’, if you care to peruse them, although I suppose I could have put all that logging stuff into an appendix as well. Regardless, let me know if you have questions or comments on what I have presented here, I will be happy to answer questions.

Appendix A: Useful Resources

These are reference links, intended to instruct the user on various aspects of the install process, and to document the source for some of the decisions that may otherwise be presented arbitrarily.

http://www.openbsd.org/faq/faq4.html
extremely detailed explanation on most aspects of the OpenBSD installation process. It is worth noting that certain sections within the document (ie partioning and other topics) may be cited using  the #(section)  at the end of the address to  link directly to the appropriate section

http://www.openbsd101.com/installation.html
A simple guide that runs through the basics of a full disk, OpenBSD install. Useful for its simplicity as well as its recommendations for install options. Very up-to-date with latest install information!

http://www.openbsd101.com/security.htmlRed
I know that it is the same root as the other mentioned previous, but this outlines some good security practices for the OpenBSD install, as well as post install features

http://www.openbsd.org/
OpenBSD homepage

http://ezine.daemonnews.org/200412/openbsd.html
A simple install guide, slightly out of date, but still perhaps, useful

http://www.openbsd.org/faq/pf/example1.html
This simple outline is a good start for users wanting not only a quick rundown of a functional pf file, but also good comments on best practices and some shortcuts to enhanced functionality

http://ezine.daemonnews.org/200207/transpfobsd.html
this is all about the bridge device, how to enable it and many other things

http://www.netikus.net/documents/OpenBSDTransparentFirewall/index.html
I wish that I had found this easy to follow and well-organized tutorial earlier! Really helps you out and is very clear on what needs to happen. Most helpful on the bridge aspect, but has lots of other good info, although it was originally created for OpenBSD 3.3, and uses that less useful method of blacklisting for its blocks.

http://bsdbrasil.wordpress.com/2007/12/16/bridge-redundant-transparent-firewall/
this site is looking promising, as it has many of the extra features that I am looking at adding


Appendix B: Partitioning
  1. ~Partitioning: I put relative sizes for the partitions based on if you plan on using the entire hard disk, it hardly needs this much space.
    1. 1/3 for root
    2. 2 g for swap (double-ish your RAM)
    3. 1/15 for tmp – more space if you plan on compiling ports from source
    4. 1/5 for var – this is where your logs are going to be, so how much do you want to keep?
    5. 1/3 for usr – more if you plan on compiling port from source
    6. 1/4 or whatever for home


Appendix C: Customizing the Prompt w/ OpenBSD

  1. In order to customize the prompt you have to edit your users .profile file which is contained in the home directory of the user.
  2. I don’t know how to change it system wide, you dont really have to, I suppose. 
  3. To find the syntax, just check the ksh man page, it seems to have all the commands
  4. Syntax
    1. add this line to the .profile of the user: PS1=”\u@\h:\w> “
    2. This is  saying prompt will be “user@hostname:current working directory> “
  1. No comments yet.

  1. No trackbacks yet.