IPTABLES – Configuration & Syntax

Standard

Configuration & Syntax

Document conventions

eth0 – name of your external interface (connected to the world)
eth1 – name of your internal interface (connected to the LAN)”
ip_address_of_eth0 – numeric dotted quad IP address of your eth0 in the form of x.x.x.x
ip_address_of_eth1 – numeric dotted quad IP address of your eth1 in the form of x.x.x.x

Tables, chains, and rules

Catholic jokes aside, when you construct firewall rules using Iptables, it’s important to understand the distinction between tables, chains and rules.

A table provides a certain functionality. The default tables are filter, nat, and mangle (unless you applied the experimental drop table patch). There is no way (and reason) to create custom tables via syntax.

A chain is the path that a packet can travel. Different tables contain different built-in chains (more below). User defined chains can be targets of built-in chains. If a packet traverses through a custom chain without a match, it is returned to the calling chain. If a packet traverses through a built-in chain, it is accepted or dropped depending on the default policy that chain.

Rules are what you put in chains to achieve a desired match.

Packet Traversal

Before you can make effective rules, you’ll first have to understand how a packet travels though Netfilter’s tables and chains.

packet traversal diagram

More details of how a packet traverses netfilter can be found at http://ods.dyndns.org/ipt_flow.html. With the permission of the author, I’ve mirrored the page at http://www.knowplace.org/netfilter/ipt_flow_mirror.html.

Bootstrapping Iptables

  • Insert connection-tracking modules (only needed if not built into the kernel).

    modprobe ip_tables
    modprobe ip_conntrack
    modprobe ip_conntrack_ftp
    (needed only if you plan on using FTP)

  • Set the default policies – sets the default actions of the built-in chains.

    iptables -P INPUT DROP
    iptables -P FORWARD DROP
    iptables -P OUTPUT ACCEPT

Chain syntax

  • Create a new chain

    iptables -N name_of_chain

  • Delete an empty chain – only for custom chains

    iptables -X name_of_chain*
    *if name_of_chain is omitted, it deletes all custom
    chains.

  • Change the default policy for a built-in chain

    iptables -P name_of_chain name_of_policy*
    *DROP or ACCEPT

  • List the rules in a chain

    iptables -L name_of_chain

  • Flush the rules out of a chain

    iptables -F name_of_chain*
    *if name_of_chain is omitted, it flushes all chains.

  • Zero the packet and byte counters on all rules in a chain

    iptables -Z name_of_chain

Rule syntax

A typical Iptables rule command will specify:

  • A table (-t table_name). If omitted, this will default to the filter table. Other built-in tables are nat and mangle.
  • A rule action to perform on a chain to either append (-A) , delete (-D) or replace (-R) or insert (-I) followed by the name of a chain in this table
    • Built-in chains for the filter table are INPUT, FORWARD and OUTPUT
    • Built-in chains for the nat table are PREROUTING, POSTROUTING and OUTPUT
    • Built-in chains for the mangle table are PREROUTING and OUTPUT
  • What to match – Available matches are (this list is incomplete):
    • -p (protocol: TCP, UDP, ICMP, etc – can be numeric – see /etc/protocols)
    • -s (source address)
    • -d (destination address)
    • -i (incoming interface)
    • -o (outgoing interface – note that this specifies the interface to send the packet; this does not match the interface origin of the packet)
    • –fragment (will only attempt to match second and further fragments of fragmented packets since there is no way to tell the source and destination ports, or ICMP type of such a packet)
    • –dport (destination port)
    • –sport (source port)
    • -port (source and destination ports are equal to the specificified value)
    • –mark (nfmark value)
    • –tcp-flags (allows TCP flags based matching)
    • –syn (shorthand for –tcp-flags SYN,RST,ACK SYN)
    • –tcp-option (examines the numeric value of the TCP option in a TCP header – will drop packet if the TCP header is incomplete)
    • –state (NEW, ESTABLISHED, RELATED, INVALID)
    • –mac-source (source MAC address)
    • -m unclean (this actually loads a module to attempt to match unusual or malformed packets – EXPERIMENTAL)
    • –tos (TOS value of the packet)
    • –ttl (ttl value of the packet)
      General rate limit section
    • –limit (match rate limiting – value can be give in seconds, minute, hour, or day)
    • limit-burst (maximum burst number before the imposing the set rate limit)
      IP based rate limit section (TCP) – experiemental
    • –iplimit-above – allows you to restrict the number of parallel TCP connections by IP address or address block
      Owner matching section
    • –uid-owner userid (matches if the packet was created by a process with the given effective numeric user ID)
    • –gid-owner groupid (matches if the packet was created by a process with the given effective numeric group ID)
    • –pid-owner processid (matches if the packet was created by a process with the given process ID)
    • –sid-owner sessionid (matches if the packet was created by a process in the given session group)
      Port scan detection section – experimental
    • –psd-weight-threshold (threshold)
    • –psd-delay-threshold (delay)
    • –psd-lo-ports-weight (weight)
    • –psd-hi-ports-weight (weight)
  • Where to send the packet if it matches. Available targets are:
    • ACCEPT – accept the packet
    • DROP – silently drop the packet
    • REJECT – drop the packet and inform the sender
    • LOG – log the packet via syslogd and continue traversal
    • ULOG – send the packet to an userspace logging process (experimental)
    • MIRROR – swap the source/destination IP address and resend the packet (experimental)
    • QUEUE – queue the packet to an userspace process – if there is no userspace process, the packet is eventually dropped
    • RETURN – return to previous (calling) chain
    • Name_of_a_custom chain – user defined, typically in lowercase but can be in uppercase as well

For example: iptables -t mangle -A PREROUTING -m state –state NEW -d 255.255.255.255 -i eth0 -j DROP (this command appends a rule to the PREROUTING chain of the mangle table, loads the state module, matches packets that initiate new connections to eth0 with a destination address of 255.255.255.255 and drops the matching packets without logging it)

Iptables rules for a simple masquerading gateway (no server services)

  • Blocks all new connections unless initiated from the “protected” network.

    iptables -N state_chk
    iptables -A state_chk -m state –state ESTABLISHED,RELATED -j ACCEPT
    iptables -A state_chk -m state –state NEW -i ! eth0 -j ACCEPT
    iptables -A state_chk -j DROP

  • Jump to the state_chk chain from INPUT and FORWARD chains.

    iptables -A INPUT -j state_chk
    iptables -A FORWARD -j state_chk

  • Masquerade connections – only needed on the firewall box if you have an internal network that you wish to route traffic to and from the Internet.
    • Enable IP forwarding between the interfaces – remember to disable this if you’re going to unload the Iptables rules.

      echo “1” > /proc/sys/net/ipv4/ip_forward

    • Load the NAT modules – needed only if you compiled as modules

      modprobe iptable_nat
      modprobe ip_nat_ftp
      (needed only if you plan on using FTP)

    • Enable IP masquerading – Use if your eth0 has a dynamic IP address. For static IP, it’s recommended that you use source NAT instead.

      iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

    • Enable source NAT – Use if your eth0 has a static IP address.

      iptables -t nat -A POSTROUTING -o eth0 -j SNAT –to ip_address_of_eth0

Port Forwarding

Port Forwarding in Netfilter is done with Iptables. You do not need another tool (such as ipmasqadmin w/ Ipchains). This is only needed if you need to forward traffic from one machine to another. Note that this is different from redirecting traffic.

Port forwarding under Netfilter is done via a two step process.

  • Destination NAT the packets (changes the destination IP address in the IP header and port number in the TCP/UDP header)

    iptables -t nat -A PREROUTING -i eth0 -p protocol -d ip_address_of_eth0 –dport original_port_number -j DNAT –to destination_ip_address:destination_port_number

  • Forward the natted packets (allow the natted packet to be forwarded)

    iptables -A FORWARD -i eth0 -o eth1 -p protocol -d destination_ip_address –dport destination_port_number -j ACCEPT

Note that port forwarding also requires IP forwarding and masq’ing or source NAT (the return packets need their source IP addresses to be modified as well).

Putting it together (rc files and such)

Now that you have your first working firewall, you’ll probably want to keep these rules in effect between boots. There are basically two options. The first is to include all of the rules and syntax in a custom rc shell script. The second is to use the iptables-save and iptables-restore commands (currently experimental and only recommended for brave souls).

To use the rc script approach, start your firewall rc file immediately after your network initiation. Actually, the exact time that you start your firewall rc script isn’t that crucial because you can setup rules for interfaces that don’t exist.

Iptables help

  • For a brief description/usage of a specific target

    iptables -j name_of_TARGET –help
  • For a brief description/usage of a specific match

    iptables -m name_of_match –help

  • For a listing of icmp message types

    iptables -p icmp –help

Note that below is simply the output of ‘iptables -h’. It is not a complete list of options. For more details, please see the iptables(8) man pages.

iptables v1.2.2    Usage: iptables -[ADC] chain rule-specification [options]         iptables -[RI] chain rulenum rule-specification [options]         iptables -D chain rulenum [options]         iptables -[LFZ] [chain] [options]         iptables -[NX] chain         iptables -E old-chain-name new-chain-name         iptables -P chain target [options]         iptables -h (print this help information)    Commands:  Either long or short options are allowed.    --append  -A chain            Append to chain    --delete  -D chain            Delete matching rule from chain    --delete  -D chain rulenum                                  Delete rule rulenum (1 = first) from chain    --insert  -I chain [rulenum]                                  Insert in chain as rulenum (default 1=first)    --replace -R chain rulenum                                  Replace rule rulenum (1 = first) in chain    --list    -L [chain]          List the rules in a chain or all chains    --flush   -F [chain]          Delete all rules in  chain or all chains    --zero    -Z [chain]          Zero counters in chain or all chains    --check   -C chain            Test this packet on chain    --new     -N chain            Create a new user-defined chain    --delete-chain              -X [chain]          Delete a user-defined chain    --policy  -P chain target                                  Change policy on chain to target    --rename-chain              -E old-chain new-chain                                  Change chain name, (moving any references)  Options:    --proto       -p [!] proto    protocol: by number or name, eg. `tcp'    --source      -s [!] address[/mask]                                  source specification    --destination -d [!] address[/mask]                                  destination specification    --in-interface -i [!] input name[+]                                  network interface name ([+] for wildcard)    --jump        -j target                                  target for rule (may load target extension)    --match       -m match                                  extended match (may load extension)    --numeric     -n              numeric output of addresses and ports    --out-interface -o [!] output name[+]                                  network interface name ([+] for wildcard)    --table       -t table        table to manipulate (default: `filter')    --verbose     -v              verbose mode    --line-numbers                print line numbers when listing    --exact       -x              expand numbers (display exact values)  [!] --fragment  -f              match second or further fragments only    --modprobe=          try to insert modules using this command    --set-counters PKTS BYTES     set the counter during insert/append  [!] --version   -V              print package version.