Two different kinds of filtering must occur on a boundary machine that is offering services to the Internet on behalf of the protected network behind it, and at the same time forwarding traffic to machines on the protected network. The first set of filtering rules protect the boundary machine from unwanted interference, and the second set protect the machines on the private network. For this reason, some security wizards recommend that the boundary machine that provides the firewalling service be dedicated to that task, and that all other services be provided by separate machines.
The earlier toolset (ipchains) required you to construct rulesets that distinguished between traffic that was traveling to and from the boundary machine, and trafffic that was passing through the boundary machine on its way somewhere else. In addition, because there was no information saved about the state of each connection, there were necessarily some gaps in the coverage of the rules that you could write. These problems have been fixed in the iptables modules. These changes make it much safer to use the boundary machine not only for firewalling, but also for a variety of other services. A useful set of such services is described here.
The iptables program constructs several sets of rule lists (chains) that are then used by the kernel to examine each packet as it arrives, is forwarded, and departs the boundary machine. For this purpose, iptables starts out with three predeclared tables: filter, nat, and mangle.
The first one, filter, holds chains of rules specifying how packets are normally handled as they arrive, pass through, or leave the boundary machine. Three pre-defined chains come with this table: input, forward, and output. As it seems convenient, you can define other chains of rules, and refer to them from the primary rule lists.
The second table, nat, is consulted when an incoming packet attempts to create a new connection. Rules in this table specify what address translation is allowed. We will see how this works in the example on the next page. This table has three built-in chains: prerouting, which holds rules that apply to an arriving packet, output, which holds rules that apply to locally-generated packets, before they are routed for transmission, and postrouting, which holds rules that apply to packets that have been routed, and are about to be transmitted.
The third table, mangle, holds rules to make specialized alterations to packets in several situations. Normally, this table is empty. Its use is not recommended for anyone below the grade of Network Wizard Class III.
Before actually constructing the rules, let us see how they are used to qualify a packet as it is handled by the boundary machine. As an example, here is a fragment of the configuration script that we will examine in detail below. The purpose of this fragment is to classify the various kinds of packets that may appear on the public interface of the boundary machine.
/sbin/iptables -t filter -P input DROP /sbin/iptables -t filter -A input -i eth1 -p tcp -d 22.214.171.124 -j TCP-CHK /sbin/iptables -t filter -A input -i eth1 -p udp -d 126.96.36.199 -j UDP-CHK /sbin/iptables -t filter -A input -i eth1 -p udp -d 188.8.131.52 -j ICMP-CHK /sbin/iptables -t filter -A input -l -j LOG
These commands define a list of input checking rules that will be applied to each packet that arrives on the interface eth1 and is addressed to some socket on the boundary machine. A comparison is made between the packet data and the rule data for each rule in turn. In this example, each packet will be sent to a separate ruleset for proper checking, depending on its protocol, if the destination address is the one for our boundary machine.
The first rule specifies the default handling of a packet that is not handled by any other rule. The policy is to drop it unceremoniously on the ash-heap. The second rule handles TCP traffic by directing it to a separate rule chain for that purpose; the third handles UDP traffic, and the fourth takes care of ICMP traffic. No other packet types are expected for this machine, so anything that is not acceptable is thrown out, after a note is made in the syslog file.
This example illustrates several points. First, we can break rulesets into manageable parts, so that we don't have to consider all protocols, all interfaces, and all combinations of traffic at once. We do this by creating secondary rulesets, each with its own name. These rulesets behave like subroutines; if no rule matches the packet being checked, then control returns to the next rule in the list that invoked ths secondary ruleset.
Second, rules are processed in order from the top; as soon as the pattern-matching code can decide what to do with a packet, it stops applying rules, and takes the indicated action for that packet. Third, there are really only two actions we can take with a packet: ACCEPT or refuse passage to it. If we refuse a packet, we can either DROP it (drop it silently on the ash-heap, carefully avoiding any accordians there), or REJECT it (complain to the sender before dropping it on the ash-heap).
To construct a useful set of rules, then, we need to know which services are offered on the boundary machine, and which kinds of traffic should be allowed to flow through the boundary machine (firewall) onto the protected network. A useful set of services that may be offered on a boundary machine is described in the section on Other Services; deciding what sorts of traffic should be allowed to flow through the firewall is left to you, the firewall manager.