iptables — a comprehensive guide
Sudam Mahagamage Sep 15, 2021
iptables is the command-line interface to the packet filtering functionality
of the Linux kernel firewall — netfilter. It is still widely in use
despite being replaced by nftables. For the sake of simplicity we could say
that iptables allows us to administer the packet management system in Linux,
rather than just a firewall. In this article, I will first explain how
iptables itself works, and then some practical situations it is used in.
The core of iptables is simply rules, which is organized hierarchically in
tables, chains and a list of rules in that order.
When a packet arrives (or leaves, depending on the chain), iptables matches
it against rules in these chains one-by-one. When it finds a match, it jumps
onto the target and performs the action associated with it. If it doesn’t
find a match with any of the rules, it simply does what the default policy
of the chain tells it to. Don’t worry just yet if you didn't get this the
first try, all of these terms are explained individually below.
This is the entire concept of iptables, all packets are run through this
‘filtration system’ of rules, and it also provides more functionality
than just filtering, it also allows you to perform all sorts of different
actions when a packet matches any rules.
Tables
Tables reside at the top of the hierarchy, their function and distinguishing
factor being the roles the rules they contain provide.
A table also contains multiple chains which are essentially a list of rules,
grouped by the point in the flow of the packet. (e.g. just as they arrive on
the NIC, just as they leave etc.) More on this in the next section.
The tables and their roles are as follows;
The filter table
This is the default and perhaps the most widely used table. This table
contains the rules that provides the actual firewall functionality, it lets
you decide whether a packet should be allowed or denied to reach its
destination.
The nat table
This table contains rules that allows you to route packets to different
hosts on NAT networks by changing the source and destination addresses of
packets. It is often used to allow access to services that can’t be
accessed directly, because they’re on a NAT network.
The mangle table
This table contain the rules that allows you to alter packet headers and
other forms of packet alteration.
The raw table
The raw table allows you to work with packets before the kernel starts
tracking its state. (For example, a packet could be part of a new
connection, or it could be part of an existing connection)
In addition, you can also exempt certain packets from the state-tracking
machinery. This basically means its used to let certain packets bypass the
firewall.
The security table
The security table is consulted after the filter table to implement
mandatory access control network rules. i.e. — it is used by SELinux to
set SELinux context markers on packets.
ChainsComposition
A chain is a string of rules. When a packet is received, it triggers a
netfilter hook, which corresponds to a default chain. iptables finds the
appropriate table, then runs it through the chain and traverses a list of
rules until it finds a match.
A rule is a statement that tells the system what to do with a packet. Rules
can block one type of packet, or forward another type of packet.
The outcome of a rule or where a packet is sent, is called a target.
The default policy of a chain is also a target. The default policy of a
chain is what happens to a packet that matches none of the rules. By
default, all chains have a default policy of allowing packets.
Targets
A target is a decision of what to do with a packet. Typically, this is to
accept it, drop it, or reject it (which sends an error back to the sender).
ACCEPT: This causes iptables to accept the packet.
DROP: iptables drops the packet. To anyone trying to connect to your
system, it would appear like the system didn’t even exist.
REJECT: iptables “rejects” the packet. It sends a “connection
reset” packet in case of TCP, or a “destination host unreachable”
packet in case of UDP or ICMP.
Default Chains
As mentioned earlier, chains represent the point in flow of a data packet.
There are several default chains in iptables and tables contain a specific
set of these chains (but not all of them). It is also possible to have your
own custom chains.
Following is a list of the default chains and what point in flow of a data
packet they represent;
The PREROUTING chain
Rules in this chain apply to packets as they just arrive on the network interface.
The INPUT chain
Rules in this chain apply to packets just before they’re given to a
local process.
The OUTPUT chain
The rules here apply to packets just after they’ve been produced by a process.
The FORWARD chain
The rules here apply to any packets that are routed through the current host.
The POSTROUTING chain
The rules in this chain apply to packets as they just leave the network interface.
skip this section for now
It is important to remember which chains are present in which tables and
also the traversal order of chains. However this section is a bit
overwhelming at first and also better understood after understanding the
flow of a data packet, so I recommend skipping this for now and coming back
to it later.
Table-chain mapping
Packet Flow in iptables
To properly understand the iptables functionality, it can be divided into 3
ideate sections which we will use on a scenario basis;
(Take a quick peek at the complete overview of process section below for a
illustrated view)
Routing —(Referred in this article as the ‘Routing Section’)
Every Inbound packet first arrives at this section. This section is
where its decided whether the packet is to be routed to the Host Inbound
Firewall or out into another address on the network.
Host Inbound Firewall — Packets that are to be sent to a local
socket.
Host Outbound Firewall — Packets that are being sent out of the host.
Packet Entry — Routing Section I
When a packet first enters, it is run through the PREROUTING chains of the
raw, mangle and nat tables, in that order.
The raw table rules check if the packet is to be bypass the firewall or not.
The mangle table rules check if the packet headers needs to be modified in
any way.
The nat table rules are consulted when a packet that creates a new
connection is encountered.
After this PREROUTING processing, a decision is made whether the packet is
intended for the host system or not.
If it is, it is then sent to the Host Firewall section, otherwise it is sent
to the FORWARD processing area of the Routing section.
Host Inbound Firewall Section
After a packet enters this section, it is then sent to this INPUT processing
section where it is run through the mangle, filter and security tables, in
that order.
The mangle table rules check if any headers or packet alteration is to be made.
The filter table INPUT chain is where most of the commonly used firewall
functionality happens. The rules in this table are what decides whether a
packet is dropped or accepted before it is allowed to reach a host application.
The security table INPUT chain implements any mandatory access control,
mostly checking for SeLinux Context in data packets.
The packet is finally received by the Host Application.
Host Outbound Firewall Section
You can also implement an outbound firewall to control what data is leaving
your computer. This is done by OUTPUT chain processing where it is run
through the raw, mangle, nat, filter and security tables in that order.
The raw table OUTPUT chain rules decides whether the packet has
privileges to bypass the firewall.
The mangle table OUTPUT chain rules decides whether the packet headers
needs to be modified.
The nat table rules are consulted when a packet that creates a new
connection is encountered.
The filter table OUTPUT chain rules is where we decide whether we want
to allow or deny the packet.
The security table OUTPUT chain rules implements access control and
SeLinux Control of data packets.
It is then sent to Routing Section II where it is decided whether the
packet is routable or not.
Packet Exit — Routing Section II
This is the area of the routing section where a packet is redirected outside
the host. It is sent through the FORWARD chains of the mangle, filter and
security tables, in that order.
The mangle tables rules decide if any packet headers needs to modified
before routing it out.
The filter table rules allows us to decide whether or not we want to
allow this packet to be routed.
The security table rules decides whether the selinux or access control
wants to allow this packet to be routed.
Then it reaches section II, which is the same as step 6 in the outbound
firewall, here it is first checked if this packet is routable or not.
Its dropped if it is not routable.
If it is routable then it is sent through POSTROUTING chains of the
mangle and nat tables in that order.
The mangle table rules decide if any packet headers needed to be
modified after finding out it is routable.
The nat table rules are consulted when a packet that creates a new
connection is encountered.
The packet is finally sent to the outbound interface.
Complete Overview of Process
Following is a holistic view of the entire process and can be used as a
cheat-sheet to understand the whole process in one shot. I have also uploaded a
higher resolution image of the above here.
Another helpful illustration from this great article by Ivan
Using iptables and practical uses
Now that we learnt how iptables actually works, lets see how to actually use it.
Note
The different internet protocols are handled differently in the kernel,
so there’s the command iptables for IPv4 and ip6tables for IPv6, however
it works and is used in a very similar way.Command Syntax
Lets take a look at the command syntax specified in iptables itself;
sudo iptables [option] CHAIN_rule [-j target]An example command;sudo iptables –A INPUT –s 192.168.0.27 –j ACCEPT
The same command in long format;
sudo iptables --append INPUT –-source 192.168.0.27 –-jump DROP
For the sake of easier comprehension we will only be using the long format
in this article, you can switch to the short format in your real use.
Now you know how the commands look like, lets understand them. The best way
to do this is by explaining real scenarios that we might run into.
Scenario 1: Blocking IPs
One of the most common use cases of a firewall, this is how we do it.
iptables \
--table filter \ # Use the filter table
--append INPUT \ # Append to the INPUT chain
--source 59.45.175.62 \ # This source address
--jump REJECT # Use the target Reject
If you want to delete this exact rule;
iptables \
--table filter \ # Use the filter table
--delete INPUT \ # Delete from the INPUT chain
--source 59.45.175.62 \ # This source address
--jump REJECT # Use the target Reject
or if you just want to change the IP;
iptables \
--table filter \ # Use the filter table
--replace INPUT \ # Replace from the INPUT chain
--source 59.45.175.62 \ # This source address
--jump REJECT # Use the target Reject
Note that you don't have to specify the filter table, since it is the
default table, it will automatically be used if no table is specified.
Scenario 2: Adding a rule to a specific position in a chain
To do this, we will first print out an ordered list of the current rules,
this can be done by;
iptables --list --line-numbers
which will give an output similar to;
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 DROP all -- 59.45.175.0/24 anywhere
2 DROP all -- 221.194.47.0/24 anywhere
3 DROP all -- 91.197.232.104/29 anywhere
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
1 DROP all -- anywhere 31.13.78.0/24
In this scenario assume you want to block the entire IP Block 59.45.175.0/24,
all except one address from it, 59.45.175.10. We have used the same process as
earlier already to block the IP block. Now we want to whitelist the exception
address, Since iptables evaluates rules in the chains one-by-one, you simply
need to add a rule to “accept” traffic from this IP above the rule blocking
59.45.175.0/24. So in this case you just need to run the command;
iptables \
--table filter \
--insert INPUT 1 \
--source 59.45.175.10 \
--jump ACCEPT
If you list again now, you will see;
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- 59.45.175.10 0.0.0.0/0
2 DROP all -- 59.45.175.0/24 0.0.0.0/0
3 DROP all -- 221.192.0.0/20 0.0.0.0/0
4 DROP all -- 91.197.232.104/29 0.0.0.0/0
You have now inserted a rule into a chain.
Scenario 3: Modifying Default Policy of a chain
We have discussed default policies in the introduction, it is simply what is
done to a packet if none of the rules in a chain match, the default chains have
an accept policy by default. Perhaps you’re configuring iptables for your home
computer, and you don’t want any local programs to receive inbound connections. To change this use;
iptables \
--policy INPUT DROPScenario 4: Blocking access to ports
To block access to SSH port for a range;
iptables \
--append INPUT \
--protocol tcp \ # Specify TCP protocol
--match tcp \ # Load the TCP module
--dport 22 \ # Destination port
--source 59.45.175.0/24 \
--jump DROP
To block access to multiple ports, i.e. SSH and VNC access for a range;
iptables \
--append INPUT \
--protocol tcp \
--match multiport \ # Load multiport module
--dports 22,5901 \
--source 59.45.175.0/24 \
--jump DROP
To block access to all ports except the ones specified, i.e. all except HTTP,
HTTPS and SSH (ideal for web server);
iptables \
--append INPUT \
--protocol tcp \
--match multiport \
! --dports 22,80,443 \
--jump DROP
To block Ping/ICMP requests;
iptables \
--append INPUT \
--jump REJECT \
--protocol icmp \
--icmp-type echo-request
Block with no error message;
iptables \
--append INPUT \
--protocol icmp \
--jump DROP \
--icmp-type echo-requestANDiptables \
--append OUTPUT \
--protocol icmp \
--jump DROP \
--icmp-type echo-replyScenario 4: Using Connection Tracking
Block incoming traffic but still access services
If you block IP on INPUT chain, you will find that you cannot access any
services on that IP too, While that IP cannot access your host, you should
still be able to access that IP. The reason why this is not working is
because while your requests are reaching that server, iptables is dropping
the responses coming to your hosts.
We can still achieve this, because iptables is a stateful firewall and has a
connection tracking module for this purpose. The state tracked by this
module can be either one of;
NEW: This state represents the very first packet of a connection.
ESTABLISHED: This state is used for packets that are part of an existing
connection. For a connection to be in this state, it should have received a
reply from the other host.
RELATED: This state is used for connections that are related to another
ESTABLISHED connection. An example of this is a FTP data connection —
they’re “related” to the already “established” control
connection.
INVALID: This state means the packet doesn’t have a proper state. This
may be due to several reasons, such as the system running out of memory or
due to some types of ICMP traffic.
UNTRACKED: Any packets exempted from connection tracking in the raw
table with the NOTRACK target end up in this state.
DNAT: This is a virtual state used to represent packets whose
destination address was changed by rules in the nat table.
SNAT: Like DNAT, this state represents packets whose source address was
changed.
Therefore we can use the RELATED and ESTABLISHED states for connections that
are initiated by us. To do this we can use the following command;
iptables \
--append INPUT
--match conntrack
--ctstate RELATED,ESTABLISHED \
--jump ACCEPT # Accept packets in above connection statesScenario 5: Security Rules in iptables
To block Christmas tree packets aka kamikaze packets, which have all headers
set so we need to simply drop packets with all headers. We can use command;
iptables \
--append INPUT \
--protocol tcp \
--match tcp \
--tcp-flags ALL FIN,PSH,URG \
--jump DROP
To block common invalid packets such as packets with SYN and FIN set, we can
simply look for packets with both set. To do this use;
iptables \
--append INPUT \
--protocol tcp \
--match tcp \
--tcp-flags SYN,FIN SYN,FIN \
--jump DROP
And also packets that are a ‘new connection’ that doesn't begin with a SYN. To
do this you simply need to check the FIN, RST, ACK and SYN flags; however only
SYN should be set. Then, you can negate this condition. Finally, you can use
conntrack to verify if the connection is new. Thus, the rule is:
iptables \
--append INPUT \
--protocol tcp \
--match conntrack \
--ctstate NEW
--match tcp ! \
--tcp-flags FIN,SYN,RST,ACK SYN \
--jump DROPScenario 6: Rate Limiting using iptables
This is done by using the limit module, it has two main parameters; ‘limit-burst’
acts as a buffer and is the buffer size, if this buffer size is exceeded all
packets are dropped. The rate you can refill this buffer is the ‘limit’.
This can be done with 2 commands, first you must change the default policy
of the INPUT chain to drop and then use; (i.e. rate limiting ICMP packets)
iptables \
--append INPUT \
--protocol icmp \
--match limit \
--limit 1/sec \
--limit-burst 1 \
--jump ACCEPT
You can also perform rate limiting dynamically for specific IP addresses,
however this can be only performed by the recent module. It takes two commands
and is done as follows;(i.e. Rate Limiting SSH per IP)
iptables \
--append INPUT \
--protocol tcp \
--match tcp \
--dport 22 \
--match conntrack \
--ctstate NEW \
--match recent \
--set \
--name SSHLIMIT
--rsourceiptables \
--append INPUT \
--protocol tcp \
--match tcp \
--dport 22 \
--match conntrack \
--ctstate NEW \
--match recent \
--set \
--name SSHLIMIT \
--update \
--seconds 180 \
--hitcount 5 \
--name SSH \
--rsource \
--jump DROPScenario 7: Logging packets using iptables
This is fairly simple and done using;
iptables \
--append INPUT \
--protocol tcp \
--match tcp \
--tcp-flags FIN,SYN FIN,SYN \
--jump LOG
--log-prefix=iptables:
The ‘ — log-prefix=’ is optional and is added so you can easily search the log
later. The log is usually stored at /var/log/syslog or /var/log/messages.
Scenario 8: Port redirection In same machine
To redirect a port in your machine to another port, i.e. HTTP port to 8080
iptables \
--table nat \
--append PREROUTING \
--protocol tcp \
— dport 80 \
--jump REDIRECT \
--to 8080Scenario 9: Turning iptables into a proxy!
Watch this amazing video by the great Hussein Nasser, he will explain it better
than I ever could. Below are the iptables rules;
iptables \
--in-interface wlan0 \
--append PREROUTING \
--table nat \
--protocol tcp \
--destination 192.168.254.47 \
--dport 81 \
--jump DNAT \
--to-destination 192.168.254.10:8080iptables \
--append POSTROUTING \
--table nat \
--protocol tcp \
--destination 192.168.254.10 \
--dport 8080 \
--jump SNAT \
--to-source 192.168.254.47iptables \
--table nat \
--append POSTROUTING \
--protocol tcp \
--dport 81 \
--jump MASQUERADEBonus Scenarios:
iptables as a load-balancer? — also by Hussein check it out here!
The owner module for rules only for internal users
Conclusion
As you can see the uses of iptables are limitless. There are many frontend
firewalls now that use iptables so chances are you wont have to directly
interact with iptables, and with nftables the chances are less. It is still
important as an SRE, developer or security professional to understand how
iptables work.
This article is a compilation of all the knowledge I gathered from many
sources while on my journey to understand iptables, I hope to make that
journey easier for someone else thanks to this article.
For an even more comprehensive guide check out — Linux iptables Pocket
Reference [Book] (oreilly.com)
A great many thanks to all my sources mentioned below, all rights reserved to
owners.
Sources: Dr. Murphy, Supriyo Biswas, Phoenix Nap, XPSTECH, David Adams
Thanks for reading!
Linux iptables Pocket Ref
Linux iptables Pocket Reference
by Gregor N. Purdy
Released August 2004
Publisher(s): O'Reilly Media, Inc.
ISBN: 9780596005696
Read it now on the O’Reilly learning platform with a 10-day free trial.
O’Reilly members get unlimited access to books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.
Buy on AmazonBuy on ebooks.comStart your free trial
Book description
Firewalls, Network Address Translation (NAT), network logging and accounting are all provided by Linux's Netfilter system, also known by the name of the command used to administer it, iptables. The iptables interface is the most sophisticated ever offered onLinux and makes Linux an extremely flexible system for any kind of network filtering you might do. Large sets of filtering rules can be grouped in ways that makes it easy to test them and turn them on and off.Do you watch for all types of ICMP traffic--some of them quite dangerous? Can you take advantage of stateful filtering to simplify the management of TCP connections? Would you like to track how much traffic of various types you get?This pocket reference will help you at those critical moments when someone asks you to open or close a port in a hurry, either to enable some important traffic or to block an attack. The book will keep the subtle syntax straight and help you remember all the values you have to enter in order to be as secure as possible. The book has an introductory section that describes applications,followed by a reference/encyclopaedic section with all the matches and targets arranged alphabetically.