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:
- ACCEPT: lets the package pass through
- DROP: drops the package
- RETURN: stops traversing the chain rules and continue to the next rule in the previous chain.
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.
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