ipchains is a packet-filtering architecture consisting of an infrastructure in the Linux kernel and a user-space program to manage rules lists, like all packet-filtering architectures currently implemented in Linux. In Linux 2.2, this product is called ipchains. (See Figure 19-2.) Section 19.2.1 will discuss its invocation syntax and how we can define rules. Figure 19-2. The packet-filtering architecture in Linux 2.2 (ipchains). The filtering mechanisms implemented in Linux kernel Version 2.2 divide all data packets into the following three classes, depending on their source and destination addresses: incoming packets those addressed to the local computer; packets to be forwarded and leaving the local computer over a different network interface based on a routing decision; outgoing packets created in the local computer. For each of these classes, the network stack of the respective protocol includes a prominent position, and each packet of the corresponding class has to pass it. In each of these positions, there is a hook, where a linked rules list (chain) is hooked, hence the name ipchains. According to the packet class they are allocated to, the rules lists are called input chain, forward chain, and output chain. These chains are organized so that they are processed sequentially, beginning from the first defined rule. If a rule accepts an incoming packet, then this packet is handled according to the branch destination defined in the rule, where Linux Version 2.2 introduced the support of user-defined rules lists. This means that, in addition to the linear processing of rules lists, we can also implement branching. Other possible branch destinations are the following: ACCEPT completes processing of the rules list and releases the packet for further handling. DENY drops the packet. REJECT discards the packet and returns an ICMP message of the "destination unreachable" type to the sender. REDIRECT?an item new with Linux 2.2) makes sense only for the input chain and directs the packet to another local port. This is useful, for example, to implement transparent proxies, where all HTTP requests are redirected from port 80 to the port of a local HTTP proxy. This means that, if a TCP/IP packet is addressed to the local computer, then it first has to undergo the usual verifications of the checksum field and the packet length before it arrives in the input chain, where it is handled according to this rule list. Packets belonging to the second class (addressed to computers in a different network) visit all three rules chains hooked into the kernel in ipchains. As mentioned above, they first arrive in the input chain. The destination address is not in the local computer, so the packet is passed to the forward chain. Before this step, the packet is checked to see whether it is a packet masked by NAT. If this is the case, the packet is first unmasked and then passed directly to the output chain, bypassing the forward chain. If the forward chain accepts the packet, then a final step checks it in the output chain, before it leaves the router. Outgoing packets created in the local computer are handled exclusively by the output chain. Each rules list has options to log the network traffic it handles. The counters of these functions have been 64 bits wide since Linux Version 2.2; this much finer granularity, as compared with that of the 32-bit predecessor versions, prevents overflow. In addition to the core functionality covered by ipchains, the packet-filtering architecture of Linux 2.2 uses additional modules to support more complex protocols, including active FTP (see Section 19.2.1), RealAudio or CUSeeMe, which are controlled over additional management tools (e.g., ipmasqadm). The entire core functionality is managed in the ipchains program, which is described in more detail below. 19.2.1 The ipchains Rule Syntax This section describes the ipchains program, which is used to manage rules lists. The basic structure of a rule definition is given by the following form: ipchains - <operation> <chain> <criterion> -j <branch destination>. Table 19-1 shows command-line options of ipchains and iptables, before we describe the options in detail. Table 19-1. Command-line options of ipchains and iptablesOption | ipchains | iptables |
---|
Standard rules lists: | | | | input | INPUT | | output | OUTPUT | | forward | FORWARD | Branch destinations: | | | Accept packet | -j ACCEPT | -j ACCEPT | Drop packet | -j DENY | -j DROP | Reject packet | -j REJECT | -j REJECT | Convert/mask address | -j MASQ | -j MASQUERADE | Redirect to other port | -j REDIRECT | -j <Port> | Return from rules list | -j RETURN | -j RETURN | Log packet (log) | -j <branch destination> | -j LOG | | -l | | Criteria for filter rules: | | | IP source address (source) | -s [!] <address> | -s [!] <address> | IP destination address (destination) | -d [!] <address> | -d [!] <address> | Source address and source port | -s [!] <address> | -s [!] <address> | | [!] <port> | sport [!] <port> | Destination address and destination port | -d [!] <address> | -d [!] <address> | | [!] <port> | -dport [!] <port> | Transport protocol | -p <protocol> | -p <protocol> | Network device (interface) | -i [!] <device> | -i [!] <device> | TCP-SYN flag set | [!] -y | [!] -y | Fragments (consecutive packets) | [!] -f | [!] -f |
Operation: We can use one of the keywords listed in Table 19-1 to specify how we want the existing rules list to be manipulated. We use APPEND to build a list, which means that the new rule we just defined is appended to the end of a list. To generate a user-defined rules list, we use NEW. User-defined rules lists behave like subfunctions of the respective lists. This means that, when they are reached, they are evaluated with regard to the current packet and then this packet is returned to the calling rules list, if none of the other rules applies to the packet. Chain: This is the rules list (input, output, forward, or a user-defined list) that the operation should run on. Criterion: This is the most complex part of the definition; it specifies packets that this rule should be applied on. First, the protocol (-p <protocol<) and ranges for the source and destination addresses (-s <address(es)> and -d <address(es)>, respectively) are defined. In addition, we can limit the validity range for the TCP and UDP protocols to specific port numbers (-s <address(es)> <port(s)> and -d <address(es)> <port(s)>, respectively). The criterion -i <interface> can be used to select only packets that arrive at or leave from a specific interface. For the TCP protocol, we can use -y to specify that only packets with the SYN flag set and the ACK flag cleared should be considered. (See Section 19.1.2.) We can use -f to specify that the rule should apply only to the second and all consecutive fragments of a fragmented IP packet. This criterion can be thought of as a simpler predecessor of the netfilter introduced in Chapter 20, which implements stateful connection tracking. Only the first fragment includes the transport protocol header, so we cannot specify port numbers together with this criterion. All criteria can be negated by a leading exclamation sign?-s ! 127.0.0.1 would select all packets with a source address unequal 127.0.0.1. Branch destination: This parameter specifies what should happen to packets subject to these rules. ACCEPT lets these packet pass; DENY discards the packets silently; REJECT returns an ICMP error message of the type "Destination Unreachable" to the sender before it drops them. The branch destination RETURN is used for a conditioned return from a rules chain. This is particularly interesting during handling of user-defined rules lists, because it allows us to return to the calling rules lists. Packets can be lgoged by the sys log mechanism by stating -l (log), in addition to one of the above branch destinations. This allows us, for example, to better detect and trace attempts of attacks (which means that one of the criteria described in Section 19.1.3 is met) or to monitor the traffic volume at a specific network interface. 19.2.2 Drawbacks of the ipchains Architecture Design flaws were observed soon after the introduction of ipchains in Linux 2.2. The most important problems are as follows: ipchains had no uniform programming interface that would have enabled us to embed new rules lists into the kernel without having to consider network implementation details. For this reason, adding new rules lists was tiresome and extremely error-prone. In contrast, the netfilter architecture supplies a framework that minimizes direct interventions in the network code and allows us to append additional code in the form of modules for packet mangling into the kernel by using the regular interface. The integration of code for transparent proxies was expensive in ipchains and was connected to many interventions in the Linux kernel. In ipchains, rules were necessarily bound to a network address in general, which made the creation of rule sets much too complicated, because the address was the only way to distinguish packets generated locally from packets to be forwarded. ipchains implemented "masquerading" (a simple NAT variant) and the packet filter code in one piece, which made the code harder to read and unnecessarily complex. |