ipt_pkd is a port knock detector with spa (single packet authorization) which when used in conjuction with ipt_recent gives you a decent port knocking system thats based in iptables. The knock packet is a sha256 of a timestamp, some random bytes, a small header, and a shared key, sent via udp. The timestamp and the bytes are passed in the packet so the server can do the sha256 and compare the results. If its a match then the pkd module returns true, otherwise false. *NOTE* The format of the packet changed in 1.0, it is not compatible with earlier versions. The source and destination ports are used in the hash to eliminate a replay attack avenue. It has limited proc support. It opens an entry /proc/net/ipt_pkd. Reading this file (with cat, less, ...) gives information about packets outside of the time window and how many replayed packets it thinks it has seen, and the ports + last timestamps of replayed packets that it has in it's packet queue. ipt_pkd has three options: --key <key> Sets the shared key, it's up to 40 bytes long and can be entered in as hex by starting it with 0x. The remainder of the key is zero filled. --window <time> Time in seconds +- that the packet can be different from the computer. Default is 10 which gives a 20 second window for the packet to arrive. If your clocks are close in time you can reduce that, say if they are synced to an ntp server. *NOTE* You can also set the window to 0 and skip the time check, nice for virtual machines whose clocks might be messed up. Be aware that turning off the time check means packets can replayed (at the moment) at will. --tag <tag> Sets the tag for this knock key. Use different tags for different keys on the same machine. This speeds up processing as the knock doesn't have to be rehashed for every key check. Default tag is PKD0, the tag is up to 4 bytes and can be entered as hex by starting it with 0x. The remainder of the tag is zero filled. Some examples: Protecting ssh (port 22). iptables -A INPUT -p udp -m pkd --key test --tag SSHK -m recent --set --name PKD iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --rcheck --name PKD --seconds 60 --hitcount 1 -j ACCEPT iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j REJECT --reject-with tcp-reset These rules will drop any new ssh connection attempts unless a valid knock packet was seen for the incoming client ip in the last 60 seconds. You can use hitcount to control how many times you have to knock, though in the above rules you'd also need to change the --set to --update otherwise the hitcount wouldn't go over 1. You could also use it to control how long a session could be by adding a drop on all packets to --dport 22 and setting --seconds to be how long you wanted a session to last. iptables -A INPUT -p udp -m pkd --key 0xAA0693aB --tag 0x00010203 -m recent --set --name PKD iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --rcheck --name PKD --seconds 60 --hitcount 1 -j ACCEPT iptables -A INPUT -p tcp --dport 22 -m state --state ESTABLISHED,RELATED -m recent --name PKD --rcheck --seconds 600 -j ACCEPT iptables -A INPUT -p tcp --dport 22 -j REJECT --reject-with tcp-reset libipt_pkd.c -- iptables user space portion, becomes libipt_pkd.so pkd.c -- iptables kernel portion, becomes ipt_pkd.ko knock.c -- client knock program becomes knock knock.py -- client knock in python stays knock.py ipt_pkd.h -- common header knock (c version) gets the host (and optional tag) from the command line and then asks for a key knock_original.py (python version) reads its information out of an ini file (default ~/.ipt_pkd.ini) and example ini file is included in the distribution. knock.py has a compatibility mode for older knock packets, just add old=1 to an entry you want to use the previous packet style. knock.py (python module version) module version of knock.py, includes a main so you can use it like the original or import it into your own script knock.exe (c# version), gui version, stores the keys encrypted in a per-user config file, it asks you for a password and shows you the knock key entries that are available using that password. To build you need your kernel headers for the kernel module, iptables-dev for the iptables user space portion, and libssl-dev for knock as it uses the sha256 library from openssl. Then just make; make install. For the make install you need to run as root. The Makefile tries to make a best guess as to where to put the userspace iptables part (libipt_pkd.so), typically its found in /lib/iptables or some libexec directory like /usr/local/libexec/xtables/, you might need to move it if it puts it in the wrong directory. The kernel module uses the kernel installer so who knows where it puts it. Also sometimes you have to manually run depmod -a afterward, if you see an error like, iptables: No chain/target/match by that name, then most likely depmod -a will fix it. On my system its been putting the module in /lib/modules/<kernel>/extra. knock, knock.py, and knock.exe don't get put anywhere, so put them whereever you'd like (I have them in ~/bin). You might need to set the IPT_VERS in the Makefile manually. It tries to get it by running iptables -V. I tested it with 1.3.6, 1.3.8, 1.4.0, 1.4.1.1, and 1.4.2 it seemed to be fine with those versions. The headers in 1.4.2 didn't seem to have any changes that affected the pkd code so I just linked 1.4.2 include to 1.4.1.1 include, same for 1.4.3-1.4.21 A quick note on the vyatta-5 prebuild, just copy the vyatta-5 directory over to your vyatta-5 box and run the install.sh script. I have no idea what you'd need to do to make persitent rules, guessing you could use some custom firewall rule, otherwise I think you'd need to add them to one of the boot scripts. Eric estabroo@gmail.com The release includes headers from iptables-1.4.0 & 1.4.1.1. I did this because iptables-dev for 1.4.0 on debian systems at least no longer includes the headers required to build this extension.