Iptables

This post is a collection of notes about iptables, a useful CLI tool to manage the Linux kernel firewall implemented by Netfilter.

There is actually a newer tool created by the same guys called nftables, in this post we will focus in iptables, but it is highly recommended to migrate to nftables.

Key concepts: Tables, Chains, Rules and Targets

To be more specific iptables is a user-space framework intended to manage the builtin Linux kernel firewall, basically with iptables we can set how our system will handle IP packets.

When a packet comes through a device running iptables, it is tested sequentially against a set of rules called chains which are also grouped in a set of builtin tables. These tables are filter, nat, mangle, raw and security, in this blog we will focus on filter (used to filter packets), and nat (used for routing and network address translation operations).

If a packet matches a rule an action is performed, the rule can redirect the packet to another user-defined chain within the same table or a built-in target which determines how the packet will be handled. The most fundamental built-in targets are:

You can find more built-in targets on iptables-extensions(8) manpage.

If the packet reaches the end of a built-in chain or matches a built-in chain rule with RETURN target, iptables will execute their chain policy which is just a default target, (usually ACCEPT or DROP).

As its man page indicates, a user can create a chain using the structure iptables -N chain-name, in the following example we are creating a chain called ICMP in filter table (the option -t filter is not necessary since it is the default table).

# iptables -N ICMP

Also it is possible to make rules in a chain with iptables -A chain-name [matching parameters] -j target, for example what about blocking the ICMP packets on loopback interface:

# iptables -A ICMP -p icmp -i lo -j DROP
# iptables -A INPUT -p icmp -j ICMP

The first line creates a rule on our previously created ICMP chain which drops any ICMP packet coming from loop-back interface while the other one redirects all incoming ICMP traffic to our chain.

Now lets explore two knee applications where iptables becomes handy, to keep it simple we will create the rules in built-in chains:

Port Forwarding

Suppose we have an isolated device A hosting an https service connected to device B which is accessible through the domain foo.org. Device B and device A are in the Local Area Network (LAN) 192.168.4.0/24, where B has 192.168.4.1 and A has 192.168.4.10 as IP addresses.

If device B system has iptables, it is possible to redirect one port on device B to device A service using the following commands:

# iptables -tnat -A PREROUTING -p tcp,udp -j DNAT --dport 8443 --to-destination 192.168.4.10:443
# iptables -tnat -A POSTROUTING -j MASQUERADE

In the example above the port 8443 was set to redirect all tcp and udp traffic to 192.168.4.10:443, therefore HTTPS service hosted by A can be accessed using https://foo.org:8443 URL.

Filtering IPs

Iptables can also be set to filter packages, one example of this could be setting up the host to ignore outside traffic. Lets suppose you want to configure the device 192.168.100.2 to receive packets from 192.168.100.0/24.

# iptables -tfilter -P INPUT DROP
# iptables -tfilter -A INPUT -s 192.168.100.0/24 -j ACCEPT 

The first line tells the device to drop all incomming packets by default, and the second sets a rule to accept incomming packets from 192.168.100.0/24 network.

iptables_filter

The above configuration comes with the cost of iptables also blocking the content of loopback interface, thus to allow its traffic you can run

# iptables -tfilter -A INPUT -i lo -j ACCEPT 

References