Troubleshooters.Com and T.C Linux Library and Steve's BSD Resources Present

OpenBSD/pf Firewalling
For the Less Gifted

Copyright (C) 2011 by Steve Litt, All rights reserved. Material provided as-is, use at your own risk. 



Steve Litt is the author of the Universal Troubleshooting Process Courseware,
which can be presented either by Steve or by your own trainers.

He is also the author of Troubleshooting Techniques of the Successful Technologist,
Rapid Learning: Secret Weapon of the Successful Technologist, and Samba Unleashed.


DISCLAIMER
The firewall produced by these instructions is intended to be moderately defensive, not extremely secure. Your firewall needs are determined by your setup and what you have to lose. The firewall described in this document may not be sufficient for your needs.

There may be mistakes in these instructions, and you might make mistakes following these instructions, and such mistakes might lead to penetration of your computer or network, which could lead to personal, business or financial loss. The author is not responsible for the outcome of your use of this document: Use at your own risk.

Contents

Introduction

Sorry about the disclaimer. It's a sign of the time. Now let's switch from law to technology...

If you're a Ninja network administrator this document offers you nothing. Just go install OpenBSD, enable port forwarding, set the Internet facing NIC for DHCP and the LAN facing NIC for a proper address on the LAN, set up a DHCP server with properly set DNS servers on the LAN facing NIC, and plug it in. Ellapsed time -- probably an hour -- less if you have some ultra fast way to install OpenBSD. About the only thing you can get from this document is a way of explaining firewalling to others.

If you're NOT a Ninja network administrator, this document is for you. It explains in step by step detail how to set up an OpenBSD/pf firewall to protect your LAN, plus it details a two level firewall testing framework for ultimate safety and protection, plus it explains the concepts of firewalling so if you later have to improve on the generic firewall described herein, you'll know just how to do it.

This document is very long, which may lead you to believe that building an OpenBSD/pf firewall is hugely complicated and not worth the effort. Such a belief is not accurate. The reason this document is long is so you understand everything about this firewall, avoid most dead ends, and if you do hit a dead end, you know how to get out of it.

But why should you hit dead ends? Simple: mistakes happen. Typos happen. Things are sometimes forgotten. If you were a Ninja network administrator you could look at the symptom and know the diagnostic tests necessary to find the problem. And you'd know which diagnostic tests are safe and which have the potential to let in network destroying trouble. If you were a Ninja network administrator, you could build an OpenBSD/pf using a 15 item checklist and reading between the lines.

But you're not a Ninja network administrator, so when everything appears to just stop working, you may experience one of those "what do I do now" moments, or even an "I give up" moment. This document gives you ideas how to safely diagnose your way out of problems. The Internet is full of 15 item checklists for BSD/pf. Some of them are wrong, and all of them are useless without quite a bit of foundational knowledge. This document takes little for granted, and tells you all. If you know the basics of networking, this document gives you a great opportunity to deploy an OpenBSD/pf firewall.

Which brings up the next question: Why would you want to deploy OpenBSD/pf? You have many options for firewalling. Walmart or CompUSA can sell you a decent dedicated low power firewall appliance for what, fifty bucks? If you want more configurability, there are seemingly endless Linux and BSD distributions solely dedicated to firewalling (with the obligatory router, gateway, DHCP server, port forwarding and NATting duties). IPCop, IPFire, MOnOwall,  PfSense, Smoothwall,  and many, many more.

Most of these options are much easier for an inexperienced person to install and configure than BSD's PF firewall because they put an abstraction layer between you and PF, or if it's a Linux distribution between you and IPTables. That's nice, and I definitely recommend using one of these for your first firewall, but after a while you'll notice that for less usual needs such as servers on your network, or OpenVPN, or many other situations, OpenBSD plus PF is the easier and more direct way to go. You'll notice that with an OpenBSD/pf firewall, almost anything is possible.You'll notice that although the other alternatives hold your hand, OpenBSD/pf is actually the simplest and most direct.

You'll also notice that if you go through this document and its associated checklist outline, you'll understand firewalling. That means when a new need comes up, you'll have the knowledge to adapt your firewall to the need. And it means that you've taken one step closer to network administrator Ninjahood.

This document comes in three parts:
Part I covers the basics so you can understand the instructions and have enough foundational knowledge to be able to devise diagnostic tests if you need to troubleshoot. Part II gives the nitty gritty details on how to build your OpenBSD/pf firewall/router/gateway, but with enough details and specificity that you know exactly how to do it. Part III is for reference, later, after you've built your OpenBSD/pf.

PART I: CONCEPTS

Part I consists of the following sections:
The assumptions section tells you what's necessary in order to use this document. The Vocabulary section is a quick review of terminology necessary to understand this and other firewalling documents. The Essential Principles section gives you the foundational knowledge to understand the procedures you'll perform in Part II.

Assumptions

In writing this document I'm making some assumptions:
The assumption about an existing firewall/router has two reasons:
  1. Your first firewall should be more "user friendly" than OpenBSD/pf.
  2. An existing firewalled LAN enables you to do the two level testing and troubleshooting that's essential to keeping badguys off your LAN, both while you're testing and troubleshooting, and forever after. Remember that if your OpenBSD/pf machine is compromised during testing, that compromise could come back to bite your whole LAN days, weeks, or years later.
All the examples in this document use the following IP address characteristics:
I suggest you create a chart of all these values as they exist in this document, and cross reference them to the same values as they exist on your existing LAN.

Vocabulary

Before going on it's probably a good idea to lay down some definitions. As described in this document, your OpenBSD/pf box will simultaneously act as your LAN's firewall, a gateway, a router, and a DHCP server.
Firewall

Hardware or software that blocks Ethernet packets deemed likely to be dangerous
Router

A device that forwards Ethernet packets between two networks or subnets
Gateway

Pretty much the same thing as a router, but the point of reference is different, in that the gateway is seen from the point of reference of its own network. In other words, your OpenBSD/pf box will be a router, and specifically it will be the router that's the gateway to the Internet.
DHCP

Dynamic Host Configuration Protocol. This is a protocol in which a computer gets its IP address and maybe quite a few other things assigned to it when it plugs into a network or wirelessly connects to a Wifi access point. Here's how it works. The computer has a DHCP client, and one computer on the network has a DHCP server. When the computer plugs in, its DHCP client sends out a message saying "what's my IP address and other info?" The network's DHCP server sends back the IP address it assigns to the computer, along with possibly other optional information:
  • Computer's host name
  • Computer's DNS client query addresses (/etc/resolv.conf)
  • Computer's default gateway (typically the same as that for the network)
You will configure your OpenBSD/pf box to be the network's DHCP server.
Private
IP
space

Three blocks of IP addresses which are disallowed on the Internet, but allowed to be used, without registration,
Internet Assigned Numbers Authority
Also called IANA, this is the organization that distributes blocks of IP addresses to different entities (usually larger companies who may re-assign smaller blocks and individual addresses to others). IP addresses used on the Internet MUST be assigned by IANA.
Private
IP
addresses

These are three blocks of IP addresses which IANA and everyone else has agreed can be used privately as long as they are kept off the Internet. They're called "private" because they can be used only privately within a company, and not in the "public" Internet. The three address blocks are:
  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16
Public
IP
addresses

Address assigned by IANA to companies to be used on the Internet.
Public/
private
paradox

"Private" addresses can be use by anyone and everyone, whereas "public" addresses can be used only by the company that's been assigned them. Here's how you explain that apparent paradox: Private addresses are to be used ONLY within the privacy of their own private network, and NEVER used on the public network (Internet), whereas public addresses can be used on the public network (Internet). So the word public or private refers to where they're being used, not to who's using them.
NAT
Network Address Translation. A way to "multiplex" all the private IP addresses on your LAN onto the address with which you hit the Internet (the IP address coming out of your cable modem). You'll learn more about NAT in the Essential Principles section of this document.







Essential Principles

Firewalling, NATting and port forwarding are complex things, so a high level understanding of these concepts will make the difference between success and failure building a OpenBSD/pf firewall.

Two NICs, Four Directions

A simple two zone firewall has an external interface (NIC) going out to the Internet, and an internal interface (NIC) going out to your local LAN. Did you notice I said "going out to" in both cases? That's how the PF firewall looks at everything -- from the perspective of the OpenBSD box, which in this case is a firewall. Traditionally the external interface to the Internet is represented by a variable (macro to be more specific) called $ext_if, while the internal interface to the local LAN is represented by macro $int_if. These names are arbitrary -- you could call them $tom and $jerry if you want, but the standard is $ext_if and $int_if.

Consider the following diagram:
Data flow through the firewall
Gaze at the preceding diagram until you understand, in your very soul, that the terms "in" and "out", as used in the pf.conf file, are relative to the BSD/pf firewall, not to the LAN. If you don't understand that intuitively, you'll have a lousy time making your pf.conf file.

So the two NICs are $ext_if and $int_if, and the four directions are:

Keep it Simple, VERY Simple

Firewalls that do Network Address Translation (NAT) and Port Forwarding are incredibly complex, with numerous and inobvious variables. There's lots of stuff that can go wrong, and usually does go wrong, and when it does, it's hard to troubleshoot because diagnostic tests are expensive in terms of time, setup, and inconvenience to everyone. In a SOHO type situation, if you take down your current firewall/router to test your new one, everybody goes offline, and if they're anything like my wife and kids, they scream bloody murder. If you're in a running small business with employees, it's worse.

So this document walks you through creation of a very simple firewall/router in the hopes that you can get it operational very quickly. After that, if you want, you can add one feature at a time, testing as necessary and putting it back if things screw up.

Here are some of the simplifications this document makes:
It's my belief, at least in my situation, that the preceding pass/block are reasonably safe, at least as a start. My belief is that adding more rules before you have a working system can turn this project into a time sucking tar baby. Once you have a working firewall, you can add new features one at a time.

What's In and What's Out?

The next point you must understand is that, although TCP and UDP connections are a two way communication, as far as pf.conf is concerned, the direction is governed by the first contact. This is because the PF firewall keeps track of state, so if you query http://www.troubleshooters.com and http://www.troubleshooters.com sends data back to you, the PF firewalling software has enough smarts to remember that you asked for Troubleshooters.Com's information and it's just replying, so PF considers the entire communication as outgoing from the firewall to http://www.troubleshooters.com. What does NOT happen is the firewall considereing the response to be incoming.

Please remember this. All computer communication goes back and forth. The factor that determines whether a packet is considered incoming or outgoing for the purpose of firewalling is not the source and destination of the packet, but the source and destination of the packet that initiated the conversation. Without that understanding you're dead meat!

Let's go through this one more time. You query http://www.troubleshooters.com. PF remembers enough from your initial query that when the response comes, PF says "oh, I already know this is a response to a known query going out, so I'll consider it outgoing." PF does this even if your pf.conf bans all traffic in from the Internet, because it doesn't consider Troubleshooters.Com's response incoming on the external interface -- it considers it part of an outgoing conversation on the external interface. It's vitally important you understand this.

By the way, I know that UDP is stateless, but the PF firewalling software has ways of "remembering" who sent what and "recognizing" a UDP response to a sent out query.

Once again, the terms "in" and "out" refer to entire conversations, not to specific responses. It's vital you understand this.

Now let's see how this fits into the "Keep it Simple" philosophy discussed earlier. Basically, this document assumes your LAN's users are at least somewhat intelligent and responsible. They don't cruise the Internet looking for porn, warez, and all the other creeping crud that installs malware on their computers. They don't use Outlook (you don't let them use Outlook, do you?) and they don't click on unknown attachments. Last but not least, because you're reading this on Linux friendly Troubleshooters.Com, there's an assumption that at least a good portion of your LAN is comprised of Linux computers rather than virus prone Windows computers. In short, your users don't go out looking for trouble.

Therefore, we assume that any communications on the LAN itself are OK. We assume that any communications from your users to the Internet are OK. The only thing that's not OK are spontaneous communications from the Internet to your users or firewall -- that's not OK -- why would anyone have a reason for instituting communication with your LAN or firewall. This paragraph is why we set the firewall pass/block rules at:
Almost always, servers listen for communication, and respond after a client calls them. Therefore, a good rule of thumb is that conversations start with a communication from client to server. And typically servers don't try to reach in and mess with your network -- clients do that. Therefore, for the most part, the only time you need to restrict outgoing traffic out of the external interface is one of these two situations:

1) You're hosting servers on your firewall or your LAN and don't want them sending private or dangerous information to just anybody
2) You don't trust your users not to access dangerous servers

In other words, if you have an FTP server on the LAN, you're darned well going to restrict who can access it.

But more to the point, as computers on your LAN become infected with viruses, they can acquire dangerous servers. Thus, for instance, a virus installed keylogger stores info and maintains a server listening for the badguy to come in on some port or whatever with just the right query. When that happens, the keylogger sends all your keystrokes. There go all your passwords, including those to your bank accounts. You're in trouble.

To combat that, you might implement a rule against traffic out of the external interface, so the server can't send the stuff out. If your LAN has the kind of users who download anything and everything, open any email from anybody, use Outlook Express, and are just plain careless, you might need to limit their ability to send to the Internet, or more precisely, their traffic in on the internal interface. You can recognize them by IP address or other ways.

Network Address Translation (NAT)

In an ideal (or maybe not so ideal) world, every device would have its own, registered IP address, so any device could contact any other device. Maybe that will happen when the world moves to the IPV6 addressing standard, but right now most everyone's on the IPV4 addressing standard, which is already nearly out of IP addresses.  Therefore, most homes have only one IP address (usually assigned only temporarily), and most non-home businesses have either one fixed IP address, or a small block of them. Bottom line, there are many more computers than there are possible IP addresses.

But good news. Long ago they saw this problem coming down the pipeline and created an innovative solution: Private Addressing Spaces. Private addressing spaces are three blocks of IP addresses that are not registered with the Internet authorities but instead can be used *INTERNALLY* by any home or business, as long as such addresses are kept internal and now allowed to escape onto the Internet. Those three private address spaces are:
If you notice, all this document's existing LAN addresses start with 192.168.100. They're part of the third above listed block of private addressing space. This document's "new test LAN" has addresses that start with 192.168.200. Once again, part of the third above listed block of private addressing space.

OK, so you're sitting here with about twelve computers, each needing to access the Internet, but with IP addresses that can't go onto the Internet. They all go through a single IP address assigned your house. How can that be done?

The answer is Network Address Translation, or NAT, which is done in the firewall. Note that in the setup described by this document, the firewall is also the LAN's gateway. NAT is a technique by which the NAT box changes the private address of the sending computer to the address of the NAT box's Internet facing NIC, and changes the source port to an arbitrary high number. These values and some others are stored in the "Network Address Translation Table" so that when responses come in, they can be remembered and changed in reverse. See the following graphic:
Graphic of how NAT works
In the preceding graphic, all boxes without background are packets. Those with background are computers. The computer at 192.168.100.2 sends an HTTP query to the website at 5.5.5.5. It sends it out the gateway address 192.168.100.96, where NAT changes its source IP address to the NAT's Internet facing address, in this case 9.9.9.9, and its source port to a random unused high port number, in this case 65432. This port number is recorded in the NAT table so responses can be recognized.

The computer at 5.5.5.5 receives the packet, which it thinks came from 9.9.9.9 at port 65432, and does what it always does, replies to the packet, switching the source and destination data. So it sends back a packet whose source address is 5.5.5.5 and source port is 80, to destination address 9.9.9.9, port 65432. That packet goes to the NAT, whose software looks up port 65432 in its NAT table to find out that corresponds to port 39000 on computer 192.168.100.2, and it forwards the packet there. So the computer at 192.168.100.2 receives the packet appearing to be from 5.5.5.5 at port 80, and processes it.

Thus, the server at 5.5.5.5 thinks it's talking directly to 9.9.9.9 port 65432, and has no idea its responses are being forwarded to 192.168.100.2.

One more thing. It's not symetrical. 192.168.100.2 can initiate a conversation with to 5.5.5.5, but 5.5.5.5 cannot initiate a conversation with to 192.168.100.2. The only way for an Internet entity to initiate a conversation with 192.168.100.2 would be to initiate a conversation with the firewall (9.9.9.9) at a certain port (let's say port 22), and have the firewall have a port forwarding rule that forwards the request to 192.168.100.2. Be very careful with port forwarding -- it can backfire on you security wise.

Dual Level Testing: Do It Safely

The "hows" of dual level testing are explained in later sections. This subsection discusses the "whats" and "whys".

You know what the truly fearless among us would do? After configuring the OpenBSD/pf box, they'd disconnect their current firewall, take their newly configured OpenBSD/pf box, plug the Internet facing NIC into their cable modem, their LAN facing NIC into their Lan, and fire it up. If it works, great, they've just saved themselves hours of testing and reconfiguration. If it fails, they can just keep switching things around til it does, or set the firewall wide open and then just keep narrowing things until they discover what was blocking them. Carpe Diem: Seize the Day!

I'm not that fearless, and I hope you're not either. Because that fearless fellow has a natural enemy with a Latin slogan of his own: Veni, vidi, vici: I came, I saw, I conquered. While the courageous commando seizes the day by connecting his LAN to the Internet through his not-ready-for-prime-time firewall, perhaps for minutes at a time partially or fully disabling the firewall, an army of thousands of script-kiddies, crackers, badbots, organized crime cyber profiteers, and other badguys of every stripe are coming to his firewall, seeing what's there with nmap or other techniques, and conquering if they find a chink in the firewall's armor. Depending on that chink, they might be able to compromize any and all machines on the LAN, and maybe the OpenBSD/pf firewall itself itself. Think about it: if our hero leaves the firewall up for three minutes with no guard against incoming ftp and telnet, the attacker can leave a root kit for later use.

Being compromized is kind of like radiation. You can't see it. You can't feel it. But it's there, getting you sicker and sicker as time goes on. Or, maybe like radiation caused cancer, it sits there for months until all of a sudden makes you violently ill and kills you.

For all these reasons, in this document I espouse dual level testing, where in the first level your new box's Internet NIC is plugged into your existing LAN, which is protected by your current firewall. In this level, which can be called "simulation mode", you can test almost everything about your new firewall, and troubleshoot it to your hearts content, including running the thing wide open, and you'll still be as safe as your current firewall. As an added bonus, when testing in simulation mode, your LAN stays up so you don't have people yelling at you to hurry up -- a sure recipe for trouble. Another bonus -- you can do penetration testing from your LAN through the BSD/pf box to your test computer without violating anyone's terms of service.

Once it's up and working in simulation mode, you go to the second level, which is just like running it live except that instead of the firewall feeding your LAN, it feeds one test machine that contains no valuable or private data and can easily be reformatted. I call it "live Internet, test client" mode. Illustrations and simple explanations follow.
Simulation Mode
Live Internet with Test Computer
Simulation mode: First level of testing  
Live internet with test computer
NOTE: The newly created LAN is physically separate from the existing LAN.
Simulation Mode
Live Internet with Test Computer
The Internet NIC of the pf box plugs into the existing LAN, gets an address from the existing LAN's DHCP server, then serves out an address to the test computer on a different subnet via the pf box's DHCP server. Advantages are:
  • No matter what's done to the pf box during testing or troubleshooting, it's as safe as the existing LAN's firewall.
  • You needn't take down your existing LAN while doing simulation mode testing, nor kick your LAN's users off the Internet.
  • It's easier to simulate Internet badguys from your own LAN than from the Internet, and you don't have to explain your activites to the owner of the facility from which you do your penetration testing.
  • You don't violate anyone's terms of service (TOS).
  • It can be done with just a few changes to pf.conf, hosts, hostname.re0 (or whatever the file extension for the LAN facing NIC), and dhcpd.conf. This will be explained in the next section of this document.
  • Once the system's passed the simulation mode level of testing, it's a pretty good bet that if you reverse the changes to pf.conf, hosts, hostname.re0, and dhcpd.conf., it will pass the Live Internet Test Computer mode level of testing immediately.

After your OpenBSD/pf box passes all the simulation mode tests, you reverse out the changes you made for simulation mode, and then run it live against the Internet. This means you disconnect the current firewall from the cable modem, and instead connect the WAN facing NIC of the BSD/pf box to the cable modem. You then connect the test box to the BSD/pf box's LAN facing NIC in order to simulate the existing LAN without letting any bad stuff onto it.

So, just to be clear, the existing LAN goes on with its life, but without a connection to the Internet. The new simulated LAN immitates the current LAN, complete with the same netmask and DNS servers, but the simulated LAN is completely physically separated from the existing LAN, so they can't interfere with each other, they can't ping each other, they can't see each other. This is why, at least for this test, you can't use a DNS server on the existing LAN. Later, when testing's complete, you can.

The beauty of the test computer is if something is wrong, instead of getting every machine on your LAN infected, you just infect your test computer.

PART II: PROCEDURES

At the very highest level, here is the process by which you make and deploy your new OpenBSD/pf firewall:
  1. Build, install and configure your box
  2. Test and troubleshoot in Simulation Mode with your current LAN connected to the PF box's Internet facing NIC.
  3. Test and troubleshoot in Live Internet Test Computer Mode with the PF box's Internet facing NIC connected to the cable modem and the LAN facing NIC connected to a single test computer.
  4. Connect the LAN facing NIC to the existing LAN so that now the PF box has replaced your existing firewall. Watch the logs very carefully the first couple weeks.
  5. As time goes on, add and test rules one at a time to increase security for specifics like careless users and Windows computers, or to implement additional zones for Wifi or DMZ, or to make redirection pinholes for incoming SSH, mail server or web server.
Read the preceding to understand the lay of the land. But when you want an actual roadmap of how to set up an OpenBSD/pf box, use the following:
The preceding are not only a roadmap, they're also your table of contents for Part II. Read on...

Build the OpenBSD/pf Box

Building the box is straightforward. You need a hard disk at least 1 GB in capacity. In SOHO environment probably 512K of RAM and a 1GHz processor are sufficient. In other words, it's probable that anything new enough to be reliable is good enough for this firewall. You're also going to need two different NICs. Sometimes the one on the motherboard can be used, but sometimes OpenBSD won't work with it. So be prepared with two daughterboard NICs, preferably of a different type so they're easy to tell apart in config files and physically.

Last but not least, you'll need a case, power supply and the like. If you're going spend money on this firewall, it makes sense to get a small, low power computer to save on electricity, space, and noise. If you're using a computer you have laying around, go for it.

Install the Software

Start by connecting one of the NICs to your current DHCP serving LAN. Then make yourself an OpenBSD 4.8 install CD. Get the install48.iso file for your particular platform (i386, amd64, etc) from a nearby mirror listed at http://openbsd.org/ftp.html. Burn the CD from the ISO and boot the CD, which walks you through the installation.

For the most part, take the defaults. Add a non-root user,  say no root ssh, and say no to X. meaning all the packages that begin with x, as well as the games package. Tell the installation that the plugged in NIC is a DHCP client. If asked, configure the (so far) unused NIC to an unused address on your LAN's subnet. You can configure it more accurately later. When asked for the domain, put the domain of your subnet.  When asked for the hostname, put bsdpf or something like that.

If you find software you need but don't have, you can get it by typing the following command:
pkg_add <software-name>
For instance, you'll probably want the irssi IRC client so you can talk to people from your BSD box when your regular firewall is down. The following is a pkg_add session to install it:
# pkg_add irssi    
Ambiguous: irssi could be irssi-0.8.15-socks irssi-0.8.15
# pkg_add irssi-0.8.15
irssi-0.8.15: ok
#
As you notice, I got the name wrong and it gave me hints. When your firewall is about to go live, you probably want to get rid of irssi, so do this:
pkg_delete irssi
You can find what packages have been installed via pkg_add with this command:
pkg_info

Configure the Box

Before you start configuring there are several things you need to figure out:
Simulation mode: First level of testing  
A few notes about the preceding. The simulation testing LAN can be seen in the upper right on the diagram on the left, labelled "Newly created LAN". Its subnet must not be the same as the existing LAN, shown at the bottom of the diagram. The diagram shows the numbers used in the examples of this document.
The NIC device names are important because they're used in several config files and as extensions in the hostname.<devicename> files. Be sure you know which devicename faces the Internet and which faces the LAN. Remember in the diagram above, the Internet facing NIC is connected to the current LAN, because the current LAN is simulating the Internet.

One of the great things about OpenBSD is all configuration is done with files, most of it within the /etc directory. The configuration of your firewall involves these files -- all are in /etc except dhcpd.leases, which isn't even a config file but still must be created:
Now let's discuss specific changes to these files. All these changes put the firewall in the live mode. Later we'll change them for the simulation mode:

/var/db/dhcpd.leases         

All you have to do is make sure this file exists, so you use the following command:
touch /var/db/dhcpd.leases

hosts

Add Lines for test and live firewall IP address:
192.168.100.96 bsdpf.domain.cxm bsdpf   ## LIVE
#192.168.200.96 bsdpf.domain.cxm bsdpf ## TEST

hostname.<devicename> (for Internet facing NIC)

In this document, the devicename for the Internet facing NIC is rl0, so the filename is hostname.rlo. It's a DHCP client, so the file contains just the following:
dhcp
The way  a lot of people do that is just to echo the string in:
echo dhcp > /etc/hostname.rl0

hostname.<devicename> (for LAN facing NIC)

In this document, the devicename for the Internet facing NIC is re0, so the filename is hostname.reo. It's hard coded to address 192.168.100.96 for live, production service, but for simulation testing it's hard coded to 192.168.200.96. Therefore, its contents look like this:
inet 192.168.100.96 255.255.255.0  192.168.100.255  # LIVE
#inet 192.168.200.96 255.255.255.0 192.168.200.255 # TEST
So each line contains these four items in order:
  1. The interface type, in this case inet
  2. The IP address of the interface
  3. The netmask of the interface (255.255.255.0)
  4. The broadcast address
  5. Optional comment telling its use so you know which one to uncomment
Be SURE to include the broadcast address. The NIC will silently fail to start if you don't.

sysctl.conf

Back up the file to sysctl.conf.org, and then in sysctl.conf uncomment the line that begins with:
net.inet.ip.forwarding=1
Doing this enables port forwarding.

rc.conf.local

Anything in this file completely overrides what's in rc.conf. In this way, you can leave the fairly long and complex rc.conf alone and just see your changes in rc.conf.local. It's an excellent idea, in my opinion. The rc.conf and rc.conf.local files determine what services boot up. Here's what yours should look like to make an OpenBSD/pf box:
dhcpd_flags="re0"
#dhcpd_flags=NO
The first line declares that you will have a DHCP server on interface re0, which in this example is the LAN facing NIC. The second line would say, if it weren't commented out, that there's no DHCP server. If at any time you want to turn off DHCP serving you can switch the hash sign to switch which line is commented, and then reboot the box.

Please remember that file /var/db/dhcpd.leases must exist, so make sure it does. If it doesn't, make it with this command:
touch /var/db/dhcpd.leases

dhcpd.conf        

Before doing this, one way or another get the IP addresses of two known good Internet DNS servers. This turns out to be much harder than you'd imagine, because today most ISPs for some reason don't list their DNS servers in their support sections. Maybe they figure you're always using DHCP on everything, or maybe they just don't care. If you can't quickly find your ISP's DNS server IP addresses, my suggestion would be to use a "public DNS" as listed in these two documents:
In this example I've used 65.32.5.111 and 65.32.5.112. You'll need to insert these in your option domain-name-servers statement.

First we'll show the contents of the file, and then discuss them:


#       $OpenBSD: dhcpd.conf,v 1.2 2008/10/03 11:41:21 sthen Exp $
#
# DHCP server options.
# See dhcpd.conf(5) and dhcpd(8) for more information.
#

option domain-name "domain.cxm";
option domain-name-servers 65.32.5.111, 65.32.5.112;

## LIVE DHCPD SUBNET
subnet 192.168.100.0 netmask 255.255.255.0 {
option routers 192.168.100.96;

range 192.168.100.230 192.168.100.239;
}

## TEST DHCPD SUBNET
subnet 192.168.200.0 netmask 255.255.255.0 {
option routers 192.168.200.96;

range 192.168.200.230 192.168.200.239;
}


You already know from file rc.conf.local that any DHCP server will be on the LAN facing NIC. This file declares DHCP services on two subnets: 192.168.100.0/24 and 192.168.200.0/24. In each case, it serves out DHCP leases between .230 and .239. Notice that this is a different range from the current firewall, which in this example serves leases between 240 and 249.

Each subnet serves out a router on its subnet: 192.168.100.96 for live production, and 192.168.200.96 for simulation test mode.

Last but not least are the domain names above both subnet declarations, setting the domain name sent to clients to be domain.cxm and the DNS servers sent to both clients to be 65.32.5.111 and 65.32.5.112. You'll notice these are not DNS servers on my LAN (there are two boxes on my LAN with djbdns servers). In testing the LAN isn't available for DNS service, so what you must do is pass two known good DNS servers. The best way is to use those documented by your ISP (after testing to make sure they work).

You don't need to comment or uncomment anything when switching from live to simulation. This is because in live mode, the LAN facing NIC is constrained by hostname.re0 (or whatever your config file's extension) to be in the 192.168.100 (or whatever it is on your LAN) subnet, so the other DHCP subnet never gets exercised. In simulation mode, the existing LAN indeed has a 192.168.100 subnet, but that never touches the LAN facing NIC, which is the NIC that is the DHCP server. In simulation mode, hostname.re0 constrains this NIC to the 192.168.200 subnet.

myname

Put in the desired host and domain name. Here's what it looks like in this example:
bsdpf.domain.cxm

dhclient.conf

This file will have a bunch of comments. At the very end, insert two lines like these:
request subnet-mask, broadcast-address, time-offset, routers, domain-name, domain-name-servers;
require subnet-mask, domain-name-servers, routers;
You can request anything you want, but clients of your OpenBSD/pf box's DHCP server absolutely must know their domain-name-servers.

pf.conf

This is the big kahuna, the firewall definition. Remember the "Keep It Simple" subsection back in section Essential Principles? I guarantee you that if you're just an ordinary guy and not a Network Ninja, trying to throw in every last feature before getting everything running will frustrate you for days or weeks. Initially make it simple: NATting, simple packet scrubbing and antispoofing, dropping packets sent to or from private networks in the Internet (a clear illegality), dropping packets intended for your LAN's internal private network (the only way they should be able to see an internal host is via redirection/forwarding), and the simple philosophy discussed in Keep It Simple:
One other principle you should know is that in the pf.conf file, when two rules contradict, the later one determines. So I implemented the simple "all open except in from the Net" this way:

block log all
pass on $int_if all
pass out on $ext_if all

The first line allows in all traffic on all interfaces. The third contradicts it for the purpose of $ext_if,  the Internet facing NIC, blocking all incoming traffic from that interface.

However, you can override the "last rule takes precidence" technology with the use of the quick keyword. If, going down the rules, you match a quick rule, then all further rules are disregarded.

The following is the contents of the pf.conf file when set up live direct to the Internet. It will be explained later:


# STEVE LITT'S ULTRASIMPLE pf.conf

# MACROS
ext_if="rl0"
int_if="re0"
lan_ip="192.168.100.0/24"

private_networks="{ 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 255.255.255.255/32, 127.0.0.0/8 }"

# SCRUB PACKETS
match in all scrub (no-df)
match out all scrub (random-id)

# SET UP NAT: 4.8 SYNTAX
match out on $ext_if from $lan_ip nat-to ($ext_if)  #LIVE
#match out on $ext_if from !($ext_if) nat-to ($ext_if)  #TEST

# IPV6 CURRENTLY IRRELEVANT, DROP IT **QUICK**
block drop in quick inet6

# ANTISPOOF **QUICK**
antispoof log quick for { $ext_if } inet

# DEFAULT IS BLOCK IN FROM INTERNET, PASS ALL ELSE
block log all
pass on $int_if all
pass out on $ext_if all

# SKIP LOOPBACK
set skip on lo0

# ALLOW ALL ICMP EXCEPT REDIRECTS
pass in inet proto icmp all
block in log on $ext_if inet proto icmp all icmp-type redir

# BLOCK THE OBVIOUSLY BOGUS **QUICK**
#block in quick log on $ext_if from any to 192.168.200.0/24  #TEST
block in quick log on $ext_if from no-route to any
block in quick log on $ext_if from any to 255.255.255.255
block in quick log on $ext_if from any to $private_networks
block in quick log on $ext_if from $private_networks to any
block return out quick log on $ext_if from any to $private_networks
# COMMENT OUT THE PRECEDING 3 LINES WHEN TESTING THE INTERNET FACING
# NIC ON THE LAN IN ORDER TO SIMULATE THE INTERNET,
# UNCOMMENT THEM FOR LIVE PRODUCTION

# ALLOW INTERNET QUERIES TO FIREWALL'S SAFE INTENTIONAL SERVERS
#pass in on $ext_if proto tcp from any to any port {22}



I'm going to pretend that all of the preceding is self explanetory until the part about NATting. The problem with NATting is its syntax changed recently. The syntax above is for OpenBSD 4.8. The syntax I marked as "Test" will work in live production situations, but the one marked "Live" is a little more restrictive, so that's better for live. But for testing, the live one would fail to transfer.

The next thing needing explanation is the part about defaults for TCP and UDP. I defaulted the firewall to block in from Internet, pass everything else. For IMCP, I set it to pass everything except redirects.

Now look at the part labelled "block the obviously bogus". The first of those lines is used only in simulation testing, to prevent someone from setting up a route from 192.168.100.2 to, let's say, 192.168.200.230 though 192.168.100.249. Without that line, from the existing LAN, I can have my way with the test computer -- the equivalent of putting a  Windows computer on the Internet with no firewall at all. What could possibly go wrong?

Look at the last three lines of the "obviously bogus" section. The first of those three block rules prevents anything from the Internet trying to access your private networks. In live mode this does everything discussed in the preceding paragraph, but in simulation mode it doesn't work because the firewall's Internet facing NIC has a private address, so it has to be commented out. That's why in simulation mode you need the rule preventing the outside from reaching into your LAN and accessing 192.168.200.0/24 -- to substitute for the more inclusive rule that blocks reaching in for ANY private address.

For the same reason, the second of those lines must be commented out. Any packet on the Internet purporting itself to be from a private address is no good. But of course in simulation mode everything coming in is from your LAN and must be commented out.

Same with the third of those three lines. It's there to prevent something on your LAN from reaching out to a private address on the Internet. And like the other two, it must be commented out for simulation test mode.

The pf.conf given in this section is for live use, as is everything in this section. But before doing any live testing, you need to do simulation testing, and to do that you need to make some changes to several of these files. Read on...

Do Simulation Mode Testing


Simulation Mode

Simulation mode: First level of testing
 
Simulation mode is as safe as the existing firewall, which of course we all hope is safe indeed. You have to plug the new BSD/pf machine's Internet facing NIC into a hub or switch on the existing, firewall protected LAN. Changes are made so the LAN facing NIC outputs on a different subnet, 192.168.200.0/24 in the illustration.

Then you begin your tests, with your existing LAN acting as the Internet and the test machine acting as your future LAN.
To accommodate simulation mode, the following changes must be made to files in the /etc directory:
Now that you have the BSD box configured for simulation testing, perform your simulation tests. They are very thorough because hopefully, if you pass all the simulation tests, you'll easily pass the live internet test computer tests with flying colors. Most of the simulation tests are performed without using the test box because they don't test NAT or DHCD server. Those not using the test box follow:
IF YOU GOT THIS FAR, your BSD machine's firewall and DHCP client are working correctly. Now it's time to test the BSD machine's NAT capabilities and DHCP server, using a test machine.
IF YOU GOT THIS FAR, your OpenBSD/pf machine's NAT and DHCP server are functioning correctly. Next, for extra credit, and even though I said port redirection was beyond the scope of this document, let's do a quick port redirection exercise.

Extra Credit: Port Redirection Exercise

Don't do this until the simulation mode tests all passed. Now, with /etc/pf.conf just the way you left it, add this one line to the bottom of /etc/pf.conf:
pass  in on $ext_if proto tcp from any to $ext_if port 22 rdr-to 192.168.200.230 port 22
In the preceding command, substitute your test box's IP address for the 192.168.200.230. What the preceding command says is that if any TCP packet with destination port 22 comes in from the Internet facing NIC, redirect it to port 22 on the test machine's IP address.

Now, on the BSD/pf box, reset PF with this command:
pfctl -f /etc/pf.conf
Make sure you have a non-root login on the test machine, and if not, make one.

From a Linux machine on the existing LAN, ssh into the IP address of your BSD/pf machine's Internet facing NIC. In this example it would be 192.168.100.249. This address was provided by your existing LAN's DHCP server. If you remember, you ssh'ed into it a few tests ago. But this time, when asked for the username, put your username on the test machine. Same with the password. If the stars are smiling on you, you'll be logged into your test machine, meaning you penetrated into the other side of the NAT (use uname -a to verify). 

But another likely result is that you'll get an error something like this well known problem:

root@mydesk:~# ssh slitt@192.168.100.249
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
07:9b:b9:27:58:87:49:8c:54:80:3b:98:06:47:3e:de.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending key in /root/.ssh/known_hosts:7
RSA host key for 192.168.100.249 has changed and you have requested strict checking.
Host key verification failed.
root@mydesk:~#



Here's what this error means. Your .ssh/known_hosts file has the credentials of your BSD/pf box from the last time you sshed into it. But now when you ssh into that same IP address, you're actually sshing into the test machine so you get the test machine's credentials, which don't match what's stored, so of course your client thinks someone's trying a man in the middle attack even though you know better. So here's what you do, on the machine from which you're trying to ssh, to get past this:
  1. ssh-keygen -H -F 192.168.100.249 to see the auth data for that IP address
  2. Copy to clipboard at least twenty characters from the output
  3. Edit $HOME/.ssh/known hosts
  4. Search for the string you copied to clipboard, and make sure it happens only once in known_hosts.
  5. If it occurs only once, delete that record (dd in Vim). If it occurs more than once, investigate.
  6. Save the file and exit the editor
Now when you try the ssh command it should work. Once you get in, do a uname -a command to verify you're really on the experimental computer. If so, you've done port forwarding. If not, troubleshoot.

Now put the file back the way it was. Delete the line you just put on the bottom of pf.conf., and restart PF with pfctl -f /etc/pf.conf. Note that if you now try to ssh back in you'll get the same known_hosts error and have to solve it the same way.

So Far So Good

You're almost done. You created a firewall, connected it to your existing LAN to simulate the Internet, and proved it could do firewalling, NAT, DHCP server to a new LAN, and redirection/port forwarding. Now, by undoing the changes made in order to do the simulation testing, you can connect this firewall directly to the Internet (through your cable modem or whatever), test briefly with your test box representing the LAN, and then connect the LAN where the test box was, and let your OpenBSD/pf box begin its daily duty as your firewall.

Warning:

Do NOT yet rewire things so your OpenBSD/pf is plugged into your cable modem. If you were to do that before reworking all files to get back into live mode, a script kiddie might come in and own you.

Do Live Internet, Test Computer Mode Testing

WARNING
Do not wire the OpenBSD/pf box into the cable modem until told to do so. Wiring it in early can allow a badguy to come in and own your computer!


Live Internet, Test Computer mode
 
The diagram at the left describes the Live Internet, Test Computer mode of testing, except that the test computer plugs right into the LAN facing NIC of the BSD/pf.

Before you do anything else, you first have to reset everything back to its original "live" settings. Read on...

Reconfigure for Live Internet, Test Computer

Test the New Configuration

If you haven't done so, make sure your configuration is correct as described in the preceding subsection. Now rewire everything:
Now you're ready to begin testing. Log in as root.
Now you've proven to a reasonable degree (the best you can do without penetration tests) that the BSD/pf box's DHCP client and firewall work properly. Now it's time to test NAT and DHCPD server.

Use As a Real Firewall

If all your tests worked with the BSD/pf hooked directly to the Internet, the next step is to start using your new OpenBSD/pf firewall as it was intended, sitting between the Internet and your LAN. So unplug your LAN facing NIC from the test machine and plug it into a switch port on your LAN, and start using your new firewall.

As time goes on and you need to further refine your firewall, keep in mind all the principles you've learned in this document.

PART III: REFERENCE

Part III is a quick reference for after you've built your firewall and want to change it. It consists of the following sections:

Files

This section contains listings of the relevant files. Note that in all these files, re0 is the NIC facing the LAN, rl0 is the NIC facing the Internet, the LAN is in subnet 192.168.100.0/24, and the test subnet is 192.168.200.0/24. You'll need to change these to fit your own situation.

Filename
Description
Contents
rc.conf.local Everything in this file overrides rc.conf. This is where you enable or disable services, or give information about services.

The file on the right enables a DHCP server on re0, the LAN facing NIC. You can switch the comment to disable the DHCP server if needed, and you can uncomment the pf line to disable pf for diagnostic tests. Note that if you disable pf and connect directly to the Internet, you've just compromised your OpenBSD/pf box and really should reformat it, along with anything that was connected to it.
dhcpd_flags="re0"
#dhcpd_flags=NO
#pf=NO
sysctl.conf This is where you enable port forwarding. To enable port forwarding, just uncomment the line that looks like:
#net.inet.ip.forwarding=1




myname The BSD box's hostname
bsdpf.domain.cxm
hosts Quick internal name resolution
click
hostname.rl0 The NIC config for the Internet facing NIC, a DHCP client. Note that in your case the file extension will probably be different. NICs are named by manufacturer and order, so every computer has different names for their NICs. dhcp
hostname.re0
The NIC config for the LAN facing NIC, hard wired to an IP address. To implement a hard wired config, the line starts with the word "inet", then the IP address of the NIC, then the netmask of the NIC, and finally the broadcast IP address for the NIC. Note that in your case the file extension will probably be different. NICs are named by manufacturer and order, so every computer has different names for their NICs.
Click
dhclient.conf This defines what information a DHCP client acquires from its server. In this case the DHCP client is attached to the Internet facing NIC, and the DHCP server is at your ISP.
Click
dhcpd.conf This defines what information a DHCP server sends to its clients. In this case the DHCP server is attached to the LAN facing NIC. For each subnet served, it defines the range of IP addresses it can lease out. It enables the DHCP server to give each of its clients DNS servers. In this case, at least during testing, it's best to give out the DNS servers that the Internet facing NIC got from its DHCP server. It can also give the clients a domain name, which in this case is set to "domain.cxm".

To facilitate testing in which the current LAN simulates the Internet, a testing config is added, and need not be commented out unless you really intend to have a LAN at that subnet. The 192.168.200.0/24 subnet is for testing. It can only serve out addresses if the BSD box's LAN facing NIC is at an address in that subnet, so basically when you switch the LAN facing NIC, you switch the DHCP setup along with it, without commenting anything in dhcpd.conf.
Click
resolv.conf For the purposes of the BSD box, this should be controlled by the WAN facing NIC's DHCP server.
search domain.cxm
nameserver 192.168.100.96

pf.conf This covers the firewall rules, the NAT, and any redirections (beyond the scope of this article).

Note there are several pairs of lines labelled LIVE and TEST, in most cases corresponding to whether the Internet facing NIC connects to  the LAN as a simulation test, or directly to the Internet for testing live operation or to function in a live environment.
Click
ssh (directory, make sure no bogus known hosts) Contains files related to SSH. Be careful that nothing in here, perhaps put in during diagnostic tests, can compromise your system.


/etc/hosts
#       $OpenBSD: hosts,v 1.12 2009/03/10 00:42:13 deraadt Exp $
#
# Host Database
#
# RFC 1918 specifies that these networks are "internal".
# 10.0.0.0      10.255.255.255
# 172.16.0.0    172.31.255.255
# 192.168.0.0   192.168.255.255
#
127.0.0.1       localhost
::1             localhost
#192.168.100.96 bsdpf.domain.cxm bsdpf   ## LIVE
192.168.200.96  bsdpf.domain.cxm bsdpf   ## TEST


/etc/hostname.re0
inet 192.168.100.96 255.255.255.0  192.168.100.255  # LIVE
#inet 192.168.200.96 255.255.255.0  192.168.200.255  # TEST

/etc/dhclient.conf
# $OpenBSD: dhclient.conf,v 1.1 1998/09/08 20:26:41 marc Exp $
#
# DHCP Client Configuration
#
# See dhclient.conf(5) for possible contents of this file.
# When empty default values are used:
#
# Example:
#
# send dhcp-lease-time 3600;
# send host-name "myhost";
# supersede host-name "myhost";
# supersede domain-name "my.domain";
# request subnet-mask, broadcast-address, time-offset, routers,
#       domain-name, domain-name-servers, host-name, lpr-servers, ntp-servers;
# require subnet-mask, domain-name-servers, routers;
# media "link0 link1", "link0 link1", "link0 link1", "-link0 link1";

request subnet-mask, broadcast-address, time-offset, routers, domain-name, domain-name-servers;
require subnet-mask, domain-name-servers, routers;
#



/etc/dhcpd.conf
#       $OpenBSD: dhcpd.conf,v 1.2 2008/10/03 11:41:21 sthen Exp $
#
# DHCP server options.
# See dhcpd.conf(5) and dhcpd(8) for more information.
#

option  domain-name "domain.cxm";
option  domain-name-servers 65.32.5.111, 65.32.5.112;

## LIVE DHCPD SUBNET
subnet 192.168.100.0 netmask 255.255.255.0 {
        option routers 192.168.100.96;

        range 192.168.100.230 192.168.100.239;
}

## TEST DHCPD SUBNET
subnet 192.168.200.0 netmask 255.255.255.0 {
        option routers 192.168.200.96;

        range 192.168.200.230 192.168.200.239;
}

NOTE: For the option  domain-name-servers line, use two known good Internet DNS servers, probably those given you by your ISP. If you have a trusted DNS server on your LAN, after your firewall goes live you can change this line to include any trusted DNS servers on your LAN.

/etc/pf.conf for LIVE use and LIVE testing
# STEVE LITT'S ULTRASIMPLE pf.conf

# MACROS
ext_if="rl0"
int_if="re0"
lan_ip="192.168.100.0/24"

private_networks="{ 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 255.255.255.255/32, 127.0.0.0/8 }"

# SCRUB PACKETS
match in all scrub (no-df)
match out all scrub (random-id)

# SET UP NAT: 4.8 SYNTAX
match out on $ext_if from $lan_ip nat-to ($ext_if)  #LIVE
#match out on $ext_if from !($ext_if) nat-to ($ext_if)  #TEST

# IPV6 CURRENTLY IRRELEVANT, DROP IT **QUICK**
block drop in quick inet6

# ANTISPOOF **QUICK**
antispoof log quick for { $ext_if } inet

# DEFAULT IS BLOCK IN FROM INTERNET, PASS ALL ELSE
block log all
pass on $int_if all
pass out on $ext_if all

# SKIP LOOPBACK
set skip on lo0

# ALLOW ALL ICMP EXCEPT REDIRECTS
pass in inet proto icmp all
block in log on $ext_if inet proto icmp all icmp-type redir

# BLOCK THE OBVIOUSLY BOGUS **QUICK**
#block in quick log on $ext_if from any to 192.168.200.0/24  #TEST
block in quick log on $ext_if from no-route to any
block in quick log on $ext_if from any to 255.255.255.255
block in quick log on $ext_if from any to $private_networks
block in quick log on $ext_if from $private_networks to any
block return out quick log on $ext_if from any to $private_networks
# COMMENT OUT THE PRECEDING 3 LINES WHEN TESTING THE INTERNET FACING
# NIC ON THE LAN IN ORDER TO SIMULATE THE INTERNET,
# UNCOMMENT THEM FOR LIVE PRODUCTION

# ALLOW INTERNET QUERIES TO FIREWALL'S SAFE INTENTIONAL SERVERS
#pass in on $ext_if proto tcp from any to any port {22}


/etc/pf.conf for SIMULATION Mode test
# STEVE LITT'S ULTRASIMPLE pf.conf

# MACROS
ext_if="rl0"
int_if="re0"
lan_ip="192.168.100.0/24"

private_networks="{ 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 255.255.255.255/32, 127.0.0.0/8 }"

# SCRUB PACKETS
match in all scrub (no-df)
match out all scrub (random-id)

# SET UP NAT: 4.8 SYNTAX
#match out on $ext_if from $lan_ip nat-to ($ext_if)  #LIVE
match out on $ext_if from !($ext_if) nat-to ($ext_if)  #TEST

# IPV6 CURRENTLY IRRELEVANT, DROP IT **QUICK**
block drop in quick inet6

# ANTISPOOF **QUICK**
antispoof log quick for { $ext_if } inet

# DEFAULT IS BLOCK IN FROM INTERNET, PASS ALL ELSE
block log all
pass on $int_if all
pass out on $ext_if all

# SKIP LOOPBACK
set skip on lo0

# ALLOW ALL ICMP EXCEPT REDIRECTS
pass in inet proto icmp all
block in log on $ext_if inet proto icmp all icmp-type redir

# BLOCK THE OBVIOUSLY BOGUS **QUICK**
block in quick log on $ext_if from any to 192.168.200.0/24  #TEST
block in quick log on $ext_if from no-route to any
block in quick log on $ext_if from any to 255.255.255.255
#block in quick log on $ext_if from any to $private_networks
#block in quick log on $ext_if from $private_networks to any
#block return out quick log on $ext_if from any to $private_networks
# COMMENT OUT THE PRECEDING 3 LINES WHEN TESTING THE INTERNET FACING
# NIC ON THE LAN IN ORDER TO SIMULATE THE INTERNET,
# UNCOMMENT THEM FOR LIVE PRODUCTION

# ALLOW INTERNET QUERIES TO FIREWALL'S SAFE INTENTIONAL SERVERS
pass in on $ext_if proto tcp from any to any port {22}


Commands

Task
Command
Restart the network (after changing config). This also restarts any DHCP clients. I found one case where doing this didn't recognize a change to the IP address, so if all else fails you might have to reboot.
sh /etc/netstart
Restart the DHCP server.
dhcpd
Find every file with the current IP address (presumably to change them)
grep -rl 192.168.100.96 /etc/*


Reset the PF firewall. This also syntax checks /etc/pf.conf.
pfctl -f /etc/pf.conf
Temporarily disable PF firewall
NOTE: Very dangerous unless running in simulation mode behind another firewall.
pfctl -d
Re-enable PF firewall
pfctl -e
Show firewall rules in the order they're executed
pfctl -s rules
Show everything including ruleset warnings.
pfctl -vv <other options and args>
Run "lint" on your pf.conf to show warnings and other stuff. Compiles but does not load the config file, so if it fails to compile it doesn't leave you wide open. If you want to actuall load it, which I think is a bad idea if you're at the lint stage,substitute the -f option for the -n.

This is also an excellent way to get a numbered list of rules, with numbers starting at zero.
pfctl -g -vv -nf /etc/pf.conf
View your PF log file. DO NOT use the -v option -- insecure! tcpdump -n -e -ttt -r /var/log/pflog
View PF events live as they happen (sort of like a tail-f). DO NOT use the -v option -- insecure!
tcpdump -n -e -ttt -i pflog0


Finding a host's entry in a hashed .ssh/known_hosts. After running the command, grep .ssh/known-hosts for the material shown by the command.
ssh-keygen -H -F 192.168.100.249

Public DNS servers




Back to Troubleshooters.Com * Back to Linux Library * Back to Steve's BSD Resources