Stateful Filtering with Netfilter

When implementing security policies with a packet filter you will usually have to specify rules for each and every packet that you wish to handle. This will result in a myriad of rules that are hard to maintain. Still, you might be able to prolong choas by distributing rule definitions among several files and cascading chains of similar rules. Though, there is an easier way.

The netfilter code supports stateful filtering which assigns packets to states. That’s a very natural approach because protocols are formally defined by finite state machines. Although this vastly reduces the number of rules, you need to be aware that you trust the netfilter code to correctly categorize packets into states. It makes your life easier but abstracts from what is really happening.

netfilter distinguishes between three generic states:

NOTE: The following code snipplets assume that you deny everything that is not explicitly allowed.

An easy approach is to accept all packets that netfilter was able to assign to a connection that was successfully initiated, i.e. the connection was allowed by another rule:

iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

The following rule authorized a connection to be initiated from hosts in the local network to web servers on the public interface:

iptables -t filter -A OUTPUT
-o ppp0 -s 192.168.0.0/24
-p tcp -dport 80
-m state --state NEW -j ACCEPT
Feedback is always welcome! If you'd like to get in touch with me concerning the contents of this article, please use Twitter.