No Clean Feed - Stop Internet Censorship in Australia

Building an OpenBSD firewall for use with Telstra/Optus broadband

PDF
Print
Written by Dan Lehman
Thursday, 02 October 2008 21:33


NOTE & CAVEAT:

As the revision table below shows, I haven't maintained this article for a number of years.  However I still receive regular, positive feedback from visitors who have located the article linked from other websites, hence it remains a part of my website.

At the time of (re)publication, OpenBSD is now at version 4.4, so the information here may now be wildly inaccurate when applied to current releases.  The only changes I have made recently are minor formatting adjustments to fit the current look and feel of the rest of the website.

 

Document Revision History:

Date Version Comments

26th March 2002

1.0

Initial Release

29th March 2002

1.1

Updated NAT section, added extra explanation of rules

13th April 2002

1.2

- Added appendices for Name Resolution and DHCP

- Updated resources section

25th July 2002

1.3

Updated for OpenBSD 3.x and created additional sections for using Packet Filter for filtering and NAT

13th April 2003

1.3.1

Minor updates, fixed line indentation issue with PPPoE instructions

2nd May, 2003

1.3.2

- Added minor changes to accommodate changes in 'pfctl' commands for OpenBSD 3.2

- Noted the PPPoE requirement for interface to only be brought 'up', instead of 'dhcp'

- Updated resources section

 

Contents:

  1. Overview
  2. Assumed Knowledge
  3. Specific ISP/Connection Requirements
  4. IP Forwarding
  5. Packet Filtering
    1. IP Filter (OpenBSD 2.x)
    2. Packet Filter (OpenBSD 3.x)
  6. NAT
    1. IPNAT (OpenBSD 2.x)
    2. Packet Filter (OpenBSD 3.x)
  7. PPPoE
  8. Login Client
  9. Appendices
    • Appendix A: Name Resolution
    • Appendix B: DHCP
  10. More Resources

 

Overview:

This document aims to provide a basic overview of how to build an secure, OpenBSD Unix firewall for the purposes of securing an Optus or Telstra broadband internet connection.  The information presented here makes certain assumptions about the reader (see section titled "Assumed Knowledge') and their abilities.

Comments regarding this document can be forwarded to me via email.

 

Assumed Knowledge:

This document makes the following assumptions:

  • OpenBSD is the operating system being used
  • The reader has already installed (or can install without assistance) OpenBSD on the firewall computer
  • The firewall computer has 2 NICs (network interface cards)
  • The reader is building the firewall for use with a Telstra ADSL/Cable or Optus Cable broadband connection
  • The reader has chosen an private IP addressing scheme to use internally (ref. RFC1918)

 

Specific ISP/Connection Requirements:

Consult the following table to determine which components of this document are required reading for you to be able to configure OpenBSD to use your broadband connection:

ISP/Connection Type

IP Forwarding

Packet Filtering

NAT

PPPoE

Login Client

Telstra Cable

X

X

X

-

X

Telstra ADSL

X

X

X

X

-

Optus Cable

X

X

X

-

-

 

IP Forwarding:

This change will not take effect until the machine has been restarted.

 

Packet Filtering:

The term packet filtering refers to (as the tricky name suggests) filtering network packets as they pass through the firewall.  For OpenBSD 2.x computers, this means using IPF, or IP Filter.  In OpenBSD 3.x, PF, or Packet Filter, is used.

Either way, packet filtering involves the creation of rules that govern how each packet is handled.  These rules can be created so that they look at which network interface the packet is coming from/going to, which direction it is going in, who it is from or who is it going to, which protocol is being used and many other.  Like all good security features, there is also the ability to log packets that match a given rule.

Please choose the appropriate section from the links below to read up on configuring packet filtering for your OpenBSD firewall:

  • IP Filter (OpenBSD 2.x)
  • Packet Filter (OpenBSD 3.x)

It is important that you choose the correct section as the rules and methods vary between OpenBSD versions.

 

IP Filter (OpenBSD 2.x):

Enabling:

To enable IPF, change the following line in /etc/rc.conf:

Original:

ipfilter=NO

Edited:

ipfilter=YES

This change will not take effect until the machine has been restarted.

IPF Rules:

CAUTION!!!  An incorrectly configured IPF rule can prevent you from accessing the firewall across the network connection.  It is always a good idea to check your rules before using them and to perform the work at the console itself.

IPF rules are typically stored in the file /etc/ipf.rules.  A very basic IPF rule would be:

In the above example, this rule states that IP connections going out on interface lo0 (1st loopback adapter) should be passed through without any further rule checking (quick).

The following list of rules provide a basic, secure ruleset for a firewall (lines beginning with '#' are comments).  In these rules, 'rl0' refers to the external interface (connected to the internet) and 'xl0' refers to the internal interface (connected to PC/LAN).  You will probably need to change these interface names (bolded) to match those on your own OpenBSD computer:

Command:


The standard command to issue after changing these rules is:

The 'F' option flushes any existing rules, the 'a' option makes any rule changes to the active ruleset and the 'f' option specifies that the following filename contains the rules to be brought in.

 

Packet Filter (OpenBSD 3.x):

Enabling:

To enable PF, change the following line in /etc/rc.conf:

CAUTION!!!  An incorrectly configured PF rule can prevent you from accessing the firewall across the network connection.  It is always a good idea to check your rules before using them and to perform the work at the console itself.

PF rules are typically stored in the file /etc/pf.conf.  A very basic PF rule would be:

pass out quick on lo0

In the above example, this rule states that IP connections going out on interface lo0 (1st loopback adapter) should be passed through without any further rule checking (quick).

One of the major improvements PF has over IPF from OpenBSD 2.x is the ability to use variables in your rules.  This means that you can define variables to hold your interface names, private IP addresses and IP addresses for specific machines you would like to work with.

The following list of rules provide a basic, secure ruleset for a firewall (lines beginning with '#' are comments).  In these rules, '$ext_if' refers to the external interface (connected to the internet) and '$int_if' refers to the internal interface (connected to PC/LAN).  You will probably need to change these interface names using the variables at the top of the file to match those on your own OpenBSD computer:

bpa_auth="61.9.128.13/32"
Allow Bigpond 'heartbeat' to pass in
# Following IP is valid for auth server in Victoria only -
# use appropriate IP for dce-server
pass in quick on $ext_if inet proto { tcp, udp } from \
$bpa_auth to any port 5050

Command:


The standard command to issue after changing these rules is:

The 'F rules' option tells Packet Filter to flush the rules first.  The 'R' option reloads the packet filter using Packet Filter rules found in the filename following.  The 'f' option in OpenBSD 3.2 tells Packet Filter which file to use.

 

NAT:

NAT stands for Network Address Translation.  As the name might suggest, this component 'translates' network addresses across a connection.  When configured correctly, all computers on a LAN using private IP addressing (ref. RFC1918) can share the one internet connection using a single public IP address, according to a set of defined rules.

Please choose the appropriate section from the links below to read up on configuring NAT for your OpenBSD firewall:

  • IPNAT (OpenBSD 2.x)
  • Packet Filter (OpenBSD 3.x)

It is important that you choose the correct section as the rules and methods vary between OpenBSD versions.

 

NAT using IPNat (OpenBSD 2.x):

Enabling:

To enable NAT, change the following line in /etc/rc.conf:

This change will not take effect until the machine has been restarted.

IPNAT Rules:

IPNAT rules are typically stored in the file /etc/ipnat.rules.  A very basic IPNAT rule would be:

In the above example, this rule tells IPNAT to 'map' connections received at rl0 (external interface) from any IP in the private range 10.x.x.x to the actual IP on rl0.  A good, common IPNAT ruleset to start with is (lines beginning with '#' are comments):

You may notice that the above mappings can be broken into 3 "sets" of 3 similar rules.  This is because I've reproduced each set of rules to accommodate each of the 3 private IP address ranges specified in RFC1918.  This way, the same NAT rules file will cover most private networks.

The first rule in each "set" is important to notice as it uses the portmap option. This option allows us to narrow down the field of mappings, so to speak.  Take, for instance, the first group of rules that specifically deal with the 10.0.0.0 IP network.  On its own, mapping just the network to our public IP address would result in over 16,000,000 private IP addresses being mapped to our single public IP address.  The portmap option allows us to remap ports as well.  In the above case, my rule is remapping a range of ports (10000 to 60000) for both the tcp and udp protocols.

The second rule (the lines ending in "proxy port ftp ftp/tcp") allow 'transparent' connections to FTP servers through the firewall and the third rule takes care of all other mappings.

Note also, that these rules are only mapping in one direction (ie: mapping private to public).  It is possible to use the bimap option to map in both directions but that is outside the scope of this document.  For more details, use the man ipnat command.

Command:

The standard command to issue after changing these rules is:

The 'C' option clears any existing rules, the 'F' option flushes any existing connections from the list and the 'f' option specified the the filename following contains the rules to be brought in.

 

NAT using Packet Filter (OpenBSD 3.x):

Enabling:

To enable NAT, change the same line in /etc/rc.conf as for the OpenBSD Packet Filter:

This change will not take effect until the machine has been restarted.

NAT Rules:

NAT rules are typically stored in the file /etc/nat.conf.  A very basic NAT rule would be:

In the above example, this rule tells NAT to 'map' connections received at rl0 (external interface) from any IP in the private range 10.x.x.x to the actual IP on rl0.  As with the packet filtering rules, variables can now be used in the rules file.  A good, common NAT ruleset to start with is (lines beginning with '#' are comments):

You may notice that the above mappings appear to be 3 very similar rules.  This is because I've reproduced each rule to accommodate each of the 3 private IP address ranges specified in RFC1918.  This way, the same NAT rules file will cover most private networks.

Port mapping is now built into OpenBSD's Packet Filter.  There is no longer any need to write specific rules to handle them.

FTP Proxy:

FTP proxying requires a little extra work.  In OpenBSD 3.x, ftp-proxy is a daemon that is forked by the inetd superserer.  To enable ftp-proxy, you need to add the following lines in the following files:

In /etc/services:

In /etc/inetd.conf:

In /etc/nat.conf

In /etc/pf.conf:

The port specified in the lines added to /etc/services and /etc/inetd (8081 in my examples) can be any free port you like.  8081 is an ideal choice as it is rarely used by anything else.  FTP proxying is what allows the clients behind your firewall to access FTP servers using either active or passive FTP connections.

Command:

The standard command to issue after changing these rules is:

The 'F nat' option tells Packet Filter to flush the existing NAT rules first.  The 'N' option reloads Packet Filter using NAT rules found in the filename following.  The 'f' option in OpenBSD 3.2 tells Packet Filter which file to use.

 

PPPoE:

PPPoE stands for PPP Over Ethernet.  For the purpose of this document, it should be understood that PPPoE is only required for connection to the Telstra BigPond ADSL network, and not either of the cable networks.

Configuration:

To configure PPPoE, ensure that the file /etc/ppp/ppp.conf looks like the following (replace bolded words with appropriate information).  Blank lines and commented lines (beginning with '#') are ignored, labels start at column 0 (ending with ':') and all other lines are indented by a single space:

Connection Startup:

To ensure your firewall config is correct when your ADSL connection starts, put the following lines in /etc/ppp/ppp.linkup. Again, blank lines and commented lines (beginning with '#') are ignored, labels start at column 0 (ending with ':') and all other lines are indented by a single space:

PPPoE Also requires that the internet-facing interface simply be brought up but not configured (ie: not 'dhcp' like Telstra or Optus cable).  To do this, ensure that the contents of your /etc/hostname.xxx file (where 'xxx' is the name of your internet-facing interface) simply contains the word 'up' (without the quotes).

Command:

The command to issue to start your PPPoE connection is:

The 'd' option tells ppp to reconnect if the connection fails and the 'dial' option specifies that the following, configured connection (pppoe) is to be used.

 

Login Client:

Currently, the only network that requires a login client is the Telstra BigPond Cable network.

For OpenBSD, the best (and currently the only) login client to use is BPA Login.  Unless there is an OpenBSD-specific version available, it is always best to download the source code and compile it using your OpenBSD computer.

Configuring:

Once downloaded and installed, locate and edit the following lines in /etc/bpalogin.conf (replace bolded words with appropriate information):

Command:

The above command launches BPA Login.  The 'c' option specifies that the following filename contains the configuration information required to login successfully.

 

Appendices:

OK, so maybe the next two sections don't quite qualify as appendices but I wanted to include them without giving the impression that they were required to successfully build a firewall for your internet connection.

One of the more common questions I get asked after someone has built a firewall for themselves is how to go about setting up name resolution and automatic IP address assignment for their internal network's clients.  Without these, it's still quite a simple matter to setup your clients manually to use your ISP's DNS servers and to update hosts and lmhosts files to resolve names for the rest of your computers, but it's pretty nice if it can be done automatically, especially if you regularly invite friends over for LAN parties and such.

In the Name Resolution section, I'll discuss setting up hosts and lmhosts files on your computers so they can find each other on your network.  Setting up a true DNS server can be complex and confusing for the uninitiated and there are a few DNS server products that can be used.  If you're looking for a recommendation for a DNS product, I suggest you check out DJB-DNS.  It's far more reliable and secure than the BIND DNS product that comes with OpenBSD.

In the DHCP section, I'll discuss how to setup and configure a DHCP service on your OpenBSD firewall so you can automatically configure your network's clients with the appropriate details so they can participate on your network properly.

Please note that, currently, the following sections are still a work in progress.  I have not yet taken the time to explain everything in great detail.  For now, these sections serve (at best) as a simple guide to setting up and installing DHCP and DNS on your firewall.

 

Appendix A: Name Resolution

Name resolution is an important part of any network.  It's what allows a computer to locate other computers on a network and, indeed, the internet.  Fortunately, you don't have to worry about resolving the names on the internet yourself.  Your ISP provides that service for you in the form of DNS servers.

However, these do not help you when trying to locate other computers on your network by name.  Although you can locate them by IP address, it is obviously far easier to remember a computer's name rather than the numbers that make up its IP address.

A simple method of resolving computer names in OpenBSD is the use of the hosts file.  The hosts file is (strangely enough) /etc/hosts.  Each entry in /etc/hosts is comprised of the following information:

A typical entry for, say, your firewall might be:

This entry would allow you firewall to ping the IP address 192.168.0.1 by the names 'firewall' and 'firewall.example.com'.  There is no other action required for this to work, by default.  You can immediately add similar entries into this file for each computer on your network and your firewall will be able to locate each of them by name.

On your Windows client computers, the equivalent file to use is lmhosts.  This file is located in <WindowsDirectory>\System32\Drivers\Etc (for Windows NT/2000/XP) or just in <WindowsDirectory> (for Windows 9x/ME).

In each case, the entries in this file are very similar to those that go in /etc/hosts on you OpenBSD computer:

I'd also recommend adding a '#PRE' at the end of each line so that the entry is remembered by the computer from the very start, instead of looking through the file each time you want to resolve the name.  Add entries to this file for each computer on your network.

The command to execute after editing this file in Windows is:

This command tells Windows to reload the remote name cache table.  It's this table that holds the entries for the computers being resolved using this method (amongst others).

If all of the above is done correctly, you should be able to locate the computers on your network by machine name.  After following the instructions in the next section, most of the IP address management for your computers can be done automatically and you should have no trouble communicating with machines both inside and outside your local network.

 

Appendix B: DHCP

For those who don't know, DHCP stands for Dynamic Host Configuration Protocol.  DHCP is service that provides network clients with the ability to automatically configure their IP address details, including (but not limited to) default gateways, DNS servers, domain name(s) and so forth.

Without DHCP, your network clients would be required to have their IP address details manually configured in order to communicate with each other and the internet (via your firewall).  For the average home network, this isn't a major issue but it is rather helpful to be able to dynamically configure your client computers without having to visit each computer.  It's also handy when an extra client joins your network temporarily and all they have to do is plug themselves into your network and they're instantly ready to use it.

OpenBSD comes with dhcpd, the DHCP daemon.  A daemon in Unix/Linux is just like a service in Windows NT/2000/XP.  It's a program that runs in the background and usually requires no interaction from the user at all to perform its given function.

Enabling DHCP:

Enabling dhcpd in OpenBSD is very easy.  Like everything else, it's configured by editing some plain-text files.  To enable dhcpd, edit the following line in your /etc/rc.conf file:

On the next reboot, dhcpd will be enabled and running.  Before you reboot, though, there is some configuration that needs to be done so that the daemon can run properly and do its job.

Configuring DHCP:

Firstly, you need to tell dhcpd which network interface to listen on.  This is simply done by editing /etc/dhcpd.interfaces and putting in your internal interface's name on a line by itself.

The most complex part of setting up dhcpd is configuring the DHCP details to be given to client computers.  This is all done in the /etc/dhcpd.conf file.  The manual page for dhcpd.conf (run man dhcpd.conf from the command line) explains the various entries and options required.  As a guide, the below lines show the sort of information you will need to provide (the bolded items will be explained afterwards):

The default-lease-time and max-lease-time lines specify how long a client is initially given an IP address for and the maximum time they can hold it.  The number specified is the length of time in seconds.  In my examples above, these numbers calculate to 31 days.

The share-network declaration is a section that includes at least one subnet.  The bolded portion above is simply a descriptive name and can say anything you like.

The domain-name option tells the clients which DNS domain use for itself and for searches when looking for other computers on your network by name.  The bolded value above is the domain name enclosed in double quotes.

The domain-name-servers option configures the clients with the DNS server addresses and corresponds to the DNS server addresses on a Windows computer.  Usually, the value you put here will be the IP addresses given out by your ISP.  This is requires so you clients can find other computers on the internet.  Remember, your clients should already be able to locate each other using the hosts and lmhosts files described in Appendix A.

The get-lease-hostname flag (set to 'on' in my example above) is optional.  It's handy when you want to assign a specific IP address to a specific client.  In the above example, I have this option switched on.  Its function will become obvious during the explanation of another line later on.

The subnet declaration is the really functional part of DHCP.  It contains all the details to be used/given by dhcpd.  The values appearing in the subnet line specify the IP subnet to be used, including the subnet mask.  In my example above, the IP subnet to be used is 192.168.0.0 with a subnet mask of 255.255.255.0.  This essentially means that the subnet covers all IP addresses from 192.168.0.0 to 192.168.0.255 (a range of 254 IP addresses as .0 and .255 cannot be assigned to hosts).

The routers option corresponds to the default gateway address on a Windows computer.  It tells the client which computer to use when attempting to communicate with computers outside the local subnet. Again, in the example above, the firewall's IP address is used as it handles all communication between the local network and the internet.

Before explaining the range line, I will skip over it to the next line.  After you understand the next bit, this line will make more sense.

The host line in the example above specifies that a particular computer on my network be given a specific IP address that is matched to its name (through name resolution as described in the previous appendix).  In this case, the host named 'foobar' with the MAC (hardware) address of '01:11:4c:2b:79:ea' will the given the IP address 192.168.0.50.

In the example above, the fixed-address option refers to a specific IP address.  If you have configured name resolution for your machines, you can also put the client computer's name on this line instead of its IP address.  dhcpd will then resolve this name to an IP address and assign that IP address to the client.  The hardware ethernet portion refers to the specific client MAC address to match when granting the DHCP lease.

If you assign fixed IP addresses based on the hosts requesting them, you might also want to provide temporary IP addresses to clients that aren't a normal part of your network, such as when friends come over and plug into your network.  In this case, the range line I skipped earlier takes care of that.

In the example above, the range of IP addresses being used is 192.168.0.100 to 192.168.0.150.  Note that this range does not include the fixed IP address being assigned to the client 'foobar'.  This means that I can assign some IP addresses to temporary hosts without infringing upon the fixed IP addresses I hand out to my regular, permanent clients.

I have not explained everything you need to know about setting up the DHCP daemon but I hope I have provided you with enough information to get you well and truly on your way.  Before jumping in head first, I strongly recommend you read the manual pages for dhcpd and dhcpd.conf.  These should provide you with all the information you need to setup dhcpd but, if not, you should also read the appropriate section in the OpenBSD FAQ listed in my resources section at the end of this article.

 

More Resources:

This document aims only to give you the basic requirements to configure your OpenBSD computer as a firewall.  In the event of problems, or if you'd like more in-depth technical information, please consult the following resources:

http://www.openbsd.org - The home of OpenBSD and the OpenBSD FAQ.

http://whirlpool.net.au - Australian broadband user forums.

http://www.faqs.org/rfc/rfc1918.txt - RFC1918 discusses IP addresses that can only be used on a private network

http://bpalogin.sourceforge.net - The home of BPA Login.

http://cr.yp.to/djbdns.html - The home of DJBDNS.

http://public.pacbell.net/dedicated/cidr.html - Pacific Bell's guide to CIDR notation

Last Updated ( Friday, 19 June 2009 18:51 )