Port Knocking
Thursday, February 17, 2011
As a followup to my last article, I wanted to show how to implement port knocking functionality in Factor. This was particularly interesting to me since I ran across a recent blog post about the “inventor” of port knocking.
"port knocking is a method of externally opening ports on a firewall by generating a connection attempt on a set of prespecified closed ports"
There are several types of port knocking, with variations using any
combination of TCP, UDP, ICMP, or similar network protocols. For this
implementation, we will choose to use TCP. In particular, using the
open-port?
word from our
port-scan
vocabulary. As a reminder, it looks like this:
USING: continuations io.encodings.binary io.sockets kernel ;
: open-port? ( host port -- ? )
<inet> [ binary [ t ] with-client ] [ 2drop f ] recover ;
The idea is to knock on a sequence of ports, in order. In its simplest form, we attempt a connection to each port, ignoring whether it is open or closed (not relevant).
: knock-ports ( host ports -- )
[ dupd open-port? drop ] each drop ;
You can imagine using it something like this (knocking on ports 10000, 10001, 10002 and then write a “Hello” message to port 12345):
IN: scratchpad "localhost"
[ { 10000 10001 10002 } knock-ports ]
[ 12345 <inet> ascii [ "Hello" print ] with-client ]
bi
Some ways to improve this might be to allow “knock delay” between
successive knocks, support UDP or ICMP knocks, or perhaps to encompass
this functionality transparently into a reusable with-knocking-client
word.