Posted by uroboros on Fri 7 Oct 2005 at 13:52
There are several methods of implementing port knocking (the sophisticated project Knockd for instance). Here we'll demonstrate a very simple means of achieving the port-knocking effect using nothing more than netfilter, or iptables, rules.
You will need the iptables "recent" module compiled in you kernel or as a module - we've previously introduced using this to rate-limit incoming connections with the recent module.
There are the magical rules (many thanks belongs to Rusty Russel for this):
# Netfilter/IPtables - example of multiple-port knocking # Note: Knock ports 100,200,300,400 to open SSH port for 5 seconds. # Nice thing to knock TCP with is `telnet' program: # $> alias k='telnet ip_address_or_hostname' # $> k 100 ; k 200 ; k 300 ; k 400 ; ssh ip_address_or_hostname # Then press Ctrl-C 4 times. That's all. Enjoy. HOST_IP="12.34.56.78" /sbin/iptables -N INTO-PHASE2 /sbin/iptables -A INTO-PHASE2 -m recent --name PHASE1 --remove /sbin/iptables -A INTO-PHASE2 -m recent --name PHASE2 --set /sbin/iptables -A INTO-PHASE2 -j LOG --log-prefix "INTO PHASE2: " /sbin/iptables -N INTO-PHASE3 /sbin/iptables -A INTO-PHASE3 -m recent --name PHASE2 --remove /sbin/iptables -A INTO-PHASE3 -m recent --name PHASE3 --set /sbin/iptables -A INTO-PHASE3 -j LOG --log-prefix "INTO PHASE3: " /sbin/iptables -N INTO-PHASE4 /sbin/iptables -A INTO-PHASE4 -m recent --name PHASE3 --remove /sbin/iptables -A INTO-PHASE4 -m recent --name PHASE4 --set /sbin/iptables -A INTO-PHASE4 -j LOG --log-prefix "INTO PHASE4: " /sbin/iptables -A INPUT -m recent --update --name PHASE1 /sbin/iptables -A INPUT -p tcp --dport 100 -m recent --set --name PHASE1 /sbin/iptables -A INPUT -p tcp --dport 200 -m recent --rcheck --name PHASE1 -j INTO-PHASE2 /sbin/iptables -A INPUT -p tcp --dport 300 -m recent --rcheck --name PHASE2 -j INTO-PHASE3 /sbin/iptables -A INPUT -p tcp --dport 400 -m recent --rcheck --name PHASE3 -j INTO-PHASE4 /sbin/iptables -A INPUT -p tcp -s $HOST_IP --dport 22 -m recent --rcheck --seconds 5 --name PHASE4 -j ACCEPT
The script can be also downloaded from here. [Local mirror]
These rules will open port 22 for 5 seconds after you knock ports 100, 200, 300 and 400 with TCP packets.
It is not perfect I know. But can be used nearly everywhere. If you have some other ideas of how to implement the multiple-port knocking with Netfilter/IPtables, please contribute in the discussions below.
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
To `jbyers': Script pretends that default politic for the INPUT is DROP:
... /sbin/iptables -P INPUT DROP ... source /path/to/the/script ...
Thus there is no need for adding any special rule in the INPUT chain in my script. Or did I miss something about your solution?
To all:
The script works as follows: If first port is touched then we jump into PHASE1. If we are in PHASE1 we expect PHASE2 which is the second port touching. If the second port is touched then we remove from PHASE1 and jump to PHASE2 and expect PHASE3... and so on. If we reach the last phase we allow what we want for what time we want from anywere we want. I can even be generalized this way. Nice, isn't it?
More tighten rules could also be as such:
#!/bin/bash NETWORK=12.34.56.78/32 # ... cleaning up, setting up politics, etc. # ---GENERATED W/ IPTKNOCK--- /sbin/iptables -A INPUT -i eth0 -p tcp -s ${NETWORK} --dport 100 -m recent --name 1-1-1 --set /sbin/iptables -N 1-1-IN-2 /sbin/iptables -A 1-1-IN-2 -m recent --name 1-1-1 --remove /sbin/iptables -A 1-1-IN-2 -m recent --name 1-1-2 --set /sbin/iptables -A 1-1-IN-2 -j LOG --log-prefix NAME-1-1-IN-2 /sbin/iptables -A INPUT -i eth0 -p tcp -s ${NETWORK} --dport 100 -m recent --rcheck --name 1-1-1 -j 1-1-IN-2 /sbin/iptables -N 1-1-IN-3 /sbin/iptables -A 1-1-IN-3 -m recent --name 1-1-2 --remove /sbin/iptables -A 1-1-IN-3 -m recent --name 1-1-3 --set /sbin/iptables -A 1-1-IN-3 -j LOG --log-prefix NAME-1-1-IN-3 /sbin/iptables -A INPUT -i eth0 -p tcp -s ${NETWORK} --dport 200 -m recent --rcheck --name 1-1-2 -j 1-1-IN-3 /sbin/iptables -N 1-1-IN-4 /sbin/iptables -A 1-1-IN-4 -m recent --name 1-1-3 --remove /sbin/iptables -A 1-1-IN-4 -m recent --name 1-1-4 --set /sbin/iptables -A 1-1-IN-4 -j LOG --log-prefix NAME-1-1-IN-4 /sbin/iptables -A INPUT -i eth0 -p tcp -s ${NETWORK} --dport 300 -m recent --rcheck --name 1-1-3 -j 1-1-IN-4 /sbin/iptables -N 1-1-IN-5 /sbin/iptables -A 1-1-IN-5 -m recent --name 1-1-4 --remove /sbin/iptables -A 1-1-IN-5 -m recent --name 1-1-5 --set /sbin/iptables -A 1-1-IN-5 -j LOG --log-prefix NAME-1-1-IN-5 /sbin/iptables -A INPUT -i eth0 -p tcp -s ${NETWORK} --dport 400 -m recent --rcheck --name 1-1-4 -j 1-1-IN-5 /sbin/iptables -A INPUT -i eth0 -p tcp -s ${NETWORK} --dport 22 -m recent --seconds 5 --rcheck --name 1-1-5 -j ACCEPT # ---EOF GENERATED PART--- # ... etc.
Rules I used for generation of the pointed part of the above script were these:
NAME
if tcp/100,200,300,400 from \\${NETWORK} in INPUT on eth0 then
in INPUT on eth0 open tcp/22 for 5
fi
You can easily change the IPTKnock script into generator with changing the beginning of it like this:
function ec () { echo '/sbin/iptables ' "$@" ; }
IPT=ec
### IPT=/sbin/iptables
Then source stored generated firewall rules in your firewalling script on a proper place.
Examples on how to use the horrible BASH script (I know, I am really very "lame" BASH coder, oh really, I know it so much) can be found in the same directory.
If somebody founds a bug, please, send it to me. I will repair the script for future use. Also if somebody will create much efficient "meta-language" to define the rules or even anything else concerning this topic, send it to me too. Send e-mails on iptknock@ligaturaPROTECTED.org -- remove the PROTECTED chain from the e-mail address. All ideas or thoughts are heartfuly welcome!
I hope it helps.
--
If you're smart enough to ask this question, you're smart enough to RTFM and find out yourself.
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]