Linux Firewalls with IPTables

Share on:

The network firewall system used in Linux is called iptables. This is a brief overview of the system to the extent that I need to understand it if I want to fix my current firewall setup.

IPTables System Structure

IPTables is made up of a database of network packet processing rules, and an engine that executes the rules as network packets flow through the computer. The database is made up of four tables, each of which handles a different stage of packet processing. Each table includes several chains, some of which are predefined for each table and some of which are created by the user. Each chain has a name and a number of processing rules.
tables            filter                       nat         ...
                    |                           |
            +-------+--------+             +-------+
            |       |        |             |       |
chains    INPUT   OUTPUT  mychain        INPUT   OUTPUT    ...
            |       |        |             |       |
rules     Rule    Rule     Rule          Rule    Rule
          Rule    Rule     Rule                  Rule
          Rule             Rule


There are four tables. The difference between each is the types of actions that the tables can take when processing a packet, and the stage at which the rules execution engine invokes the chains of the table.
  • raw: Rules in this table serves only to turn on or off the "connection tracking" feature (in which iptables can determine, for any given packet, whether it is part of an established TCP connection).
  • mangle: Rules in this table can manipulate some of the TCP header information in a packet, such as TOS or TTL.
  • nat: Rules in this table can modify the sender/recipient addresses (for example, so that the computer can act as a router).
  • filter: Rules in this table can drop or reject packets, among other things.
The filter table is, by far, the most important in terms of setting up a firewall.


Each table is made up of several chains, each of which contains a sequential list of rules. The execution engine "executes" a chain for a given packet by applying each of the chain's rules to the packet in sequence. Some of these chains are predefined, and those chains are executed at appropriate times during packet processing, as explained in the table below. Other chains are user-defined, and they are executed when called from another chain (somewhat like subroutines).
Chain When Executed Which Chains
PREROUTING Upon receiving a packet at a network interface All chains
OUTPUT Upon receiving a packet from a local process All chains
INPUT Upon receiving a packet at a network interface, after determining that it is being directed to a local process mangle, filter
FORWARD Upon receiving a packet at a network interface, after determining that it is directed to another computer mangle, filter
POSTROUTING Immediately before sending a packet out of a network interface mangle, nat
For each of the predefined chains above, the raw table chain is always executed first, followed by the mangle, nat, and finally filter tables. PREROUTING is always done before INPUT or FILTER, and POSTROUTING is always done after OUTPUT or FILTER.


A rule is made up of two parts: a matching condition and a target. When the execution engine applies a rule to a packet, it checks whether the packet satisfies the matching condition of the rule, and if so, then it performs an action defined by the target.

The matching conditions are tests of various parts of the packet header and content, such as source and destination addresses and ports. The possible matching conditions are described below in the discussion of the iptables command.

The target may be one of two types: a predefined target, which performs an action internally defined by iptables, and a jump to another chain. Predefined targets may specify changes to packet contents, direct the execution engine to accept or drop a packet, or control the flow of rules execution. Some predefined targets may halt further execution of rules. Some particular predefined targets are described below in the discussion of the iptables command.

In the case of a jump, the execution engine proceeds to execute the other chain. Assuming that execution is not halted after that other chain is executed, the engine returns to the chain from which the jump was made, and execution of the calling chain proceeds with the next rule.

As a catch-all, each predefined chain has a default target, called a policy. The default target must be a predefined target.

Command-Line Management of Rules

Rules in iptables are managed with the iptables command. It must be run as the root user.

The iptables command line interface is entirely driven by command-line options. At least one option must be specified: the option identifying the operation to be performed. The various operations are described below.

Every invocation of iptables can accept the -t option to select the table to manipulate. By default, the filter table is used. Many commands also use a rule-specification, which describes a complete rule including matching condition and target. The syntax of a rule-specification is described after the listing of operations.

Operations Managing Chains

  • -N [chain-name]: create a new user-defined chain in the specified table.
  • -X [chain-name]: delete a user-defined chain from the specified table. The chain must have no rules and not be the destination of any jump.
  • -F [chain-name]: delete all of the rules in a chain.
  • -P [chain-name] [target]: set the policy for a chain.

Operations for Displaying Chains

  • -L [chain-name]: list all the rules in a chain (or all chains, if none is specified). The -v option will add packet and byte counts.
  • -S [chain-name]: list all the rules in a chain, in a different format.

Operations for Managing Rules in a Chain

  • -A [chain] [rule-specification]: append a rule to the end of a chain.
  • -C [chain] [rule-specification]: check to see that a rule matching the given rule specification is present in the chain.
  • -D [chain] [rule-specification]: delete a rule matching the given specification, from the chain.
  • -D [chain] [rule-number]: delete a rule from the chain based on the rule's position in the chain, where the first rule is 1.
  • -I [chain] [rule-number] [rule-specification]: insert a rule above the specified position in the chain (so rule number 1 would place the rule at the top of the chain).
  • -R [chain] [rule-number] [rule-specification]: replace the rule at the specified position.

Rule Specifications: Matching Conditions

Matching conditions of rule specifications are made up of key-value pairs, with the keys specified as command-line options and the values as arguments to the options. Some of the more common ones are as follows:
  • -p [protocol]: the packet's protocol must be of the specified type (e.g., tcp).
  • -s [addresses]: the source address of the packet must match one of the given addresses (a list of addresses, possibly with CIDR masks, separated by commas).
  • -d [addresses]: the destination address of the packet must match one of the given addresses.
Further matching conditions can be introduced through the match extensions mechanism. First, an appropriate module must be loaded through the -m [module] option. (As a convenience, specifying a protocol with -p automatically loads a module with the same name.) Then, all of the matching conditions of the module become available.

The most common of these are the --destination-port options of the tcp module, and the analogous (pluralized) options of the multiport module.

Rule Specifications: Targets

Targets are also specified as key-value pairs expressed as command-line options. One option must always be included: the -j [target] (for jump) option, specifying the name of the user-defined chain or predefined target. Some of the predefined targets require further options as well.

A partial listing of predefined targets is below:

  • ACCEPT: allow the packet through, and terminate execution of all rules.
  • DROP: drop the packet, and terminate execution of all rules.
  • REJECT: drop the packet, send an ICMP reply, and terminate execution. This is preferred over DROP because, to a port scanner, it looks the same as a closed port.