This chapter will deal with the state machine and explain it in
detail. After reading through it, you should have a complete understanding of
how the State machine works. We will also go through a large set of examples on
how states are dealt with within the state machine itself. These should clarify
everything in practice.
The state machine is a special part within iptables that should really not
be called the state machine at all, since it is really a connection tracking
machine. However, most people recognize it under the first name. Throughout
this chapter I will use these names more or less as if they were synonymous.
This should not be overly confusing. Connection tracking is done to let the
Netfilter framework know the state of a specific connection. Firewalls that
implement this are generally called stateful firewalls. A stateful firewall is
generally much more secure than non-stateful firewalls since it allows us to
write much tighter rule-sets.
Within iptables, packets can be related to tracked connections
in four different so called states. These are known as
NEW, ESTABLISHED,
RELATED and INVALID. We will discuss
each of these in more depth later. With the --state
match we can easily control who or what is allowed to initiate new
sessions.
All of the connection tracking is done by special framework within the kernel
called conntrack. conntrack may be loaded either as a module, or as an
internal part of the kernel itself. Most of the time, we need and want more
specific connection tracking than the default conntrack engine can maintain.
Because of this, there are also more specific parts of conntrack that handles
the TCP, UDP or
ICMP protocols among others. These modules grab
specific, unique, information from the packets, so that they may keep track of
each stream of data. The information that conntrack gathers is then used to
tell conntrack in which state the stream is currently in. For example,
UDP streams are, generally, uniquely identified by
their destination IP address, source IP
address, destination port and
source port.
In previous kernels, we had the possibility to turn on and off
defragmentation. However, since iptables and Netfilter were introduced
and connection tracking in particular, this option was gotten rid of. The
reason for this is that connection tracking can not work properly without
defragmenting packets, and hence defragmenting has been incorporated into
conntrack and is carried out automatically. It can not be turned off,
except by turning off connection tracking. Defragmentation is always carried
out if connection tracking is turned on.
All connection tracking is handled in the PREROUTING
chain, except locally generated packets which are handled in the
OUTPUT chain. What this means is that iptables will
do all recalculation of states and so on within the
PREROUTING chain. If we send the initial packet in a
stream, the state gets set to NEW within the
OUTPUT chain, and when we receive a return packet,
the state gets changed in the PREROUTING chain to
ESTABLISHED, and so on. If the first packet is not
originated by ourself, the NEW state is set within the
PREROUTING chain of course. So, all state changes and
calculations are done within the PREROUTING and
OUTPUT chains of the nat table.