A simple gateway, NAT if you need it

Table of Contents
Gateways and the pitfalls of in, out and on
What is your local network, anyway?
Setting up

At this point we finally move on to the more realistic or at least more common setups, where the machine with the packet filter or firewall configured also acts as a gateway for at least one other machine.

The other machines on the inside may of course also run firewall software, but even if they do, it does not affect what we are interested in here to any significant degree.

Gateways and the pitfalls of in, out and on

In the single machine setup, life is relatively simple. Traffic you create should either pass or not out to the rest of the world, and you decide what you let in from elsewhere.

When you set up a gateway, your perspective changes. You go from the "me versus the network out there" setting to "I am the one who decides what to pass to or from all the networks I am connected to". The machine has several, or at least two, network interfaces, each connected to a separate net.

Now it's very reasonable to think that if you want traffic to pass from the network connected to ep1 to hosts on the network connected to ep0, you will need a rule like this[1]:

pass in inet proto tcp on ep1 from ep1:network to ep0:network \
     port $ports 

However, one of the most common and most complained-about mistakes in firewall configuration is not realizing that the "to" keyword does not in itself guarantee passage all the way there. In fact, the rule we just wrote only lets the traffic pass in to the gateway itself, on the specific interface given in the rule.

To let the packets get a bit further on and move into the next network over, you would need a matching rule which says something like

pass out inet proto tcp on ep0 from ep1:network to ep0:network \
     port $ports 

These rules will work, but they will not necessarily achieve what you want.

If there are good reasons why you need to have rules which are this specific in your rule set, you know you need them and why. By the end of this tutorial you should be able to articulate with some precision, in the context of your own network, just when such rules are needed. However for the basic gateway configurations we'll be dealing with here, what you really want to use is probably a rule which says

pass inet proto tcp from ep1:network to any port $ports 

to let your local net access the Internet and leave the detective work to the antispoof and scrub code. They are both pretty good these days, and we will get back to them later. For now we just accept the fact that for simple setups, interface bound rules with in/out rules tend to add more clutter than they are worth to your rule sets.

For a busy network admin, a readable rule set is a safer rule set.

For the remainder of this tutorial, with some exceptions, we will keep the rules as simple as possible for readability.

Notes

[1]

Here you probably notice that we no longer have a keep state part. Keeping state is redundant if you are working with OpenBSD 4.1 or equivalent, but there is actually no need to remove the specification from your rules when upgrading your rule set from earlier versions. To ease transition, the examples in this tutorial will make this distinction when needed.