Overview of Class Seven

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

0 Contents

1 Class Seven

We spent a good portion of class seven discussing the recent catastrophic failure 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.

The slides for the ipfilter talk are available, see: ./ipf.HTML/index

The remainder of this document is the IPFilter notes fom last year; they reiterate the material from the slides...

2 IP Firewalling with IPFilter

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

    ipfilter=YES
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 option quick 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 on le0 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 from any to any.

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 port numbers 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:

        
                                   WOZ                                   
                                    |                                    
                                    | |                                  
                                    | V                                  
                                    | FW                                 
                              +-----+----+                               
      rest of CU   --> FW     | CS-GW    |                               
     & internet  -------------+          +---------- rest of CS networks 
                              |          |                               
                              +--+----+--+                               
                            FW  /      \  FW                             
                         __.   /        \   .__                          
                          /|  /          \  |\                           
                         /   /            \   \                          
                          CSEL           DRAG                            

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.

    #-----------------------------------------------------------------------------
    #
    # Input packet filter for FDDI2/0 (Campus Backbone, 128.138.138.30)
    #         and for FastEthernet4/1 (Campus Backbone, 128.138.80.142)
    #       Implements Outside World -> Rest of CS
    #                  Outside World -> Undergrad Lab
    #                  Outside World -> Woz
    #
    # Clear list
    no access-list 110
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:

    # Anti-spoofing filter
    #     Deny packets from outside with an IP address of an internal net
    #     Note:  This should list every internal network EXCEPT the one 
    #            physically connected to the interface
    #
    access-list 110 deny   ip 127.0.0.0 0.255.255.255 any
    access-list 110 deny   ip 128.138.192.0 0.0.1.255 any
    access-list 110 deny   ip 128.138.198.0 0.0.1.255 any
    access-list 110 deny   ip 128.138.202.0 0.0.0.255 any
    access-list 110 deny   ip 128.138.204.0 0.0.1.255 any
    access-list 110 deny   ip 128.138.209.0 0.0.0.255 any
    access-list 110 deny   ip 128.138.236.0 0.0.0.255 any
    access-list 110 deny   ip 128.138.241.0 0.0.0.255 any
    access-list 110 deny   ip 128.138.242.0 0.0.1.255 any
    access-list 110 deny   ip 128.138.244.0 0.0.1.255 any
    access-list 110 deny   ip 128.138.250.0 0.0.0.255 any
    access-list 110 deny   ip 198.11.20.0 0.0.0.255 any
    access-list 110 deny   ip 199.165.145.0 0.0.0.255 any
    access-list 110 deny   ip 204.228.69.0 0.0.0.255 any
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:

    # Allow any IP to Drag net
    access-list 110 permit ip any 128.138.192.64 0.0.0.63
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:

Here are the main (access-list 110) filter rules:

    # Tor Mohling, SaClass holes for SMTP
    access-list 110 permit tcp any gt 1023 host 128.138.192.12 eq smtp
    access-list 110 permit tcp any gt 1023 host 128.138.192.13 eq smtp
    access-list 110 permit tcp any gt 1023 host 128.138.192.14 eq smtp
    access-list 110 permit tcp any gt 1023 host 128.138.192.15 eq smtp
    access-list 110 permit tcp any gt 1023 host 128.138.192.16 eq smtp
    access-list 110 permit tcp any gt 1023 host 128.138.192.17 eq smtp
    access-list 110 permit tcp any gt 1023 host 128.138.192.21 eq smtp
    # Tor Mohling, SaClass holes for HTTP
    access-list 110 permit tcp any gt 1023 host 128.138.192.12 eq www
    access-list 110 permit tcp any gt 1023 host 128.138.192.13 eq www
    access-list 110 permit tcp any gt 1023 host 128.138.192.14 eq www
    access-list 110 permit tcp any gt 1023 host 128.138.192.15 eq www
    access-list 110 permit tcp any gt 1023 host 128.138.192.16 eq www
    access-list 110 permit tcp any gt 1023 host 128.138.192.17 eq www
    access-list 110 permit tcp any gt 1023 host 128.138.192.21 eq www
One hole is opened up for each service and for each saclass machine.

The CSEL filter rules are in access-list 112 and they are almost identical:

    # Tor Mohling - SaClass holes for SMTP
    access-list 112 permit tcp any gt 1023 host 128.138.192.12 eq smtp
    access-list 112 permit tcp any gt 1023 host 128.138.192.13 eq smtp
    access-list 112 permit tcp any gt 1023 host 128.138.192.14 eq smtp
    access-list 112 permit tcp any gt 1023 host 128.138.192.15 eq smtp
    access-list 112 permit tcp any gt 1023 host 128.138.192.16 eq smtp
    access-list 112 permit tcp any gt 1023 host 128.138.192.17 eq smtp
    access-list 112 permit tcp any gt 1023 host 128.138.192.21 eq smtp
    #
    # Tor Mohling - SaClass holes for HTTP
    access-list 112 permit tcp any gt 1023 host 128.138.192.12 eq www
    access-list 112 permit tcp any gt 1023 host 128.138.192.13 eq www
    access-list 112 permit tcp any gt 1023 host 128.138.192.14 eq www
    access-list 112 permit tcp any gt 1023 host 128.138.192.15 eq www
    access-list 112 permit tcp any gt 1023 host 128.138.192.16 eq www
    access-list 112 permit tcp any gt 1023 host 128.138.192.17 eq www
    access-list 112 permit tcp any gt 1023 host 128.138.192.21 eq www
And finally, the WOZ filter is access-list 113 and its rules are slightly different:

    # Tor Mohling - SaClass holes for SMTP 
    access-list 113 permit tcp host 128.138.192.12 eq smtp any gt 1023 established
    access-list 113 permit tcp host 128.138.192.13 eq smtp any gt 1023 established
    access-list 113 permit tcp host 128.138.192.14 eq smtp any gt 1023 established
    access-list 113 permit tcp host 128.138.192.15 eq smtp any gt 1023 established
    access-list 113 permit tcp host 128.138.192.16 eq smtp any gt 1023 established
    access-list 113 permit tcp host 128.138.192.17 eq smtp any gt 1023 established
    access-list 113 permit tcp host 128.138.192.21 eq smtp any gt 1023 established
    #
    # Tor Mohling - SaClass holes for HTTP
    access-list 113 permit tcp host 128.138.192.12 eq www any gt 1023 established
    access-list 113 permit tcp host 128.138.192.13 eq www any gt 1023 established
    access-list 113 permit tcp host 128.138.192.14 eq www any gt 1023 established
    access-list 113 permit tcp host 128.138.192.15 eq www any gt 1023 established
    access-list 113 permit tcp host 128.138.192.16 eq www any gt 1023 established
    access-list 113 permit tcp host 128.138.192.17 eq www any gt 1023 established
    access-list 113 permit tcp host 128.138.192.21 eq www any gt 1023 established
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.

       
                                        WOZ                          
                                         |                           
                                         |                           
                                         | 3                         
                  +------+         +-----+----+            +------+  
     rest of CU   |CS-GW |       1 |OpenBSD PC| 2  rest of |CS-GW3|  
       and  ------+      +---------+ "trnsprnt+------------+      +  
                  |cisco |         |   bridge"|        cs  |cisco |  
                  +--+---+         +-----+----+            +------+  
                     |                   | 4                        
                     |                   |                         
                     |                   |                       
                   DRAG                CSEL                      

The idea comes from the fact the OpenBSD can be used as a transparent bridge 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 full duplex 100bT 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 transparent bridge. 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.