0

Using recent module in iptables, how can I both check if the src ip address exists in a list and if it does, add it to another list?

I'm trying to implement port-knocking using iptables together with this module (recent).

So, I'd like to detect if a TCP packets arrive in a specific order by shifting the src ip address from one list to another, thus progressing it towards the final list, which would allow the src ip access to the machine.

My question is, basically, how to add src ip to a next step (list), when a packet has the correct destination port AND is in the correct current step (list), all in one rule. Something like this:

1:

# we'd like to accept the already authenticated packets quickly, hence the first rule
iptables -A KNOCKING -m recent --rcheck --seconds 60 --reap --name knockfinal -j ACCEPT

2:

# src ip is not authenticated, let's verify the first knock
# if the first port knock was correct (port 1111), add the src ip to the 'knock1' list
iptables -A KNOCKING -p tcp --dport 1111 -m recent --name knock1 --set -j DROP

3:

# now, here is the issue...
# how do we both check if the src ip is already in the 'knock1' list
# plus the second port knock was correct (port 2222), and add the src ip to 'knock2' list
# ideally, we would write something like this
iptables -A KNOCKING -m recent --rcheck --seconds 10 --reap --name knock1 -p tcp --dport 2222 -m recent --name knock2 --set -j DROP

I've read several different approaches to setting up port-knocking using iptables, but this one seemed the most trivial one for me, so I'd really like to either confirm or deny it's possible to do it using this approach.

1 Answer 1

1

As it turned out, that line I posted above is exactly how it should be written :) I guess I was too pessimistic about expecting iptables to be able to process such a "complex" rule.

Here is my config for the easy port knocking configuration:

# set default policy for INPUT chain to DROP
iptables -P INPUT DROP

# accept all local traffic
iptables -A INPUT -i lo -j ACCEPT

# accept all the already-established connections
iptables -A INPUT -p tcp -m state --state RELATED,ESTABLISHED -m multiport --sports 25,80,443,465,587 -j ACCEPT

# add more of your own rules here...

# at the end, redirect all the packets into the KNOCKING chain
# this makes it easy to quickly enable/disable KNOCKING chain, if need be
iptables -A INPUT -j KNOCKING

# if the src ip is already authenticated, accept it
iptables -A KNOCKING -m recent --rcheck --seconds 60 --reap --name knockfinal -j ACCEPT

# if the packet is not authenticated and the first port knock is correct
# add the src ip into the 'knock1' list
iptables -A KNOCKING -p tcp -m tcp --dport 1111 -m recent --set --name knock1 -j DROP

# if the src ip is already in the 'knock1' list (with the expiry time of 10 seconds)
# and the 2nd port knock is correct, add the src ip to the 'knock2' list
iptables -A KNOCKING -p tcp -m recent --rcheck --seconds 10 --reap --name knock1 -m tcp --dport 2222 -m recent --set --name knock2 -j DROP

# if the src ip is already in the 'knock2' list (with the expiry time of 10 seconds)
# and the 3rd port knock is correct, add the src ip to the 'knock3' list
iptables -A KNOCKING -p tcp -m recent --rcheck --seconds 10 --reap --name knock2 -m tcp --dport 3333 -m recent --set --name knock3 -j DROP

# if the src ip is already in the 'knock3' list (with the expiry time of 10 seconds)
# and the 4th port knock is correct, add the src ip to the 'knockfinal' list
iptables -A KNOCKING -p tcp -m recent --rcheck --seconds 10 --reap --name knock3 -m tcp --dport 4444 -m recent --set --name knockfinal -j DROP

# otherwise, we don't do anything and the default INPUT policy will drop the packet

I guess this is the shortest port knocking ruleset for iptables I've seen so far...

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .