Iptables – Skipping rules in iptables

iptablesrules

Imagine that I have 3 rules in iptables:

  1. Check if IP is whitelisted in ipset, then accept it.
  2. Check if user tries connect to port 22, then drop it.
  3. Check if user tries connect to port 80, then accept it.

This is example (not real) of rules:

iptables -A INPUT -m set --match-set whitelist src -j ACCEPT

iptables -A INPUT -p tcp --dport 22 -j DROP

iptables -A INPUT -p tcp --dport 80 -j ACCEPT

But I would like to do that if user is whitelisted (1st rule), then don't accept it, but skip/redirect it to 3rd rule (skip 2nd rule), like on this picture (I know that if packet is ACCEPTED then it is done, this is only example, I don't know how to make that jump):

Image

So I would like to ask you, how can I set this "skipping" in chain.

Subquestion: If it is possible, then is it possible to redirect it to another chain to specific rule too?

Update: Real scenario

iptables -A INPUT -m set --match-set whitelist src -j ACCEPT

iptables -A INPUT -m geoip --src-cc DE -j DROP

... other rules ...

As you can see, I whitelisted only Germany, if German's IP pass throught second rule, then I will check it for other rules, but I use whitelisted IPs too.

So if some IP is whitelisted (mostly not German) then I don't want to check if it is German IP (because it would fail) instead that IP should jump into other rules (3rd row) and skip country checking.

What about go to function?

Best Answer

A custom chain can be used to organize things more easily. There's a an other "terminal" target more useful once in a custom chain: RETURN to immediately come back and execute the rule after the calling rule. RETURN in the base chain just applies the default policy, so is not so much used.

The asked example becomes:

iptables -N whitelist-check
iptables -A whitelist-check -m set --match-set whitelist src -j RETURN
iptables -A whitelist-check -p tcp --dport 22 -j DROP
iptables -A INPUT -j whitelist-check
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

Sometimes inverting logic and grouping can work too. For this simple case an equivalent method would have simply been:

iptables -A INPUT -p tcp -m set ! --match-set whitelist src --dport 22 -j DROP
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

For the updated scenario: drop everything which is not whitelisted nor from DE (nor ...). For additional exceptions, just add more rules ending with -j RETURN before the -j DROP

Update 2: changed the logic with DE since OP changed it too... if, as per OP's change, traffic is dropped for Germany, here, traffic continues for non-Germany.

iptables -N filterchain
iptables -A filterchain -m set --match-set whitelist src -j RETURN
iptables -A filterchain -m geoip ! --src-cc DE -j RETURN
...
iptables -A filterchain -j DROP

iptables -A INPUT -j filterchain
... other rules ...