How Netfilter Works
As I mentioned earlier, for Netfilter to work, you'll need the user space program called iptables. Get the latest version (currently iptables-1.1.1), and build and install it. In the future, the author promises tools to accompany iptables, similar to the ipchains-save and ipchains-restore utilities. But for now, you'll just have to ensure that all your rules are in a script ready to go at boot time.
Netfilter is about rules. Rules work on packets. Each rule is written to do something, and that something is called a target. The rules belong to chains, which are used to group the rules. As you'll also see, the chains that are traversed depend on the packet. Each chain belongs to a table. The table used depends on your requirements. In the next few paragraphs, you'll take a look at targets, chains, and tables, in that order.
Rules work on packets. If a rule matches a packet, then the target is executed on that packet. The built-in targets are ACCEPT, REJECT, and DROP. This corresponds in ipchains to ACCEPT, REJECT, and DENY. You can do more, such as LOG, QUEUE, and RETURN. Of the six mentioned targets, only fourACCEPT, DROP, QUEUE, and RETURNare built in. If you want to use REJECT or LOG, you'll need to insert the appropriate module. But don't panic. You'll handle the modules later.
The Five Built-in Chains
Think of your system as a black box. Outside this black box is a processor that lies just beyond your incoming interface (whatever that may be, Ethernet card, modem, wireless antenna, and so on). This processor will grab all packets destined for your system before they enter the interface. This area is called prerouting. While it's true that packets won'tnay, can'tbe acted upon by the system before they've entered the system, it's easier to think of them as being acted on here so that when they hit the interface, they've already been changed and are ready for routing. So, our PREROUTING chain rules are applied before the system (actually, the routing table) is consulted about the packet's destination.
Inside the system are three more chains. These chains are the INPUT, FORWARD, and OUTPUT chains. Arriving packets will go to either one of the INPUT or FORWARD chains. Packets that are only transiting the system will go only to the FORWARD chain, and packets destined only for the local system will go only to the INPUT chain. This is a change from the 2.2.x ipchains software that had every transiting packet going to the INPUT chain first. Packets leaving the system from the local system will travel the OUTPUT chain only.
When packets leave the box (yes, this actually happens before they leave), they can hit one last chain, the POSTROUTING chain. Again, if you think of the change happening as the packet hits the wire, it's a little easier to imagine the flow.
The Three Netfilter Tables
The Netfilter framework is divided into three separate tables: filter, nat, and mangle. Each table affects only certain parts of the overall Netfilter scheme. The default table is the filter table. This is the table you'll use most often and coincides most closely to ipchains.
The other two tables you'll want to know about are the mangle table and the nat table. To do anything with either of these tables, they must be explicitly mentioned. Let me reiterate that: To do anything with any table other than the default filter table, you must declare the table. You don't need to specifically declare the filter table, but you might want to do that just to reinforce which table you're using.
So, to list the nat table, you need to declare it first. To create a user-defined chain for the mangle table, you need to declare the table. Before we get into actually building rules, let's take a look at what I'm talking about. This short exercise will show you two things: that table declaration is most certainly required for other than the filter table, and definitively which built-in chains belong to which table.
On your system (assuming that you're using a 2.4.0 kernel and have iptables installed and the Netfilter modules inserted), try these commands (must be root):
iptables -L -n iptables -t filter -L -n iptables -t mangle -L -n iptables -t nat -L -n
As you run these, note the differences. The first two commands return exactly the same thing:
Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
Because you've not yet defined any rules, none but the default policy exists. So, you can see the chains in their pristine state.
The first two commands work on the filter table to return a list of all rules in all the chains that pertain to the filter table. The -n is for numeric so that you're not trying to resolve DNS, which slows down the table listings. If you had any user-defined filter table chains, they would be listed here.
Now you know that the filter table consists initially of the INPUT, FORWARD, and OUTPUT chains. Again, remember, only one of these chains will be used for any given packet. Packets destined for the FORWARD chain will not traverse the INPUT chain.
The third command, given previously, will return the following:
Chain PREROUTING (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
So, the mangle table works initially only with the two built-in chains PREROUTING and OUTPUT. If you try to write a rule using -t mangle (the mangle table) and write that rule to any of the other three built-in tables or any user-defined chain not declared as a mangle table chain, the rule will fail.
The final list command given previously will return this:
Chain PREROUTING (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
So, your network address translation (nat) table, one that will be of great interest to many of you, works initially only with the PREROUTING, POSTROUTING, and OUTPUT built-in chains.
Notice that the OUTPUT chain can accept rules for any of the tables. The PREROUTING chain can accept rules for any of the mangle or nat tables. These two chains are exceptions. No other chain can belong to more than one table at a time. So, user-defined chains will be created as part of one table and will not accept rules for any other table. We'll revisit this with a few rule examples in the last article.
Next, we'll start writing rules and see how this all works.