Simplified the Linux netfilter firewall "iptables" can operate in in two modes.
- Mode one is as a simple packet filter.
That means that you create a bunch of rules in a specific order and every packet is checked against the full rule base, one rule after another until it triggers a rule that provides a dispositive match and the fate of that individual packet is determined.
Depending on your configuration that might result in packets needing to traverse dozens or more rules until they're allowed or rejected.
Once the packet reaches the last rule in your chain, and their fate still remains undecided, the policy of the chain is applied. (In most firewall configuration that scenario never happens because it is customary to set an explicit firewall rule accepting/rejecting/dropping all traffic that wasn't matched by the earlier rules, rather than relying on the policy.)
- Mode two is a stateful firewall.
In a stateful firewall connections are tracked. That requires that some additional kernel modules are loaded and then the Linux kernel will (in memory) keep a connection state lookup table.
The assumption is that for most systems the majority of traffic, most packets, will belong to an existing connection.
Rather than checking the complete firewall rule base, in a stateful firewall only one check is needed for most packets: if the packet belongs to an existing connection, then it is allowed.
Done.
No more checks needed.
In a stateful firewall thus the first rule is something like
# iptables-save
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
...
Only packets that don't belong to an existing connection require further evaluation. The subsequent rules then determine if the packet belongs to a connection that should be allowed or not.
The first rule:
iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT
does not refer to the connection state and is the syntax that is valid for both a simple packet filter and a stateful firewall. It completely ignores any potential connection state information and simply allows any and all packets to TCP ports 22, 80 and 443.
The second rule:
iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
is only valid for a stateful firewall where connection tracking is enabled.
In a stateful firewall, both rules usually have the same end-result, a packet to either port 22, 80 or 443 is accepted and the firewall will allow connections to be established.
But the second rule is more precise, only packets with specific connection states are allowed and packets with for example a state "INVALID" or something else, will still be rejected.
States for --ctstate:
INVALID The packet is associated with no known connection.
NEW The packet has started a new connection or otherwise associated
with a connection which has not seen packets in both directions.
ESTABLISHED The packet is associated with a connection which has
seen packets in both directions.
RELATED The packet is starting a new connection, but is associated
with an existing connection, such as an FTP data transfer or an ICMP
error.
UNTRACKED
The packet is not tracked at all, which happens if you
explicitly untrack it by using -j CT --notrack in the raw table.
SNAT
A virtual state, matching if the original source address
differs from the reply destination.
DNAT
A virtual state, matching if the original destination differs
from the reply source.