Packet Filtering Implementations for General-Purpose Computers
These days, a number of operating systems provide packet filtering features, independent of firewall products. Many Unix variants come with packet filtering, as does Windows.There are two major reasons why you might want to use packet filtering implementations on general-purpose computers. First, you may want to use a general-purpose computer as a router (either providing only packet filtering, or as a single-box firewall that provides both packet filtering and proxying). In this case, you are using the general-purpose computer to provide the same sort of packet filtering services that a router would provide. Second, you may be using the general-purpose computer as a bastion host, and you may want to use packet filtering on the computer as a security measure to protect the computer itself.
Linux ipchains and Masquerading
The Linux kernel includes a packet filtering system called ipchains, which provides powerful packet filtering capabilities. This system provides the same sorts of capabilities that you would get from a modern packet filtering router and is suitable for using where you'd use a router. Because it's part of the standard Linux kernel source, it should be present in all up-to-date Linux distributions, although it may not be enabled by default.Earlier Linux kernels used a filtering system called ipfw (which was a port of a BSD filtering system) and a configuration utility called ipfwadm. ipchains is a new filtering system, which provides more functionality than ipfw. ipchains allows you to convert configuration files from ipfwadm to ipchains.
The filtering performed by ipchains is done entirely in the kernel, and it requires only a single external utility to initialize the filtering rules. This means that it is possible to build a complete Linux filtering system that will fit on a single 1.44 MB floppy disk. The Linux Router Project is doing exactly this (see Appendix A, "Resources", for more information about the Linux Router Project).
Linux also has a facility called masquerading, which is used with ipchains to provide network address translation for both TCP and UDP. Masquerading keeps track of TCP connection state and supports timeout-based UDP requests and responses. Because it must be used with packet filtering, it can be considered a dynamic packet filtering system. In addition to providing straightforward network address translation for simple TCP and UDP protocols, Linux masquerading allows additional kernel modules to be loaded for more complicated protocols (for instance, FTP and RealAudio, which require reverse TCP connections or additional UDP ports).
ipchains
ipchains is designed around the concept of a chain of rules. Each rule specifies a condition and an action to take if the condition is met, called a target. The rules in a chain are used in order; a packet is checked against each rule in turn, and if the packet matches the condition, the specified action is taken.There are three standard chains, called the input, output, and forward chains. All packets coming in to the machine are passed through the input chain, and all packets going out of the machine are passed though the output chain. The forward chain is used for packets that need to be sent to a different network interface from the one they were received on. Thus, if a packet is received for the machine, it's matched against the input chain; if the machine generates a packet, it's matched against the output chain. If the machine is acting as a router and gets a packet addressed to some other machine, the packet will be matched against all three chains.
The standard chains each have a default policy, which is applied when no rules match. It is also possible to create additional, user-defined, chains. If no rules match when checking a user-defined chain, processing will continue at the point where the chain was called.
The conditions in a rule can be based on any of the following:
- The IP protocol number (e.g., TCP, UDP, ICMP, or IGMP).
- The source and destination IP addresses. Addresses can be specified as a variable-length subnet (e.g., 192.168.8.0/22) or a network address with a mask, and negation is allowed (you can specify "all addresses except those that match this address and mask").
- The source and destination TCP and UDP port numbers. Port numbers can be specified with ranges or masks, and negation is allowed.
- The ICMP type and code.
- Whether the packet is an IP fragment.
- Whether the packet is a TCP start-of-connection packet.
- The network interface. This is the interface the packet came in on for the input chain and the destination interface for the output and forward chains.
- Deny: Drop the packet without generating a response.
- Reject: Don't process the packet, but generate an ICMP response (which will be passed though the output chain).
- Accept: Process the packet.
- Masq: Perform masquerading. This target is only valid in the forward chain.
- Redirect: Forward the packet to a different port on the local machine.
- Return: Apply the default policy for a built-in chain or continue processing at the point where a user-defined chain was called.
- A user-defined chain.
A rule can also make a log entry, which contains information about the action that was taken, the time, and a summary of the packet headers. Logging is performed by syslog.
Testing ipchains rules
ipchains has a very useful feature that allows the kernel-filtering rules to be tested. The ipchains command allows you to specify IP header values to be tested against the currently loaded kernel filtering rules. Using the standard target names, the command prints how the kernel would react if the packet had really been sent to the firewall. At the time of writing, it is not possible to generate and test arbitrary packets.Masquerading
Linux masquerading is a network address translation system. Because it is capable of working at higher protocol levels, and doing more intricate modifications than simple address changes, it's also called a transparent proxying system. What it does could be considered either proxying or packet filtering; it's somewhere in between the two.The IP address of the firewall is used in communicating with remote services. For simple protocols, masquerading alters only IP header information, including IP addresses, port numbers, and TCP sequence and acknowledgment numbers. Masquerading uses the IP address of the host doing the masquerading as the externally visible address, and maps the port number into one from a pool of 4096 ports starting at 61000. This fixed allocation of ports does limit Linux masquerading to 4096 simultaneous TCP connections and 4096 UDP ports. At the time of writing, Linux kernels allocate only ports less than 32768, so the ports used for masquerading will never conflict with ports used for other purposes.
Linux masquerading is also capable of dealing with more complicated protocols, such as FTP or RealAudio, which might require reverse TCP connections or additional UDP ports. Support for new protocols can be added by dynamically loading new kernel modules.
How masquerading works
asquerading works by intercepting packets that are being forwarded by the Linux kernel. Masquerading for simple protocols works much like simple network address translation, as described in "Some Firewall Definitions". IP addresses and port numbers are modified on outgoing packets. For TCP connections, a new sequence number is generated. The process is reversed for incoming packets. Figure 8-5 is an example of this working for a client connecting to a remote HTTP server, and shows the IP address and ports for each half of the connection. The masquerading firewall will continue to pass packets back to the client as long as the client maintains the outgoing half of the TCP connection. In the case of UDP, the firewall will pass packets back to the client only for a configurable time period, which is typically set to 15-30 seconds.Figure 8-5. Masquerading for simple outgoing protocols
In addition to handling outgoing traffic, masquerading can be used to forward incoming ports to internal services. The ability to masquerade incoming ports is configured statically for each port that is to be forwarded. Once a port is forwarded, it can no longer be used to connect to a service on the firewall. Figure 8-6 shows a masquerading firewall configured to forward SSH to an internal destination and includes the IP addresses and port numbers for each half of the connection. It's possible to forward the same port to multiple destinations if the masquerading firewall is configured to listen to multiple IP addresses.Figure 8-6. Forwarding incoming services using masquerading
For more complicated protocols, masquerading can set up additional listening TCP and UDP ports based upon the contents of packets that have been seen. Masquerading can even rewrite the contents of data packets in order to replace IP addresses and port numbers.This is best explained by describing how the masquerading module for FTP works. As we discuss in "File Transfer, File Sharing, and Printing", FTP is a tricky protocol to support through a firewall because it normally involves a connection from the server to the client. An FTP client opens a control channel to a desired FTP server. At the point where data is to be transferred, the client issues a PORT command that contains the client IP address and a port number the client expects to receive the data on. The FTP server uses this information to open a new TCP connection to the client in order to transfer the data.
For masquerading to work, it must intercept the PORT command from the client. The FTP masquerading module does this by listening to the commands sent over all FTP control channels. When it sees a PORT command, it does two things; first, it sets up a temporary port on the masquerading host, which is forwarded to the port the client specified. Next, it rewrites the IP packet containing the PORT command with the IP address of the firewall and the temporary port. When an incoming connection to the temporary port is made, it is forwarded to the client. Figure 8-7 describes this process.
Figure 8-7. Masquerading normal-mode FTP
Available specialized masquerading modules
A number of specialized masquerading modules are available. At the time of writing, they can be split into three categories: multimedia, games, and access to internal services. An up-to-date list of modules and their availability can be found in the Linux MASQUERADING-HOWTO. See Appendix A, "Resources", for information on how to obtain Linux HOWTO documents.Using ipchains (including masquerading)
To use ipchains, you must compile it into the kernel you are using. The actual kernel compilation flags for turning it on are different in different Linux releases; you should either consult help for your Linux kernel configuration utility or use the Linux IPCHAINS-HOWTO. See Appendix A, "Resources" for information on obtaining Linux HOWTO documents.We also recommend that you turn on fragment reassembly. See "Packets and Protocols ", for information on IP fragmentation and why this is important.
asquerading is included as a standard part of Linux 2.1 and 2.2 kernel source code. It does need to be enabled when the kernel is compiled, and it also depends on the Linux firewalling code. The kernel compile-time option for enabling Linux masquerading is CONFIG_IP_MASQUERADE=Y.
In order to use all of the facilities of ipchains and masquerading, you will also need the ipchains and ipmasqadm commands used to define the filtering and masquerading rules.
ipchains rules are built incrementally; when the machine boots, it installs the rules in order, so there will be a brief period while it is initializing when the chain is not fully built, and the default policy will be used before the end of the chain has been configured. If the default policy is to accept packets, you may accept packets that you would otherwise have denied. You should therefore put in an initial explicit default policy that denies packets.
One tempting way to avoid this problem is to build the chains before you actually configure the network interfaces (if you can't receive the packets, there's no need to worry about what you do with them). In most situations, this won't work because rules will be rejected if they refer to network interfaces that haven't been configured. If you have a configuration of the kind we recommend, you will have to configure the network interface before you can build the chains you are actually going to use. Thus, you will end up using two bootup scripts for the ipchains configuration. The first script will initialize default deny policies for each chain; the second will load the rules you wish to use. When combined with the network interface configuration scripts, this will result in the following three-stage process:
- Load default deny polices that do not specify an interface.
- Configure the network interfaces.
- Load the real ipchains rules you're going to use.
When masquerading is operating, the standard Unix netstat program does not list masqueraded ports. This means that the machine will be accepting packets for ports that don't show up when you run netstat, which may be disconcerting to experienced network administrators.
ipfilter
ipfilter is another packet filtering system for Unix. It works on the free BSD implementations (FreeBSD, OpenBSD, and NetBSD) and has also been ported to and tested on other Unix operating systems including Solaris and previous versions of SunOS, IRIX, and Linux.ipfilter uses a list of rules contained in a single configuration file. Unlike ipchains, ipfilter checks all rules in sequence, and the last rule that successfully matches determines the fate of a packet. This can be a great source of confusion. Imagine a filtering configuration file containing only the following rules:
This will pass all packets because the second rule is the last rule that matches. Fortunately an ipfilter rule can specify the "quick" keyword, which if the rule matches, will terminate the rule checking at that point. The following rules would block all traffic:block in all pass in all
Rules may be arranged into groups, which allows you to make more complicated configurations quite easily. A group has a head rule, which is checked to determine whether the rest of the rules in the group are executed. If the group is executed, the rules in it are handled in the normal way. At the end of the group, processing continues at the next line.block in quick all pass in all
The conditions in a rule can be based on any of the following:
- The IP protocol number (for example TCP, UDP, ICMP, or IGMP).
- The IP options that are set.
- The source and destination IP addresses. Addresses can be specified as a variable-length subnet (for example 192.168.8.0/22) or a network address with a mask, and negation is allowed (you can specify "all addresses except those that match this address and mask").
- The source and destination TCP and UDP port numbers. Port numbers can be specified with ranges or masks, and negation is allowed.
- The ICMP type and code.
- Whether the packet is an IP fragment. Fragments that are too short to contain port numbers, and thus could prevent port rules from being applied, can be explicitly handled.
- The TCP flags that are set (for instance, the ACK and SYN bits that let you identify a start of connection packet).
- The network interface the packet came in on.
- Drop the packet without generating a response.
- Don't process the packet, but return an ICMP response (you can specify what ICMP response to return).
- Don't process the packet, but return a TCP reset.
- Process the packet.
- Process the packet, keeping state information to make sure that all TCP packets are part of a valid TCP conversation, with appropriate settings of SYN and ACK and appropriate sequence numbers.
- Change IP address and/or port number information in the packet using a static mapping (this is a simple form of network address translation).
- Send the packet or a copy of it to a specified network interface or address for logging purposes.
- Log information about the packet via syslog.
Comparing ipfilter and ipchains
ipfilter and ipchains provide roughly the same functionality; in many cases, people choose between them based on the operating system they're using, using ipchains on Linux and ipfilter on other operating systems. On the other hand, they do have distinct strengths and weaknesses.ipchains is much stronger as a network address translation system. The network address translation functionality provided by ipfilter is minimal and is not dynamically updatable. ipchains is also provided as part of Linux, so that it doesn't require separate integration.
ipfilter provides filtering capabilities that ipchains does not (allowing you to filter on IP options and providing more flexible handling of TCP options, for instance), and it is more flexible about the responses it gives to blocked packets. Its packet duplication features are useful for feeding packets to intrusion detection systems.
The architecture of ipchains makes it much easier to extend than ipfilter, so it's likely that the extra ipfilter features will eventually show up in ipchains. However, ipchains is relatively tightly integrated with the Linux kernel, which will slow down its spread to other operating systems.
Linux netfilter
At this writing, the Linux packet filtering and network address translation systems are being rewritten. The new filtering system is called netfilter, and it has several goals. One is to reduce the number of points in the Linux kernel where filtering occurs. Another is to have a clean separation of filtering from network address translation. As a result of this separation, netfilter is no longer capable of modifying packets. Some of the concepts from ipchains still exist in netfilter; in particular, lists of filtering rules are built into named chains. The significant features that have been added to netfilter are:- The ability to filter on both the input and output interface in the forward chain
- The ability to pass packets to user-level processes for handling
Windows Packet Filtering
Windows 4 comes with a very limited ability to do packet filtering, suitable only for protecting the machine itself, and that only in some circumstances. From the Network control panel, when you are configuring TCP/IP properties, you can go to the IP address tab and select Advanced. You have two different ways of doing filtering:- The Enable PPTP Filtering button will restrict the interface to only using PPTP.[20]
[20]See "Remote Procedure Call (RPC)", for more information about PPTP.
- The Configure button under Enable Security will let you configure filtering by TCP port, UDP port, or IP protocol.
This packet filtering is extremely minimal, and there are very few situations where it's possible to use it. It is useful for machines that are using PPTP, or that are bastion hosts providing single services like HTTP. Some of the problems with it are not immediately obvious and are frequently unpleasant surprises to people trying to use this packet filtering:
- It controls only incoming packets without ACK set; it will not limit outbound connections.
- The "IP protocol" entries do not control UDP and TCP; if you wish to deny UDP and TCP, you must set the TCP and UDP entries to allow only specified ports and then avoid specifying any ports.
- It will not deny ICMP, even if you set the IP protocol to allow only specified ports and avoid including ICMP.
Windows 2000 provides packet filtering in a third place as part of its implementation of IPsec (IPsec is discussed further in "Intermediary Protocols"). This packet filtering is comparable to the Routing and Remote Access Service filtering for Windows 4, except that it is possible to combine filters into sets (allowing you to mix allow and deny rules), and a rule can apply four possible actions:
- Permit all packets that match, regardless of their IPsec status.
- Block all packets that match, regardless of their IPsec status.
- Request IPsec protections on all packets that match, but accept them if IPsec is not available.
- Require IPsec protections on all packets that match, and reject them if IPsec is not available.
Ironically, the most powerful packet filtering package that Microsoft makes available for Windows is actually part of Microsoft's Proxy Server. While it still does not provide all of the features that a packet filtering router would provide, it does include alerting and logging options, specification of port ranges, and filtering of fragments. As of this writing, a new version of Proxy Server is due out shortly, and it is expected to have still more packet filtering features.