Conventions for Packet Filtering Rules

The rest of this chapter and show the kinds of rules you can specify for your packet filtering router in order to control what packets can and cannot flow to and from your network. There are a few things you need to know about these rules.

To avoid confusion, the example rules are specified with abstract descriptions, rather than with real addresses, as much as possible. Instead of using real source and destination addresses (e.g., 172.16.51.50), we use "Internal" or "External" to identify which networks we're talking about. Actual packet filtering systems usually require you to specify address ranges explicitly; the syntax varies from router to router.

In all of our packet filtering examples, the assumption is that, for each packet, the router goes through the rules in order until it finds one that matches, and then it takes the action specified by that rule. We assume an implicit default "deny" if no rules apply, although it's a good idea to specify an explicit default (and we generally do).

The syntax used in our filtering examples specifies the number of bits significant for comparison to other address after a slash character (/). Thus, 10.0.0.0/8 matches any address that starts with 10; it's equivalent to 10.0.0.0 with a UNIX netmask of 255.0.0.0, or 10.0.0.0 with a Cisco wildcard mask of 0.255.255.255, or (if it were a filename) 10.*.*.*.

Although we try to be as specific as possible in these examples, it's impossible to tell you precisely what you have to specify for your particular packet filtering product. The exact mechanism for specifying packet filtering rules varies widely from product to product. Some products (such as the screend package) allow you to specify a single set of rules that are applied to all packets routed by the system. Others (such as the Telebit NetBlazer) allow you to specify rules for particular interfaces. Still others (such as the Livingston and Cisco products) allow you to specify sets of rules and then apply sets by name to particular interfaces (so that you might define one set of rules that is shared by a number of different interfaces, for example, and put the rules that are unique to a given interface into a different set).

Packet Filtering Tips and Tricks

Here are a couple of tips and tricks that can help you deal with packet filtering rules more effectively and make them more secure.

Edit your filtering rules offline

The filter editing tools on most systems are usually pretty minimal. Also, it's not always clear how new rules will interact with existing rule sets. In particular, it's often difficult to delete rules, or to add new rules in the middle of an existing rule set.

You might find it more convenient to keep your filters in a text file on one of your UNIX or PC systems, so that you can edit them there with the tools you're familiar with, and then load the file on the filtering system as if it contained commands you were typing at the console. Different systems support various ways of doing this. For example, on Cisco products, you can use TFTP to obtain command files from a server. (Be careful of where you enable a TFTP server, though. See the discussion of TFTP in and think about using something like TCP Wrapper to control what hosts can activate that TFTP server). On Livingston products, there is a program available from Livingston called pmcommand that downloads commands to the box. On other products, there are other mechanisms.

An added advantage of keeping the filters elsewhere as a file is that you can keep comments in the file (stripping them out of the copy sent to the router, if necessary). Most filtering systems discard any comments in the commands they're given; if you later go look at the active filters on the system, you'll find that the comments aren't retained.

Reload rule sets from scratch each time

The first thing the file should do is clear all the old rules, so that each time you load the file you're rebuilding the rule set from scratch; that way, you don't have to worry about how the new rules will interact with the old. Next, specify the rules you want to establish, followed by whatever commands are necessary to apply those rules to the appropriate interfaces.

Always use IP addresses, never hostnames

Always specify hosts and networks in filtering rules by IP address, never by hostname or by network name (if your filtering product even supports that). If you specify filtering rules by hostname, your filtering could be subverted if someone accidentally or intentionally corrupts the name-to-address translation (e.g., by feeding false data to your DNS server).

Here's a simple example to illustrate the differences. We chose these three systems because they represent somewhat different ways of specifying filters, not because of any particular preference for them; in general, other systems are similar to these. For example, Cisco's products are similar to Livingston's products in that you create sets of rules, then apply those rules to packets going in a particular direction through a particular interface. They are different in details of their syntax, such as in how you specify host addresses and bitmasks.

Let's say that you want to allow all IP traffic between a trusted external host (host 172.16.51.50) and hosts on your internal network (Class C net 192.168.10.0). In our examples, we would show this case as follows:

ACK
Rule Direction Source Address Destination Address Set Action
A Inbound Trusted external host Internal Any Permit
B Outbound Internal Trusted external host Any Permit
C Either Any Any Any Deny

With screend, you would specify:

between host 172.16.51.50 and net 192.168.10 accept ; between host any and host any reject ;

With a Telebit NetBlazer, you also have to specify which interface the rule is to be applied to, and whether the rule applies to incoming or outgoing packets on that interface. For an external interface named "syn0", your rules would be:

permit 172.16.51.50/32 192.168.10/24 syn0 in deny 0.0.0.0/0 0.0.0.0/0 syn0 in permit 192.168.10/24 172.16.51.50/32 syn0 out deny 0.0.0.0/0 0.0.0.0/0 syn0 out

On a Livingston PortMaster or IRX, you would specify rules as a set and then apply the relevant set to the right direction on the right interface. If your external interface is named "s1", your rules would look something like this:

add filter s1.in set filter s1.in 1 permit 172.16.51.50/32 192.168.10.0/24 set filter s1.in 2 deny 0.0.0.0/0 0.0.0.0/0 set s1 ifilter s1.in add filter s1.out set filter s1.out 1 permit 192.168.10.0/24 172.16.51.50/32 set filter s1.out 2 deny 0.0.0.0/0 0.0.0.0/0 set s1 ofilter s1.out

On a Cisco router, you also specify rules as sets, and apply the relevant sets to the right direction on the right interface. If your external interface is named "serial1", your rules would look like this:

access-list 101 permit ip 172.16.51.50 0.0.0.0 192.168.10.0 0.0.0.255 access-list 101 deny ip 0.0.0.0 255.255.255.255 0.0.0.0 255.255.255.255 interface serial 1 access-group 101 in access-list 102 permit ip 192.168.10.0 0.0.0.255 172.16.51.50 0.0.0.0 access-list 102 deny ip 0.0.0.0 255.255.255.255 0.0.0.0 255.255.255.255 interface serial 1 access-group 102 out

For detailed information on the syntax of a particular package or product, consult the documentation for that package or product. Once you understand the syntax for the particular system you are using, you shouldn't have too much difficulty translating from our tables to that system's syntax.

NOTE: Watch out for implicit defaults. Different filtering systems have different default actions they take if a packet doesn't match any of the filtering rules specified. Some systems deny all such packets. Other systems make the default the opposite of the last rule; that is, if the last rule was a "permit," the system default is to "deny," and if the last rule was a "deny," the default is to "permit." In any case, it's a good idea to put an explicit default rule at the end of your list of packet filtering rules, so you don't have to worry about (or even remember) which implicit default your system is going to use.