Setup port knocking with iptables on single port?

I've been looking into using port knocking as a way to conceal/protect SSHD. I'm aware of knockd and other implementations, but I want something portable and simple. So I've decided iptables with the recent module is good enough.

I've already disabled password based login and require a public/private key. I just want it to appear like SSHD is not on the server, even to a port scanner.

I've seen many iptables rule examples, and I'm not quite clear how they're supposed to work.

What I want is to knock on a single obscure port to open port 22. At the same time I want to disable port knocking for a while if ports around it are accessed. So if my knocking port was 123, knocking on this port would open port 22 for 5 seconds for just the knocker. But if port 122 or 124 was knocked on it would disable port knocking for the knocker for 15 minutes (so even if they knocked on 123 nothing would happen in that time frame).

What iptables rules would achieve this?

Edit: I should add that I'm using CentOS 5.5. iptable modules can be used.


Solution 1:

All these rules have iptables -A INPUT in front of them.

# if port 122 or 124 is touched add to block list
-m state --state NEW -m tcp -p tcp -–dport 122 -m recent --set --name blocked
-m state --state NEW -m tcp -p tcp -–dport 124 -m recent --set --name blocked

# if you are on the block list you cannot touch 123 for 15min
-m state --state NEW -m tcp -p tcp --dport 123 -m recent --rcheck --name blocked --seconds 900 -j DROP

# if port 123 is touched add to the knocked list
-m state --state NEW -m tcp -p tcp --dport 123 -m recent --set --name knocked

# if you are on the knock list you can initiate an ssh session for 5 seconds
-m state --state NEW -m tcp -p tcp --dport 22 -m recent --rcheck --name knocked --seconds 5 -j ACCEPT

The one caveat is that I don't know if ipt_recent can track for 15 minutes.

Edit: try to make comments better and add missing "recent."