Реклама: |
One major concern in setting up a firewall is the integrity of the firewall itself. Can
somebody break into your firewall, thereby subverting its ruleset? This is a common
problem administrators must face, particularly when they're using firewall solutions on
top of their Unix/NT machines. Some use it as an arguement for blackbox hardware
solutions, under the flawed notion that inherant obscurity of their closed system
increases their security. We have a better way.
Many network admins are familiar with the common ethernet bridge. This is a device that
connects two separate ethernet segments to make them one. An ethernet bridge is typically
used to connect separate buildings, switch network speeds, and extend maximum wire
lengths. Hubs and switches are common bridges, sometimes they're just 2 ported devices
called repeaters. Recent versions of Linux, OpenBSD, NetBSD, and FreeBSD include code to
convert $1000 PCs into $10 bridges, too! What all bridges tend to have in common is that
though they sit in the middle of a connection between two machines, the two machines don't
know the bridge is there. Enter ipfilter and OpenBSD.
Ethernet bridging takes place at Layer2 on the ISO stack. IP takes place on Layer3. IP
Filter in primarily concerned with Layer3, but dabbles in Layer2 by working with
interfaces. By mixing IP filter with OpenBSD's bridge device, we can create a firewall
that is both invisible and unreachable. The system needs no IP address, it doesn't even
need to reveal its ethernet address. The only telltale sign that the filter might be there
is that latency is somewhat higher than a piece of cat5 would normally make it, and that
packets don't seem to make it to their final destination.
The setup for this sort of ruleset is surprisingly simple, too. In OpenBSD, the first
bridge device is named bridge0. Say we have two ethernet cards in our machine as
well, xl0 and xl1. To turn this machine into a bridge, all one need do
is enter the following three commands:
brconfig bridge0 add xl0 add xl1 up
ifconfig xl0 up
ifconfig xl1 up
At ths point, all traffic ariving on xl0 is sent out xl1 and all
traffic on xl1 is sent out xl0. You'll note that neither interface has
been assigned an IP address, nor do we need assign one. All things considered, it's likely
best we not add one at all.
Rulesets behave essentially the as the always have. Though there is a bridge0
interface, we don't filter based on it. Rules continue to be based upon the particular
interface we're using, making it important which network cable is plugged into which
network card in the back of the machine. Lets start with some basic filtering to
illistrate what's happened. Assume the network used to look like this:
20.20.20.1 <---------------------------------> 20.20.20.0/24 network hub
That is, we have a router at 20.20.20.1 connected to the 20.20.20.0/24 network. All
packets from the 20.20.20.0/24 network go through 20.20.20.1 to get to the outside world
and vice versa. Now we add the Ipf Bridge:
20.20.20.1 <-------/xl0 IpfBridge xl1/-------> 20.20.20.0/24 network hub
We also have the following ruleset loaded on the IpfBridge host:
pass in quick all
pass out quick all
With this ruleset loaded, the network is functionally identical. As far as the
20.20.20.1 router is concerned, and as far as the 20.20.20.0/24 hosts are concerned, the
two network diagrams are identical. Now lets change the ruleset some:
block in quick on xl0 proto icmp
pass in quick all
pass out quick all
Still, 20.20.20.1 and 20.20.20.0/24 think the network is identical, but if 20.20.20.1
attempts to ping 20.20.20.2, it will never get a reply. What's more, 20.20.20.2 won't even
get the packet in the first place. IPfilter will intercept the packet before it even gets
to the other end of the virtual wire. We can put a bridged filter anywhere. Using this
method we can shrink the network trust circle down an individual host level (given enough
ethernet cards:-)
Blocking icmp from the world seems kind of silly, especially if you're a sysadmin and
like pinging the world, to traceroute, or to resize your MTU. Lets construct a better
ruleset and take advantage of the original key feature of ipf: stateful inspection.
pass in quick on xl1 proto tcp keep state
pass in quick on xl1 proto udp keep state
pass in quick on xl1 proto icmp keep state
block in quick on xl0
In this situation, the 20.20.20.0/24 network (perhaps more aptly called the xl1
network) can now reach the outside world, but the outside world can't reach it, and it
can't figure out why, either. The router is accessible, the hosts are active, but the
outside world just can't get in. Even if the router itself were compromised, the firewall
would still be active and successful.
So far, we've been filtering by interface and protocol only. Even though bridging is
concerned layer2, we can still discriminate based on IP address. Normally we have a few
services running, so our ruleset may look like this:
pass in quick on xl1 proto tcp keep state
pass in quick on xl1 proto udp keep state
pass in quick on xl1 proto icmp keep state
block in quick on xl1 # nuh-uh, we're only passing tcp/udp/icmp sir.
pass in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state
pass in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53 flags S keep state
pass in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25 flags S keep state
pass in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80 flags S keep state
block in quick on xl0
Now we have a network where 20.20.20.2 is a zone serving name server, 20.20.20.3 is
an incoming mail server, and 20.20.20.7 is a web server.
Bridged IP Filter is not yet perfect, we must confess.
First, You'll note that all the rules are setup using the in direction instead
of a combination of in and out. This is because the out
direction is presently unimplimented with bridging in OpenBSD. This was originally done to
prevent vast performance drops using multiple interfaces. Work has been done in speeding
it up, but it remains unimplimented. If you really want this feature, you might try your
hand at working on the code or asking the OpenBSD people how you can help.
Second, using IP Filter with bridging makes the use of IPF's NAT features inadvisable,
if not downright dangerous. The first problem is that it would give away that there's a
filtering bridge. The second problem would be that the bridge has no IP address to
masquerade with, which will most assuredly lead to confusion and perhaps a kernel panic to
boot. You can, of course, put an IP address on the outbound interface to make NAT work,
but part of the glee of bridging is thus diminished.