I don't understand some basic concepts of conntrack module.

First of all, I'm sure it's enabled in my system (Ubuntu 18.04), modinfo shows info about nf_conntrack and /proc/modules file tells nf_conntrack is "live".

Second, I have the following test setup:

Machine A ( <-----> Router Machine ( & <----> Machine B (

On Router Machine I have the following iptables rule:
iptables -t filter -A FORWARD -m set --match-set BlackListPort dst -j DROP

BlackListPort is an ipset table.
Now I establish an SSH connection from Machine A (1.2) to Machine B (2.2). After I confirm it works, I add port 22 (SSH default) to BlackListPort table.

SSH connection freezes/hangs until I remove port 22 from that ipset table.

Now the question: Since conntrack is present in my system, why SSH block is successful? SSH connection was established before port 22 was added to ipset so conntrack should just skip all packets, allowing SSH to work.

  • 1
    have you got a rule -m state --state ESTABLISHED -j ACCEPT positioned sequentially before your rule ? – LL3 Jun 3 at 14:35
  • @LL3 No, I don't have such rules in my iptables – Groosha Jun 3 at 14:58

SSH connection was established before port 22 was added to ipset so conntrack should just skip all packets, allowing SSH to work.

This is not correct.

All packets will be processed through the filter rules, whether they belong to tracked connections or not.

It is a very common optimization of iptables rules to put something like this near the beginning of the relevant rule chain (FORWARD in your example):

iptables -t filter -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

On older distributions, you might see this version instead:

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

(I understand the conntrack match is now preferred over the state match. I think some kernel versions even nag at you about it.)

This will allow packets belonging to existing connections through, if a connection tracking information exists for them. But the point is, you can control where exactly you put that rule, or whether you use it at all. So you can make your firewall rules care about connection states as much - or as little - as you want.

  • My iptables are empty (did a reboot, nothing is restored afterwards). I did 2 tests: 1) executed iptables -t filter -A FORWARD -p tcp --dport 22 -j DROP and 2) executed iptables -t filter -A FORWARD -p tcp --dport 22 -m conntrack --ctstate NEW -j DROP (tried with NEW,ESTABLISHED,RELATED as well). In all cases my existing SSH connection was frozen until I removed that rules. – Groosha Jun 3 at 14:53
  • 2
    The order of the rules matters. If you want the existing connections to keep working, you must have the rule that ACCEPTs packets that are part of ESTABLISHED connections before the rule that targets all packets going to destination port 22 and DROPs them. – telcoM Jun 3 at 15:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.