In this tutorial, let’s talk about packet filters using iptables states. We’ll mainly discuss the status of each connection, i.e., NEW, ESTABLISHED, and RELATED. We’ll look at what they mean and why we need them.
We should note that iptables states allow us to maintain the state information about a connection in the memory tables. This information is used for connection tracking. Stateful firewalls are those that do connection tracking.
This state matches a packet creating a new connection or is part of a two-way connection that has not seen packets in both directions. We need to accept it if we want to allow a new connection to a service.
For example, let’s look at this rule:
$ sudo iptables -A INPUT -p tcp -dport 22 -s 192.168.54.2 -m state --state NEW -j ACCEPT
This rule allows our computer to accept the incoming ssh connection from this IP address only.
This state indicates that the packet’s linked to a connection that has seen packets in both directions. We need to accept this state if we want to maintain a connection between two hosts.
To understand this, let’s run:
$ sudo iptables -A OUTPUT -p tcp -sport 22 -d 192.168.5.2 -m state --state ESTABLISHED -j ACCEPT
In this example, we’ve added ESTABLISHED which allows a bidirectional flow of packets between the two computers connected through ssh. This allows our computer to receive instructions and send responses back to the computer with the 192.168.54.2 address.
A RELATED state means that the packet’s starting a new connection, but is associated with an existing connection.
Let’s look at the ftp protocol to illustrate this state. Not only does ftp use port 21, but it also uses another TCP connection in some instances. In such a circumstance, ftp uses port 21 for connection control (establishing a connection) and port 20 for the data connection (data transfer).
For example, let’s say we’ve got two hosts: server and client. To allow ftp connection from the client, we run these commands on the server:
$ sudo iptables -A input -p tcp -sport 21 -m state --state ESTABLISHED -j ACCEPT $ sudo iptables -A OUTPUT -p TCP -dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
These commands allow the bidirectional flow of packets from the two hosts if a connection already exists and it also accepts a new connection from a client. Next, we need to run the following commands on the client and server respectively. The commands allow ftp connections on port 20:
$ sudo iptables -A INPUT -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT $ sudo iptables OUTPUT -p TCP --dport 20 -m state --state ESTABLISHED -j ACCEPT
Now that we’ve looked at these three states, we should bear in mind that the main disadvantage of stateful firewalls is that they require a lot of memory to maintain the state table entries for each connection. Also, stateful firewalls allow more advanced packet processing because they look at traffic on a packet-by-packet basis alone which makes it more secure compared to stateless packet filtering.
In this article, we’ve discussed stateful packet filtering by looking at three states. For connections to be complete, packet flow must be bidirectional unless we specify it to be unidirectional. We can achieve this through these states which allow us to route packets either way.