Overview of Class Seven

by Torleif Mohling
CU Boulder, dept of Computer Science
(03/01/2001)

We spent a good portion of class seven discussing the recent catastrophicfailure
of the lab file-server cia that died over the weekend (the server was down for
three days, from Sat AM, 24 Feb - Mon PM 26 Feb; files were not fully restored until
the following day). Whew.

We've looked briefly at setting up a firewall under OpenBSD. To reiterate:

Edit /etc/rc.conf and turn on ipf:

ipfilter=YES

The firewall rules live in the file /etc/ipf.rules.

Use the ipf(8) command to manipulate the runtime filter.

Use the ipfstat(8) command to show the runtime filter rules
and other statistics.

Let's take another look at my home network firewall. It is implemented
on coatlicue, the gateway host - of course. (BTW - I modified these
rules since I discussed them in class.)
We'll look at the file in chunks, to more easily describe each part.
Here is the beginning:

# /etc/ipf.rules
#
# RCS: $Id: class07.txt,v 1.3 2001/03/01 23:47:43 tor Exp $
#
# Allow anything to go *out* quickly
pass out quick from any to any
#
# But the default is to block all incoming traffic
block in on le0 from any to any
#

The comments for the rules in this file are pretty self explanatory,
but let's have a look at the basic syntax of ipf rules:

action in|out [ options ] [ proto ] [ ip ]

The two most common actions are block and pass but there are
a number of others. Every rule applies to either incoming or outgoing
traffic only (specifed by in or out, respectively).
The optionquick says to (if the packet matches the rule) immediately
apply the rule and do no further processing of the packet, otherwise
every rule is checked and the last matching rule is applied.
(Note that this is in contrast to other firewall implmentations like cisco
that operate in the opposite manner, such that 'quick' is always implied.)
The onle0 clause is another option that simply specifies which
interface the rule applies to (the default is to apply the rule
to all interfaces).
Neither of the above rules have a proto specification,
but the ip specification is fromanytoany.

The default behavior I have chosen is fairly typical: the first
rule states that all outgoing
traffic is allowed to continue unfiltered, while in the second rule
the implication is that only
specific traffic is allowed in (i.e. the default is to deny any
traffic for which there is not a subsequent rule.) It is important
that the second rule does not have the quick option!

I designed the next block of rules to allow incoming 'return'
traffic, i.e. return traffic for established connections.
These rules are necessary in conjuntion with a default that
denies everything, so that internally initiated TCP sessions
continue to function.

# Do allow established connections, but subject to further rulings
pass in on le0 proto tcp from any to any flags A
pass in on le0 proto tcp from any to any flags P
pass in on le0 proto tcp from any to any flags SA
pass in on le0 proto tcp from any to any flags PA
pass in on le0 proto tcp from any to any flags FA
pass in on le0 proto tcp from any to any flags FPA
#

Each of the above rules for allowing established connections
simply lets packets through that have the specified flags
set in their IP headers. Note that there doesn't appear to be
a way to say in one rule, "allow in any packets with the ACK flag
set". Each rules specifies exactly which flags are allowed to be set,
not a subset of flags that are set. I used tcpdump to monitor various
TCP sessions, like SSH and HTTP, to figure out what combinations of flags
were used. It is also important to remember that rules like these
are dangerous. A hacker can craft a packet with these flags set and thus
potentially spoof your firewall. It relies on internal hosts having properly
implemented TCP/IP stacks that will return a TCP reset when they
receive such packets when they are unsolicited.
At any rate, the rules are essential for allowing return traffic - the alternative
is to have explicit return-traffic rules for every internet application local users make
use of.

Next I block obviously bogus packets:

# Block any inherently bad packets coming in from the outside world.
# These include ICMP redirect packets and IP fragments so short the
# filtering rules won't be able to examine the whole UDP/TCP header.
block in log quick on le0 proto icmp from any to any icmp-type redir
block in log quick on le0 proto tcp/udp all with short
block in log quick on le0 from any to any with ipopts
#
# Block any IP spoofing atempts.
block in log quick on le0 from 198.168.4.0/24 to any
block in log quick on le0 from localhost to any
block in log quick on le0 from 0.0.0.0/32 to any
block in log quick on le0 from 255.255.255.255/32 to any
block in log quick on le0 from 10.0.0.0/8 to any
#

The second of the above two chunks of rules deserves some further explanation
as it is a common feature of every firewall. Each rule denies ranges of IP addresses
that are guaranteed to be bogus. Some of these are known to be bogus because they
are private addresses that should never exist on the internet. Others are just bogus
because they are undefined (e.g. 255.255.255.255/32). Other addresses
that you want to block here are those of hosts known to be on the inside
of your firewall and thus would never appear as the source address of packets coming
in this interface. The last of these rules blocks packets with a source
address of 10.0.0.0/8 which may seem odd. My home network is 10.0.0.0/24
which is slightly different. By using the /8 netmask, I am able to effectively
block any 'ten-net' address. The reason is that netmasks are not actually part
of the IP header itself, so any incoming packet with a source IP address that
simply starts with 10 will be blocked!

All of the above rules make use of another option called log that
causes the packet to be logged (via syslog). This is useful for
many reasons; I log packets that I think are from hackers,
which you can know because why else would someone try to contact 'rlogin'
on your machine? Here are some further rules I use for logging this
sort of traffic:

# Block and log common "hacker" ports including incoming traffic
# to NFS ports, the RPC portmapper, X servers, and talk
block in log quick on le0 proto tcp/udp from any to any port = sunrpc
block in log quick on le0 proto tcp/udp from any to any port = 2049
block in log quick on le0 proto tcp from any to any port = 6000
block in log quick on le0 proto udp from any to any port = talk
block in log quick on le0 proto udp from any to any port = ntalk
#
# Block all incoming TCP traffic connections to known services,
# returning a connection reset so things like ident don't take
# forever timing out. Don't log ident (auth port) as it's so common.
block return-rst in log on le0 proto tcp from any to any flags S/SA
block return-rst in on le0 proto tcp from any to any port = auth flags S/SA
#

The first of the last two rules above returns a "tcp-reset" for all
TCP syn packets that are received and not matched by a subsequent
rule in the firewall. Returning a reset is common courtesy so that
the sender's TCP connection attempt quickly times out.

Finally, I allow in a few things:

# Allow UPD DNS traffic
pass in on le0 proto udp from any port = domain to any
#
# Allow various TCP services
pass in on le0 proto tcp from any port = domain to any
pass in on le0 proto tcp from any to any port = domain
pass in on le0 proto tcp from any to any port = smtp
pass in on le0 proto tcp from any to any port = http
pass in on le0 proto tcp from any to any port = https
pass in on le0 proto tcp from any to any port = ssh

My home network firewall is pretty simple, as far as firewalls go, but it
is only protecting a small, simple network. However, getting the rules exactly right,
even for such a simple firewall, can be challenging. For example, trying
to figure out the TCP flags that need to be specified to allow established
connections to work. There are a couple of things to remember. One is to
always recall where the firewall is placed, and related to this, two, to recall
the direction of traffic that is being filtered. For a simple firewall
this is not very difficult, but when you are dealing with a large local
network with different zones of protection and multiple firewalls then the
details can get quite tricky.

The most useful tool for figuring out the rules that are needed in your firewall
is tcpdump. You can run tcpdump on each end of connections you need to
set up, so that you can figure out exactly which portnumbers will need to
have rules to allow the connection through the firewall.

As another example, let's revisit the CS department network topology and
then look at some excerpts from the firewalls that are in place. (Please also
refer to the Network Diagram that was handed out in Class Six or Seven.)
Although the department makes use of two big Cisco Routers, only one of them
is involved in all the action as far as the firewalls are concerned. Here is
a diagram of the basic topology:

The arrows with FW indicate the direction of traffic that is being filtered.
That is to say, for example, that inbound packets from the rest of CU and the
internet ("inbound" is from the point of view of the interface on the CS-GW router
on which there is an IP filter firewall) are subject to being filtered.
Similarly, inbound packets, that is from the CSEL lab, are also filtered,
as are inbound packets from the WOZ lab network and the DRAG net. The filters that
are in place on the CSEL, WOZ and DRAG nets are designed to protect the rest
of the CS department networks from those networks. The main filter on the
interface with the rest of campus is designed to protect the CSEL, the WOZ, and
the rest of the CS networks. The DRAG net is relatively unprotected (it is
the intention that this net actually be outside the firewall, our firewall is
designed to make it seem that way).

Now let's have look at some pieces of the departmental firewalls! The firewalls
are implemented on a Cisco Router, as we have been discussing. Each firewall
is represented as a filter access-list that is given a number. All of the
lists are delineated in a single file; once the file is read in, each list
is applied to the relevant interface on the router. The file itself is very
well commented, to facilitate the numerous administrators who edit it.
The first list we'll look at is list 110 that is the main firewall filter
on all incoming traffic from the internet.

The context of the filter is described in the header comment. The first thing
that is done is to clear the access-list (otherwise any existing rules are
retained and the new ones are appended to the list).

The next batch of rules that are added to the list should look familiar:

These are the standard anti-spoofing rules that block bogus source IP addresses.
In this case, however, we don't have to worry about private IP networks because
the router won't route them. Here we only have to deal with IP address that are
known to be on the inside of the department network, and so would never
be present as the source IP of incoming traffic.

Next we have a simple rule that allows the DRAG net to look as if it
is outside the firewall:

Then we come to many specific rules that allow specific services to individual
machines are subnets. I'm not going to show most of these because they are basically
the same as what we have looked at already. However, it is worth looking at the
rules that were added to this access-list as well as to other access-lists (for the CSEL
and WOZ nets) in order to allow SMPT and HTTP traffic to go to the saclass-N machines.
All three firewalls that we have discussed (the main one, the WOZ and the CSEL) must
have rules added:

because the saclass-N machines are on the WOZ net, the WOZ filter of course needs
new rules added

for service to CSEL from the saclass-N machines, the CSEL filter must be modified

for service from outside the CS networks (i.e. the internet) the main filter
must be modified

In the final case, the filter needs to allow established traffic through (remember
that the filter is applied to traffic coming from the WOZ net; traffic to the
WOZ net is not filtered (except in access-list 110 which we already dealt with).

The firewalls we have implemented in the CS department
have had a noticible impact on our Cisco Router - this is measured in
terms of actual and expected throughput values for the router model.
The processing required to match every single packet with an extensive
firewall ruleset is significant and beyond the power of the 680xx Motorola
CPU chips on the router; it simply doesn't have the juice to keep up with
the traffic efficiently. There are probably many different solutions to this
sort of problem, most certainly dependent on the amount of money one can throw
at it! Simply purchasing a Spankin' New Router is beyond the budget of the department.
(Our two current routers were substantially donated to us by Cisco!)

One idea is to remove the firewall completely from the Cisco and instead use a cheap
and fast PC. These days a 700MHz CPU with 100MHz bus, 512MB RAM and four 100bT NIC's
can be purchased for $1500.00 or less! I'll show a diagram of the plan and then
explain it.

The idea comes from the fact the OpenBSD can be used as a transparentbridge that
is dropped in between the two routers. Disregard the WOZ and CSEL networks
for a moment, to understand. The PC is dropped in between the two routers;
before that (i.e. right now) the link was a single ethernet cable between the routers
running at fullduplex100bT for 200Mbps. Each interface (one on each of the Ciscos)
has an IP address on a shared subnet, and they are currently the only two addresses
in use on the subnet.
The PC can be dropped into this setup (as shown) and be configured to act as
a transparentbridge. That just means that the two interfaces on the PC
that previous cable (now cut in half with new connectors crimped on :) gets
plugged into (i.e. the interfaces labeled 1 and 2 in the diagram) actually
don't have IP addresses assigned to them. That is why the bridge is "transparent"
(it won't show up in traceroute for example). However, you can set up the PC
to apply the IPfilter rulesets to the bridged traffic!

To add in the additional interfaces for the WOZ and CSEL nets changes the scenario
somewhat, but is necessary if each of those networks is in a seperately firewalled
zone. If we do add these additional interfaces then I am not sure if the transparent
bridging stuff talked about above will actually work. To verify it would require
actually setting up a test network.. If it didn't work, we can always
repeat the same idea using more new PCs as bridges for each firewalled zone.