Packet Normalization


Packets can be shredded in transit, and processing these shards of data can increase system load. The system at one end of the connection might have a habit of breaking up transmitted packets into tiny bits, or perhaps some router in the middle thinks that your packets are too large and splits them up to digest them more easily. In either event, instead of nice whole packets your network will receive small bits, or fragments. Different operating systems reassemble packets in slightly different ways. While these differences are usually trivial, a skilled attacker can use them to exploit the client operating system. PF's "scrub" rules allow you to decide how to handle packets, or even to perform some rearrangement of your own. (Other people "mangle" packets, but you "normalize" them.) PF's goal is to hand the client operating systems complete packets, so that the client doesn't have to do the work of reassembling the packet and so you don't have to worry about possible attacks on the client's packet reassembly code.

Packet normalization is done via "scrub" rules. The easiest way to perform the most common packet-fragment handling is to just put in a basic scrub rule:

 scrub in all 

This affects all packets entering the computer. While PF won't fragment or change packets unless you tell it to, you might want to also use a "scrub out all" rule. If you have a complex internal network some internal device might well mangle the packets. You could also add interface names to this rule, to only normalize packets coming from one network. In most cases, not scrubbing your own packets is an example of "My network can do no wrong."

 scrub in all on fxp0 

Customizing Fragment Handling

By default, a scrub rule reassembles fragments. The bits and pieces of each packet are cached locally until the entire packet arrives, and then the completed packet is passed on down to later rules. This simplifies the writing of rules and makes it easy for your clients to receive more complete packets than they would otherwise. If you are using network address translation, you must use fragment reassembly. While this is the default behavior for scrub rules, you can explicitly set it with "fragment reassemble."

 scrub in all fragment reassemble 

You could also choose to crop fragments. One packet can be partially repeated in a few different fragments. Cropping eliminates all duplicates and trim out any content overlap within fragments. This results in one and only one copy of each piece of data traveling on down the rules and onto the network. PF normally keeps a very small cache of recent fragments for comparison purposes. Cropping reduces PF's memory requirements, which may be important if you're running on very old hardware. In most cases, reassembling packets is a better choice.

 scrub in all fragment crop 

If you're really short on memory (e.g., running OpenBSD on a VAX), you might want to perform even more drastic fragment trimming. You can drop overlaps and fragments alike with the "drop-ovl" scrub rule. If you're this desperate for memory, however, buy a Pentium 100 to do your packet filtering instead. If you're running thousands of states simultaneously, you can certainly afford a machine with more RAM!

 scrub in all fragment drop-ovl 

In addition to handling fragmentation, scrub rules can perform some other basic packet checking and manipulation. One common setting on network packets is the "don't fragment" flag, which indicates that either the client or the server did not want this particular packet broken up. On occasion, however, a particular system or program will do something odd such as send a fragment with the don't-fragment flag set. This can confuse other computers on the network. You can choose to unset the don't-fragment flag on all packets that pass through PF by using the "no-df" modifier:

 scrub in all no-df 

Every IP packet has a time-to-live, or TTL. You can insist that all packets that pass through your packet filter have a minimum TTL. You would probably want two different scrub rules for this, as packets that you are sending should probably have a very high TTL, while packets entering your network should have a TTL large enough to let them reach their destination within your network. Set this with the "min-ttl" modifier:

 scrub in on fxp0 min-ttl 5 scrub in on fxp1 min-ttl 30 

Finally, you can adjust the maximum segment size of packets that pass through PF. Some networks have a problem with an unusual maximum segment size, so use the "max-mss" option with care.

 scrub in all max-mss 1500 

You can combine scrub rules on a single line, or break them up by interface, or any combination of these. Here, we have a scrub rule that applies to all packets, and separate rules that apply to packets that enter the system on particular interfaces:

 scrub in all max-mss 1440 fragment reassemble scrub in on fxp0 min-ttl 5 scrub in on fxp1 min-ttl 30 no-df 

Avoiding Fragment Processing

Fragment caching and reassembly uses memory, of course, and you might think that you can reduce memory usage by not reassembling fragments. Don't do this. Buy memory instead. Fragments are generally the maximum size as the physical protocol allows, which is frequently much smaller than a large TCP/IP packet. Each fragment relies on information available in the first few fragments, such as the destination and source ports.

This means that if you do not reassemble fragments, you will not be able to filter based on source or destination port, or on ICMP message or code. This means that you cannot use stateful inspection on fragments, which immediately increases the size of your rule base dramatically. Packet descriptions that rely only upon source and destination IP address and protocol will catch fragments, but once you mention a port number the fragment will not match the rule. You can choose to either let all the packets in or block them without referring to port number, both of which dramatically reduce your security options. Do something with your fragments!




Absolute Openbsd(c) Unix for the Practical Paranoid
Absolute OpenBSD: Unix for the Practical Paranoid
ISBN: 1886411999
EAN: 2147483647
Year: 2005
Pages: 298

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net